summaryrefslogtreecommitdiff
path: root/core
Unidiff
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 @@
1moc_*
2*.moc
3Makefile
4appearancesettingsbase.h
5soundsettingsbase.h
6lightsettingsbase.h
7languagesettingsbase.cpp
8rotationsettingsbase.cpp
9appearancesettingsbase.cpp
10lightsettingsbase.cpp
11languagesettingsbase.h
12rotationsettingsbase.h
13soundsettingsbase.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 @@
1moc_*
2*.moc
3Makefile
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 @@
1#############################################################################
2
3####### Compiler, tools and options
4
5 CXX =$(SYSCONF_CXX) $(QT_CXX_MT)
6 CXXFLAGS=$(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS) $(SYSCONF_CXXFLAGS_LIB)
7 CC =$(SYSCONF_CC) $(QT_C_MT)
8 CFLAGS =$(SYSCONF_CFLAGS) $(SYSCONF_CFLAGS_LIB)
9 INCPATH =-I$(QPEDIR)/include
10 LFLAGS =$(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
11 LIBS =$(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS_QTAPP)
12 MOC =$(SYSCONF_MOC)
13 UIC =$(SYSCONF_UIC)
14
15####### Target
16
17DESTDIR = ../../plugins/applets/
18VER_MAJ = 1
19VER_MIN = 0
20VER_PATCH = 0
21 TARGET= batteryapplet
22TARGET1 = lib$(TARGET).so.$(VER_MAJ)
23
24####### Files
25
26 HEADERS =battery.h \
27 batterystatus.h \
28 batteryappletimpl.h
29 SOURCES =battery.cpp \
30 batterystatus.cpp \
31 batteryappletimpl.cpp
32 OBJECTS =battery.o \
33 batterystatus.o \
34 batteryappletimpl.o
35INTERFACES =
36UICDECLS =
37UICIMPLS =
38 SRCMOC =moc_battery.cpp
39 OBJMOC =moc_battery.o
40
41
42####### Implicit rules
43
44.SUFFIXES: .cpp .cxx .cc .C .c
45
46.cpp.o:
47 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
48
49.cxx.o:
50 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
51
52.cc.o:
53 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
54
55.C.o:
56 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
57
58.c.o:
59 $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
60
61####### Build rules
62
63
64all: $(DESTDIR)$(SYSCONF_LINK_TARGET)
65
66$(DESTDIR)$(SYSCONF_LINK_TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
67 $(SYSCONF_LINK_LIB)
68
69moc: $(SRCMOC)
70
71tmake:
72 tmake batteryapplet.pro
73
74clean:
75 -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
76 -rm -f *~ core
77 -rm -f allmoc.cpp
78
79####### Extension Modules
80
81listpromodules:
82 @echo
83
84listallmodules:
85 @echo
86
87listaddonpromodules:
88 @echo
89
90listaddonentmodules:
91 @echo
92
93
94REQUIRES=
95
96####### Sub-libraries
97
98
99###### Combined headers
100
101
102
103####### Compile
104
105battery.o: battery.cpp \
106 battery.h \
107 batterystatus.h
108
109batterystatus.o: batterystatus.cpp \
110 batterystatus.h
111
112batteryappletimpl.o: batteryappletimpl.cpp \
113 battery.h \
114 batteryappletimpl.h
115
116moc_battery.o: moc_battery.cpp \
117 battery.h
118
119moc_battery.cpp: battery.h
120 $(MOC) battery.h -o moc_battery.cpp
121
122
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#include "battery.h"
21#include "batterystatus.h"
22
23#include <qpe/power.h>
24
25#include <qpainter.h>
26#include <qtimer.h>
27
28
29BatteryMeter::BatteryMeter( QWidget *parent = 0 )
30 : QWidget( parent ), charging(false)
31{
32 ps = new PowerStatus;
33 startTimer( 10000 );
34 setFixedHeight(12);
35 chargeTimer = new QTimer( this );
36 connect( chargeTimer, SIGNAL(timeout()), this, SLOT(chargeTimeout()) );
37 timerEvent(0);
38}
39
40BatteryMeter::~BatteryMeter()
41{
42 delete ps;
43}
44
45QSize BatteryMeter::sizeHint() const
46{
47 return QSize(10,12);
48}
49
50void BatteryMeter::mouseReleaseEvent( QMouseEvent *)
51{
52 if ( batteryView && batteryView->isVisible() ) {
53 delete (QWidget *) batteryView;
54 } else {
55 if ( !batteryView )
56 batteryView = new BatteryStatus( ps );
57 batteryView->showMaximized();
58 batteryView->raise();
59 batteryView->show();
60 }
61}
62
63void BatteryMeter::timerEvent( QTimerEvent * )
64{
65 PowerStatus prev = *ps;
66
67 *ps = PowerStatusManager::readStatus();
68
69 if ( prev != *ps ) {
70 percent = ps->batteryPercentRemaining();
71 if ( !charging && ps->batteryStatus() == PowerStatus::Charging && percent < 0 ) {
72 percent = 0;
73 charging = true;
74 chargeTimer->start( 500 );
75 } else if ( charging && ps->batteryStatus() != PowerStatus::Charging ) {
76 charging = false;
77 chargeTimer->stop();
78 if ( batteryView )
79 batteryView->updatePercent( percent );
80 }
81 repaint(FALSE);
82 if ( batteryView )
83 batteryView->repaint();
84 }
85}
86
87void BatteryMeter::chargeTimeout()
88{
89 percent += 20;
90 if ( percent > 100 )
91 percent = 0;
92
93 repaint(FALSE);
94 if ( batteryView )
95 batteryView->updatePercent( percent );
96}
97
98void BatteryMeter::paintEvent( QPaintEvent* )
99{
100 QPainter p(this);
101
102 QColor c;
103 QColor darkc;
104 QColor lightc;
105 if ( ps->acStatus() == PowerStatus::Offline ) {
106 c = blue.light(120);
107 darkc = c.dark(120);
108 lightc = c.light(140);
109 } else if ( ps->acStatus() == PowerStatus::Online ) {
110 c = green.dark(130);
111 darkc = c.dark(120);
112 lightc = c.light(180);
113 } else {
114 c = red;
115 darkc = c.dark(120);
116 lightc = c.light(160);
117 }
118
119 int w = 6;
120 int h = height()-3;
121 int pix = (percent * h) / 100;
122 int y2 = height() - 2;
123 int y = y2 - pix;
124 int x1 = (width() - w) / 2;
125
126 p.setPen(QColor(80,80,80));
127 p.drawLine(x1+w/4,0,x1+w/4+w/2,0);
128 p.drawRect(x1,1,w,height()-1);
129 p.setBrush(c);
130
131 int extra = ((percent * h) % 100)/(100/4);
132
133#define Y(i) ((i<=extra)?y-1:y)
134#define DRAWUPPER(i) if ( Y(i) >= 2 ) p.drawLine(i+x1,2,i+x1,Y(i));
135 p.setPen( gray );
136 DRAWUPPER(1);
137 DRAWUPPER(3);
138 p.setPen( gray.light(130) );
139 DRAWUPPER(2);
140 p.setPen( gray.dark(120) );
141 DRAWUPPER(4);
142
143#define DRAW(i) { if ( Y(i) < y2 ) p.drawLine(i+x1,Y(i)+1,i+x1,y2); }
144 p.setPen( c );
145 DRAW(1);
146 DRAW(3);
147 p.setPen( lightc );
148 DRAW(2);
149 p.setPen(darkc);
150 DRAW(4);
151}
152
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef BATTERY_H
21#define BATTERY_H
22
23#include <qwidget.h>
24#include <qguardedptr.h>
25
26class PowerStatus;
27class BatteryStatus;
28class QTimer;
29
30class BatteryMeter : public QWidget
31{
32 Q_OBJECT
33public:
34 BatteryMeter( QWidget *parent = 0 );
35 ~BatteryMeter();
36
37 QSize sizeHint() const;
38
39protected:
40 void timerEvent( QTimerEvent * );
41 void paintEvent( QPaintEvent* );
42 void mouseReleaseEvent( QMouseEvent * );
43
44protected slots:
45 void chargeTimeout();
46
47protected:
48 QGuardedPtr<BatteryStatus> batteryView;
49 PowerStatus *ps;
50 QTimer *chargeTimer;
51 int percent;
52 bool charging;
53};
54
55#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 @@
1 TEMPLATE= lib
2 CONFIG += qt warn_on release
3 HEADERS= battery.h batterystatus.h batteryappletimpl.h
4 SOURCES= battery.cpp batterystatus.cpp batteryappletimpl.cpp
5 TARGET = batteryapplet
6 DESTDIR = ../../plugins/applets
7INCLUDEPATH += $(QPEDIR)/include
8DEPENDPATH += ../$(QPEDIR)/include ..
9LIBS += -lqpe
10 VERSION = 1.0.0
11
12TRANSLATIONS += ../../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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#include "battery.h"
21#include "batteryappletimpl.h"
22
23
24BatteryAppletImpl::BatteryAppletImpl()
25 : battery(0), ref(0)
26{
27}
28
29BatteryAppletImpl::~BatteryAppletImpl()
30{
31 delete battery;
32}
33
34QWidget *BatteryAppletImpl::applet( QWidget *parent )
35{
36 if ( !battery )
37 battery = new BatteryMeter( parent );
38 return battery;
39}
40
41int BatteryAppletImpl::position() const
42{
43 return 8;
44}
45
46QRESULT BatteryAppletImpl::queryInterface( const QUuid &uuid, QUnknownInterface **iface )
47{
48 *iface = 0;
49 if ( uuid == IID_QUnknown )
50 *iface = this;
51 else if ( uuid == IID_TaskbarApplet )
52 *iface = this;
53
54 if ( *iface )
55 (*iface)->addRef();
56 return QS_OK;
57}
58
59Q_EXPORT_INTERFACE()
60{
61 Q_CREATE_INSTANCE( BatteryAppletImpl )
62}
63
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef BATTERYAPPLETIMPL_H
21#define BATTERYAPPLETIMPL_H
22
23#include <qpe/taskbarappletinterface.h>
24
25class BatteryMeter;
26
27class BatteryAppletImpl : public TaskbarAppletInterface
28{
29public:
30 BatteryAppletImpl();
31 virtual ~BatteryAppletImpl();
32
33 QRESULT queryInterface( const QUuid&, QUnknownInterface** );
34 Q_REFCOUNT
35
36 virtual QWidget *applet( QWidget *parent );
37 virtual int position() const;
38
39private:
40 BatteryMeter *battery;
41 ulong ref;
42};
43
44#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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#include "batterystatus.h"
21
22#include <qpe/power.h>
23
24#include <qpainter.h>
25#include <qpushbutton.h>
26#include <qdrawutil.h>
27
28
29BatteryStatus::BatteryStatus( const PowerStatus *p, QWidget *parent )
30 : QWidget( parent, 0, WDestructiveClose), ps(p)
31{
32 setCaption( tr("Battery Status") );
33 QPushButton *pb = new QPushButton( tr("Close"), this );
34 pb->move( 70, 220 );
35 pb->show();
36 connect( pb, SIGNAL( clicked() ), this, SLOT( close() ) );
37 percent = ps->batteryPercentRemaining();
38 show();
39}
40
41BatteryStatus::~BatteryStatus()
42{
43}
44
45void BatteryStatus::updatePercent( int pc )
46{
47 percent = pc;
48 repaint(FALSE);
49}
50
51void BatteryStatus::drawSegment( QPainter *p, const QRect &r, const QColor &topgrad, const QColor &botgrad, const QColor &highlight, int hightlight_height )
52{
53 int h1, h2, s1, s2, v1, v2, ng = r.height(), hy = ng*30/100, hh = hightlight_height;
54 topgrad.hsv( &h1, &s1, &v1 );
55 botgrad.hsv( &h2, &s2, &v2 );
56 for ( int j = 0; j < hy-2; j++ ) {
57 p->setPen( QColor( h1 + ((h2-h1)*j)/(ng-1), s1 + ((s2-s1)*j)/(ng-1),
58 v1 + ((v2-v1)*j)/(ng-1), QColor::Hsv ) );
59 p->drawLine( r.x(), r.top()+hy-2-j, r.x()+r.width(), r.top()+hy-2-j );
60 }
61 for ( int j = 0; j < hh; j++ ) {
62 p->setPen( highlight );
63 p->drawLine( r.x(), r.top()+hy-2+j, r.x()+r.width(), r.top()+hy-2+j );
64 }
65 for ( int j = 0; j < ng-hy-hh; j++ ) {
66 p->setPen( QColor( h1 + ((h2-h1)*j)/(ng-1), s1 + ((s2-s1)*j)/(ng-1),
67 v1 + ((v2-v1)*j)/(ng-1), QColor::Hsv ) );
68 p->drawLine( r.x(), r.top()+hy+hh-2+j, r.x()+r.width(), r.top()+hy+hh-2+j );
69 }
70}
71
72void BatteryStatus::paintEvent( QPaintEvent * )
73{
74 QPainter p(this);
75 QString text;
76 if ( ps->batteryStatus() == PowerStatus::Charging ) {
77 text = tr("Charging");
78 } else if ( ps->batteryPercentAccurate() ) {
79 text.sprintf( tr("Percentage battery remaining") + ": %i%%", percent );
80 } else {
81 text = tr("Battery status: ");
82 switch ( ps->batteryStatus() ) {
83 case PowerStatus::High:
84 text += tr("Good");
85 break;
86 case PowerStatus::Low:
87 text += tr("Low");
88 break;
89 case PowerStatus::VeryLow:
90 text += tr("Very Low");
91 break;
92 case PowerStatus::Critical:
93 text += tr("Critical");
94 break;
95 default: // NotPresent, etc.
96 text += tr("Unknown");
97 }
98 }
99 p.drawText( 10, 120, text );
100 if ( ps->acStatus() == PowerStatus::Backup )
101 p.drawText( 10, 150, tr("On backup power") );
102 else if ( ps->acStatus() == PowerStatus::Online )
103 p.drawText( 10, 150, tr("Power on-line") );
104 else if ( ps->acStatus() == PowerStatus::Offline )
105 p.drawText( 10, 150, tr("External power disconnected") );
106
107 if ( ps->batteryTimeRemaining() >= 0 ) {
108 text.sprintf( tr("Battery time remaining") + ": %im %02is",
109 ps->batteryTimeRemaining() / 60, ps->batteryTimeRemaining() % 60 );
110 p.drawText( 10, 180, text );
111 }
112
113 QColor c;
114 QColor darkc;
115 QColor lightc;
116 if ( ps->acStatus() == PowerStatus::Offline ) {
117 c = blue.light(120);
118 darkc = c.dark(280);
119 lightc = c.light(145);
120 } else if ( ps->acStatus() == PowerStatus::Online ) {
121 c = green.dark(130);
122 darkc = c.dark(200);
123 lightc = c.light(220);
124 } else {
125 c = red;
126 darkc = c.dark(280);
127 lightc = c.light(140);
128 }
129 if ( percent < 0 )
130 return;
131
132 int percent2 = percent * 2;
133 p.setPen( black );
134 qDrawShadePanel( &p, 9, 30, 204, 39, colorGroup(), TRUE, 1, NULL);
135 qDrawShadePanel( &p, 212, 37, 12, 24, colorGroup(), TRUE, 1, NULL);
136 drawSegment( &p, QRect( 10, 30, percent2, 40 ), lightc, darkc, lightc.light(115), 6 );
137 drawSegment( &p, QRect( 11 + percent2, 30, 200 - percent2, 40 ), white.light(80), black, white.light(90), 6 );
138 drawSegment( &p, QRect( 212, 37, 10, 25 ), white.light(80), black, white.light(90), 2 );
139}
140
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef BATTERY_STATUS_H
21#define BATTERY_STATUS_H
22
23#include <qwidget.h>
24
25class PowerStatus;
26
27class BatteryStatus : public QWidget
28{
29public:
30 BatteryStatus( const PowerStatus *s, QWidget *parent=0 );
31 ~BatteryStatus();
32
33 void updatePercent( int );
34
35protected:
36 void drawSegment( QPainter *p, const QRect &r, const QColor &topgrad, const QColor &botgrad, const QColor &highlight, int hightlight_height );
37 void paintEvent( QPaintEvent *pe );
38
39private:
40 const PowerStatus *ps;
41 int percent;
42};
43
44#endif
45
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 @@
1Files: plugins/applets/libbatteryapplet.so*
2Priority: optional
3Section: qpe/taskbar
4Maintainer: Warwick Allison <warwick@trolltech.com>
5Architecture: arm
6Version: $QPE_VERSION-3
7Depends: qpe-base ($QPE_VERSION)
8Description: Battery Monitor applet
9 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 @@
1#!/bin/sh
2/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 @@
1#!/bin/sh
2/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 @@
1#############################################################################
2
3####### Compiler, tools and options
4
5 CXX =$(SYSCONF_CXX) $(QT_CXX_MT)
6 CXXFLAGS=$(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS) $(SYSCONF_CXXFLAGS_LIB)
7 CC =$(SYSCONF_CC) $(QT_C_MT)
8 CFLAGS =$(SYSCONF_CFLAGS) $(SYSCONF_CFLAGS_LIB)
9 INCPATH =-I$(QPEDIR)/include
10 LFLAGS =$(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
11 LIBS =$(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS_QTAPP)
12 MOC =$(SYSCONF_MOC)
13 UIC =$(SYSCONF_UIC)
14
15####### Target
16
17DESTDIR = ../../plugins/applets/
18VER_MAJ = 1
19VER_MIN = 0
20VER_PATCH = 0
21 TARGET= clipboardapplet
22TARGET1 = lib$(TARGET).so.$(VER_MAJ)
23
24####### Files
25
26 HEADERS =clipboard.h \
27 clipboardappletimpl.h
28 SOURCES =clipboard.cpp \
29 clipboardappletimpl.cpp
30 OBJECTS =clipboard.o \
31 clipboardappletimpl.o
32INTERFACES =
33UICDECLS =
34UICIMPLS =
35 SRCMOC =moc_clipboard.cpp
36 OBJMOC =moc_clipboard.o
37
38
39####### Implicit rules
40
41.SUFFIXES: .cpp .cxx .cc .C .c
42
43.cpp.o:
44 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
45
46.cxx.o:
47 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
48
49.cc.o:
50 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
51
52.C.o:
53 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
54
55.c.o:
56 $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
57
58####### Build rules
59
60
61all: $(DESTDIR)$(SYSCONF_LINK_TARGET)
62
63$(DESTDIR)$(SYSCONF_LINK_TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
64 $(SYSCONF_LINK_LIB)
65
66moc: $(SRCMOC)
67
68tmake:
69 tmake clipboardapplet.pro
70
71clean:
72 -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
73 -rm -f *~ core
74 -rm -f allmoc.cpp
75
76####### Extension Modules
77
78listpromodules:
79 @echo
80
81listallmodules:
82 @echo
83
84listaddonpromodules:
85 @echo
86
87listaddonentmodules:
88 @echo
89
90
91REQUIRES=
92
93####### Sub-libraries
94
95
96###### Combined headers
97
98
99
100####### Compile
101
102clipboard.o: clipboard.cpp \
103 clipboard.h
104
105clipboardappletimpl.o: clipboardappletimpl.cpp \
106 clipboard.h \
107 clipboardappletimpl.h
108
109moc_clipboard.o: moc_clipboard.cpp \
110 clipboard.h
111
112moc_clipboard.cpp: clipboard.h
113 $(MOC) clipboard.h -o moc_clipboard.cpp
114
115
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "clipboard.h"
22
23#include <qpe/resource.h>
24
25#include <qpainter.h>
26#include <qpopupmenu.h>
27#include <qwindowsystem_qws.h>
28
29
30//===========================================================================
31
32ClipboardApplet::ClipboardApplet( QWidget *parent, const char *name )
33 : QWidget( parent, name )
34{
35 setFixedWidth( 14 );
36 clipboardPixmap = Resource::loadPixmap( "clipboard" );
37 menu = 0;
38}
39
40ClipboardApplet::~ClipboardApplet()
41{
42}
43
44void ClipboardApplet::mousePressEvent( QMouseEvent *)
45{
46 if ( !menu ) {
47 menu = new QPopupMenu(this);
48 menu->insertItem(tr("Cut"));
49 menu->insertItem(tr("Copy"));
50 menu->insertItem(tr("Paste"));
51 connect(menu, SIGNAL(selected(int)), this, SLOT(action(int)));
52 }
53 menu->popup(mapToGlobal(QPoint(0,0)));
54}
55
56void ClipboardApplet::action(int i)
57{
58 ushort unicode=0;
59 int scan=0;
60
61 if ( i == 0 )
62 { unicode='X'-'@'; scan=Key_X; } // Cut
63 else if ( i == 1 )
64 { unicode='C'-'@'; scan=Key_C; } // Copy
65 else if ( i == 2 )
66 { unicode='V'-'@'; scan=Key_V; } // Paste
67
68 if ( scan ) {
69 qwsServer->processKeyEvent( unicode, scan, ControlButton, TRUE, FALSE );
70 qwsServer->processKeyEvent( unicode, scan, ControlButton, FALSE, FALSE );
71 }
72}
73
74void ClipboardApplet::paintEvent( QPaintEvent* )
75{
76 QPainter p(this);
77 p.drawPixmap( 0, 1, clipboardPixmap );
78}
79
80
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef __CLIPBOARD_APPLET_H__
21#define __CLIPBOARD_APPLET_H__
22
23#include <qwidget.h>
24#include <qpixmap.h>
25
26class ClipboardApplet : public QWidget
27{
28 Q_OBJECT
29public:
30 ClipboardApplet( QWidget *parent = 0, const char *name=0 );
31 ~ClipboardApplet();
32
33protected:
34 void mousePressEvent( QMouseEvent *);
35 void paintEvent( QPaintEvent* );
36
37private slots:
38 void action(int);
39
40private:
41 QPopupMenu* menu;
42 QPixmap clipboardPixmap;
43};
44
45
46#endif // __CLIPBOARD_APPLET_H__
47
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 @@
1 TEMPLATE= lib
2 CONFIG += qt warn_on release
3 HEADERS= clipboard.h clipboardappletimpl.h
4 SOURCES= clipboard.cpp clipboardappletimpl.cpp
5 TARGET = clipboardapplet
6 DESTDIR = ../../plugins/applets
7INCLUDEPATH += $(QPEDIR)/include
8DEPENDPATH += ../$(QPEDIR)/include
9LIBS += -lqpe
10 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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#include "clipboard.h"
21#include "clipboardappletimpl.h"
22
23
24ClipboardAppletImpl::ClipboardAppletImpl()
25 : clipboard(0), ref(0)
26{
27}
28
29ClipboardAppletImpl::~ClipboardAppletImpl()
30{
31 delete clipboard;
32}
33
34QWidget *ClipboardAppletImpl::applet( QWidget *parent )
35{
36 if ( !clipboard )
37 clipboard = new ClipboardApplet( parent );
38 return clipboard;
39}
40
41int ClipboardAppletImpl::position() const
42{
43 return 6;
44}
45
46QRESULT ClipboardAppletImpl::queryInterface( const QUuid &uuid, QUnknownInterface **iface )
47{
48 *iface = 0;
49 if ( uuid == IID_QUnknown )
50 *iface = this;
51 else if ( uuid == IID_TaskbarApplet )
52 *iface = this;
53
54 if ( *iface )
55 (*iface)->addRef();
56 return QS_OK;
57}
58
59Q_EXPORT_INTERFACE()
60{
61 Q_CREATE_INSTANCE( ClipboardAppletImpl )
62}
63
64
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef CLIPBOARDAPPLETIMPL_H
21#define CLIPBOARDAPPLETIMPL_H
22
23#include <qpe/taskbarappletinterface.h>
24
25class ClipboardApplet;
26
27class ClipboardAppletImpl : public TaskbarAppletInterface
28{
29public:
30 ClipboardAppletImpl();
31 virtual ~ClipboardAppletImpl();
32
33 QRESULT queryInterface( const QUuid&, QUnknownInterface** );
34 Q_REFCOUNT
35
36 virtual QWidget *applet( QWidget *parent );
37 virtual int position() const;
38
39private:
40 ClipboardApplet *clipboard;
41 ulong ref;
42};
43
44#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 @@
1Files: plugins/applets/libclipboardapplet.so*
2Priority: optional
3Section: qpe/taskbar
4Maintainer: Warwick Allison <warwick@trolltech.com>
5Architecture: arm
6Version: $QPE_VERSION-3
7Depends: qpe-base ($QPE_VERSION)
8Description: Clipboard applet
9 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 @@
1#!/bin/sh
2/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 @@
1#!/bin/sh
2/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 @@
1moc_*
2*.moc
3Makefile
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 @@
1#############################################################################
2
3####### Compiler, tools and options
4
5 CXX =$(SYSCONF_CXX) $(QT_CXX_MT)
6 CXXFLAGS=$(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS) $(SYSCONF_CXXFLAGS_LIB)
7 CC =$(SYSCONF_CC) $(QT_C_MT)
8 CFLAGS =$(SYSCONF_CFLAGS) $(SYSCONF_CFLAGS_LIB)
9 INCPATH =-I$(QPEDIR)/include
10 LFLAGS =$(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
11 LIBS =$(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS_QTAPP)
12 MOC =$(SYSCONF_MOC)
13 UIC =$(SYSCONF_UIC)
14
15####### Target
16
17DESTDIR = ../../plugins/applets/
18VER_MAJ = 1
19VER_MIN = 0
20VER_PATCH = 0
21 TARGET= clockapplet
22TARGET1 = lib$(TARGET).so.$(VER_MAJ)
23
24####### Files
25
26 HEADERS =clock.h \
27 clockappletimpl.h
28 SOURCES =clock.cpp \
29 clockappletimpl.cpp
30 OBJECTS =clock.o \
31 clockappletimpl.o
32INTERFACES =
33UICDECLS =
34UICIMPLS =
35 SRCMOC =moc_clock.cpp
36 OBJMOC =moc_clock.o
37
38
39####### Implicit rules
40
41.SUFFIXES: .cpp .cxx .cc .C .c
42
43.cpp.o:
44 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
45
46.cxx.o:
47 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
48
49.cc.o:
50 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
51
52.C.o:
53 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
54
55.c.o:
56 $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
57
58####### Build rules
59
60
61all: $(DESTDIR)$(SYSCONF_LINK_TARGET)
62
63$(DESTDIR)$(SYSCONF_LINK_TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
64 $(SYSCONF_LINK_LIB)
65
66moc: $(SRCMOC)
67
68tmake:
69 tmake clockapplet.pro
70
71clean:
72 -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
73 -rm -f *~ core
74 -rm -f allmoc.cpp
75
76####### Extension Modules
77
78listpromodules:
79 @echo
80
81listallmodules:
82 @echo
83
84listaddonpromodules:
85 @echo
86
87listaddonentmodules:
88 @echo
89
90
91REQUIRES=
92
93####### Sub-libraries
94
95
96###### Combined headers
97
98
99
100####### Compile
101
102clock.o: clock.cpp \
103 clock.h
104
105clockappletimpl.o: clockappletimpl.cpp \
106 clock.h \
107 clockappletimpl.h
108
109moc_clock.o: moc_clock.cpp \
110 clock.h
111
112moc_clock.cpp: clock.h
113 $(MOC) clock.h -o moc_clock.cpp
114
115
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "clock.h"
22
23#include <qpe/global.h>
24#include <qpe/qpeapplication.h>
25#include <qpe/config.h>
26
27#include <qmainwindow.h>
28#include <qlayout.h>
29#include <qpushbutton.h>
30#include <qmessagebox.h>
31#include <qdatetime.h>
32#include <qtimer.h>
33#include <qpopupmenu.h>
34#include <stdlib.h>
35
36
37LauncherClock::LauncherClock( QWidget *parent ) : QLabel( parent )
38{
39 // If you want a sunken border around the clock do this:
40 // setFrameStyle( QFrame::Panel | QFrame::Sunken );
41 setFont( QFont( "Helvetica", 10, QFont::Normal ) );
42 connect( qApp, SIGNAL( timeChanged() ), this, SLOT( updateTime( ) ) );
43 connect( qApp, SIGNAL( clockChanged( bool ) ),
44 this, SLOT( slotClockChanged( bool ) ) );
45 Config config( "qpe" );
46 config.setGroup( "Time" );
47 ampmFormat = config.readBoolEntry( "AMPM", TRUE );
48 timerId = 0;
49 timerEvent( 0 );
50 show();
51}
52
53void LauncherClock::mouseReleaseEvent( QMouseEvent * )
54{
55 Global::execute( "systemtime" );
56}
57
58
59void LauncherClock::timerEvent( QTimerEvent *e )
60{
61 if ( !e || e->timerId() == timerId ) {
62 killTimer( timerId );
63 changeTime();
64 QTime t = QTime::currentTime();
65 int ms = (60 - t.second())*1000 - t.msec();
66 timerId = startTimer( ms );
67 } else {
68 QLabel::timerEvent( e );
69 }
70}
71
72void LauncherClock::updateTime( void )
73{
74 changeTime();
75}
76
77void LauncherClock::changeTime( void )
78{
79 QTime tm = QDateTime::currentDateTime().time();
80 QString s;
81 if( ampmFormat ) {
82 int hour = tm.hour();
83 if (hour == 0)
84 hour = 12;
85 if (hour > 12)
86 hour -= 12;
87 s.sprintf( "%2d%c%02d %s", hour, ':', tm.minute(), (tm.hour() >= 12) ? "PM" : "AM" );
88 } else
89 s.sprintf( "%2d%c%02d", tm.hour(), ':', tm.minute() );
90 setText( s );
91}
92
93void LauncherClock::slotClockChanged( bool pm )
94{
95 ampmFormat = pm;
96 updateTime();
97}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef __LAUNCHER_CLOCK_H__
21#define __LAUNCHER_CLOCK_H__
22
23
24#include <qlabel.h>
25#include <qdatetime.h>
26
27class LauncherClock : public QLabel
28{
29 Q_OBJECT
30public:
31 LauncherClock( QWidget *parent );
32
33protected slots:
34 void updateTime( void );
35 void slotClockChanged( bool pm );
36
37protected:
38 void mouseReleaseEvent( QMouseEvent * );
39 void timerEvent( QTimerEvent * );
40 void changeTime( void );
41 bool ampmFormat;
42 int timerId;
43};
44
45
46#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 @@
1 TEMPLATE= lib
2 CONFIG += qt warn_on release
3 HEADERS= clock.h clockappletimpl.h
4 SOURCES= clock.cpp clockappletimpl.cpp
5 TARGET = clockapplet
6 DESTDIR = ../../plugins/applets
7INCLUDEPATH += $(QPEDIR)/include
8DEPENDPATH += ../$(QPEDIR)/include ..
9LIBS += -lqpe
10 VERSION = 1.0.0
11
12TRANSLATIONS += ../../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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#include "clock.h"
21#include "clockappletimpl.h"
22
23
24ClockAppletImpl::ClockAppletImpl()
25 : clock(0), ref(0)
26{
27}
28
29ClockAppletImpl::~ClockAppletImpl()
30{
31 delete clock;
32}
33
34QWidget *ClockAppletImpl::applet( QWidget *parent )
35{
36 if ( !clock )
37 clock = new LauncherClock( parent );
38 return clock;
39}
40
41int ClockAppletImpl::position() const
42{
43 return 10;
44}
45
46#ifndef QT_NO_COMPONENT
47QRESULT ClockAppletImpl::queryInterface( const QUuid &uuid, QUnknownInterface **iface )
48{
49 *iface = 0;
50 if ( uuid == IID_QUnknown )
51 *iface = this;
52 else if ( uuid == IID_TaskbarApplet )
53 *iface = this;
54
55 if ( *iface )
56 (*iface)->addRef();
57 return QS_OK;
58}
59
60Q_EXPORT_INTERFACE()
61{
62 Q_CREATE_INSTANCE( ClockAppletImpl )
63}
64#endif
65
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef CLOCKAPPLETIMPL_H
21#define CLOCKAPPLETIMPL_H
22
23#include <qpe/taskbarappletinterface.h>
24
25class LauncherClock;
26
27class ClockAppletImpl : public TaskbarAppletInterface
28{
29public:
30 ClockAppletImpl();
31 virtual ~ClockAppletImpl();
32
33#ifndef QT_NO_COMPONENT
34 QRESULT queryInterface( const QUuid&, QUnknownInterface** );
35 Q_REFCOUNT
36#endif
37
38 virtual QWidget *applet( QWidget *parent );
39 virtual int position() const;
40
41private:
42 LauncherClock *clock;
43 ulong ref;
44};
45
46#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 @@
1Files: plugins/applets/libclockapplet.so*
2Priority: optional
3Section: qpe/taskbar
4Maintainer: Warwick Allison <warwick@trolltech.com>
5Architecture: arm
6Version: $QPE_VERSION-3
7Depends: qpe-base ($QPE_VERSION)
8Description: Clock applet
9 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 @@
1#!/bin/sh
2/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 @@
1#!/bin/sh
2/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 @@
1moc_*
2*.moc
3Makefile
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 @@
1#############################################################################
2
3####### Compiler, tools and options
4
5 CXX =$(SYSCONF_CXX) $(QT_CXX_MT)
6 CXXFLAGS=$(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS) $(SYSCONF_CXXFLAGS_LIB)
7 CC =$(SYSCONF_CC) $(QT_C_MT)
8 CFLAGS =$(SYSCONF_CFLAGS) $(SYSCONF_CFLAGS_LIB)
9 INCPATH =-I$(QPEDIR)/include
10 LFLAGS =$(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
11 LIBS =$(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS_QTAPP)
12 MOC =$(SYSCONF_MOC)
13 UIC =$(SYSCONF_UIC)
14
15####### Target
16
17DESTDIR = ../../plugins/applets/
18VER_MAJ = 1
19VER_MIN = 0
20VER_PATCH = 0
21 TARGET= volumeapplet
22TARGET1 = lib$(TARGET).so.$(VER_MAJ)
23
24####### Files
25
26 HEADERS =volume.h \
27 volumeappletimpl.h
28 SOURCES =volume.cpp \
29 volumeappletimpl.cpp
30 OBJECTS =volume.o \
31 volumeappletimpl.o
32INTERFACES =
33UICDECLS =
34UICIMPLS =
35 SRCMOC =moc_volume.cpp
36 OBJMOC =moc_volume.o
37
38
39####### Implicit rules
40
41.SUFFIXES: .cpp .cxx .cc .C .c
42
43.cpp.o:
44 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
45
46.cxx.o:
47 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
48
49.cc.o:
50 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
51
52.C.o:
53 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
54
55.c.o:
56 $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
57
58####### Build rules
59
60
61all: $(DESTDIR)$(SYSCONF_LINK_TARGET)
62
63$(DESTDIR)$(SYSCONF_LINK_TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
64 $(SYSCONF_LINK_LIB)
65
66moc: $(SRCMOC)
67
68tmake:
69 tmake volumeapplet.pro
70
71clean:
72 -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
73 -rm -f *~ core
74 -rm -f allmoc.cpp
75
76####### Extension Modules
77
78listpromodules:
79 @echo
80
81listallmodules:
82 @echo
83
84listaddonpromodules:
85 @echo
86
87listaddonentmodules:
88 @echo
89
90
91REQUIRES=
92
93####### Sub-libraries
94
95
96###### Combined headers
97
98
99
100####### Compile
101
102volume.o: volume.cpp \
103 volume.h
104
105volumeappletimpl.o: volumeappletimpl.cpp \
106 volume.h \
107 volumeappletimpl.h
108
109moc_volume.o: moc_volume.cpp \
110 volume.h
111
112moc_volume.cpp: volume.h
113 $(MOC) volume.h -o moc_volume.cpp
114
115
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 @@
1Files: plugins/applets/libvolumeapplet.so*
2Priority: optional
3Section: qpe/taskbar
4Maintainer: Warwick Allison <warwick@trolltech.com>
5Architecture: arm
6Version: $QPE_VERSION-3
7Depends: qpe-base ($QPE_VERSION)
8Description: Volume applet
9 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 @@
1#!/bin/sh
2/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 @@
1#!/bin/sh
2/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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "volume.h"
22
23#include <qpe/resource.h>
24#include <qpe/qpeapplication.h>
25#include <qpe/config.h>
26#if ( defined Q_WS_QWS || defined(_WS_QWS_) ) && !defined(QT_NO_COP)
27#include <qpe/qcopenvelope_qws.h>
28#endif
29
30#include <qpainter.h>
31#include <qcheckbox.h>
32#include <qslider.h>
33#include <qlayout.h>
34#include <qframe.h>
35#include <qpixmap.h>
36
37
38VolumeControl::VolumeControl( QWidget *parent, const char *name )
39 : QFrame( parent, name, WDestructiveClose | WStyle_StaysOnTop | WType_Popup )
40{
41 setFrameStyle( QFrame::PopupPanel | QFrame::Raised );
42
43 QVBoxLayout *vbox = new QVBoxLayout( this );
44 slider = new QSlider( this );
45 muteBox = new QCheckBox( tr("Mute"), this );
46 slider->setRange( 0, 100 );
47 slider->setTickmarks( QSlider::Both );
48 slider->setTickInterval( 20 );
49 slider->setFocusPolicy( QWidget::NoFocus );
50 muteBox->setFocusPolicy( QWidget::NoFocus );
51 vbox->setMargin( 6 );
52 vbox->setSpacing( 3 );
53 vbox->addWidget( slider, 0, Qt::AlignVCenter | Qt::AlignHCenter );
54 vbox->addWidget( muteBox );
55 setFixedHeight( 100 );
56 setFixedWidth( sizeHint().width() );
57 setFocusPolicy(QWidget::NoFocus);
58}
59
60void VolumeControl::keyPressEvent( QKeyEvent *e)
61{
62 switch(e->key()) {
63 case Key_Up:
64 slider->subtractStep();
65 break;
66 case Key_Down:
67 slider->addStep();
68 break;
69 case Key_Space:
70 muteBox->toggle();
71 break;
72 case Key_Escape:
73 close();
74 break;
75 }
76}
77
78//===========================================================================
79
80VolumeApplet::VolumeApplet( QWidget *parent, const char *name )
81 : QWidget( parent, name )
82{
83 setFixedHeight( 18 );
84 setFixedWidth( 14 );
85 volumePixmap = Resource::loadPixmap( "volume" );
86 muted = FALSE; // ### read from pref
87 volumePercent = 50; // ### read from pref
88 connect( qApp, SIGNAL( volumeChanged(bool) ), this, SLOT( volumeChanged(bool) ) );
89 writeSystemVolume();
90}
91
92VolumeApplet::~VolumeApplet()
93{
94}
95
96void VolumeApplet::mousePressEvent( QMouseEvent *)
97{
98 // Create a small volume control window to adjust the volume with
99 VolumeControl *vc = new VolumeControl;
100 vc->slider->setValue( 100 - volumePercent );
101 vc->muteBox->setChecked( muted );
102 connect( vc->slider, SIGNAL( valueChanged( int ) ), this, SLOT( sliderMoved( int ) ) );
103 connect( vc->muteBox, SIGNAL( toggled( bool ) ), this, SLOT( mute( bool ) ) );
104 QPoint curPos = mapToGlobal( rect().topLeft() );
105 vc->move( curPos.x()-(vc->sizeHint().width()-width())/2, curPos.y() - 100 );
106 vc->show();
107}
108
109void VolumeApplet::volumeChanged( bool nowMuted )
110{
111 int previousVolume = volumePercent;
112
113 if ( !nowMuted )
114 readSystemVolume();
115
116 // Handle case where muting it toggled
117 if ( muted != nowMuted ) {
118 muted = nowMuted;
119 repaint( TRUE );
120 return;
121 }
122
123 // Avoid over repainting
124 if ( previousVolume != volumePercent )
125 repaint( 2, height() - 3, width() - 4, 2, FALSE );
126}
127
128
129void VolumeApplet::mute( bool toggled )
130{
131 muted = toggled;
132 // clear if removing mute
133 repaint( !toggled );
134 writeSystemVolume();
135}
136
137
138void VolumeApplet::sliderMoved( int percent )
139{
140 setVolume( 100 - percent );
141}
142
143
144void VolumeApplet::readSystemVolume()
145{
146 Config cfg("Sound");
147 cfg.setGroup("System");
148 volumePercent = cfg.readNumEntry("Volume");
149}
150
151
152void VolumeApplet::setVolume( int percent )
153{
154 // clamp volume percent to be between 0 and 100
155 volumePercent = (percent < 0) ? 0 : ((percent > 100) ? 100 : percent);
156 // repaint just the little volume rectangle
157 repaint( 2, height() - 3, width() - 4, 2, FALSE );
158 writeSystemVolume();
159}
160
161
162void VolumeApplet::writeSystemVolume()
163{
164 {
165 Config cfg("Sound");
166 cfg.setGroup("System");
167 cfg.writeEntry("Volume",volumePercent);
168 }
169#if ( defined Q_WS_QWS || defined(_WS_QWS_) ) && !defined(QT_NO_COP)
170 // Send notification that the volume has changed
171 QCopEnvelope( "QPE/System", "volumeChange(bool)" ) << muted;
172#endif
173}
174
175
176void VolumeApplet::paintEvent( QPaintEvent* )
177{
178 QPainter p(this);
179
180 if (volumePixmap.isNull())
181 volumePixmap = Resource::loadPixmap( "volume" );
182 p.drawPixmap( 0, 1, volumePixmap );
183 p.setPen( darkGray );
184 p.drawRect( 1, height() - 4, width() - 2, 4 );
185
186 int pixelsWide = volumePercent * (width() - 4) / 100;
187 p.fillRect( 2, height() - 3, pixelsWide, 2, red );
188 p.fillRect( pixelsWide + 2, height() - 3, width() - 4 - pixelsWide, 2, lightGray );
189
190 if ( muted ) {
191 p.setPen( red );
192 p.drawLine( 1, 2, width() - 2, height() - 5 );
193 p.drawLine( 1, 3, width() - 2, height() - 4 );
194 p.drawLine( width() - 2, 2, 1, height() - 5 );
195 p.drawLine( width() - 2, 3, 1, height() - 4 );
196 }
197}
198
199
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef __VOLUME_APPLET_H__
21#define __VOLUME_APPLET_H__
22
23
24#include <qwidget.h>
25#include <qframe.h>
26#include <qpixmap.h>
27#include <qguardedptr.h>
28
29class QSlider;
30class QCheckBox;
31
32class VolumeControl : public QFrame
33{
34 Q_OBJECT
35public:
36 VolumeControl( QWidget *parent=0, const char *name=0 );
37
38public:
39 QSlider *slider;
40 QCheckBox *muteBox;
41
42private:
43 void keyPressEvent( QKeyEvent * );
44};
45
46class VolumeApplet : public QWidget
47{
48 Q_OBJECT
49public:
50 VolumeApplet( QWidget *parent = 0, const char *name=0 );
51 ~VolumeApplet();
52 bool isMute( ) { return muted; }
53 int percent( ) { return volumePercent; }
54
55public slots:
56 void volumeChanged( bool muted );
57 void setVolume( int percent );
58 void sliderMoved( int percent );
59 void mute( bool );
60
61private:
62 void readSystemVolume();
63 void writeSystemVolume();
64 void mousePressEvent( QMouseEvent * );
65 void paintEvent( QPaintEvent* );
66
67private:
68 int volumePercent;
69 bool muted;
70 QPixmap volumePixmap;
71};
72
73
74#endif // __VOLUME_APPLET_H__
75
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 @@
1 TEMPLATE= lib
2 CONFIG += qt warn_on release
3 HEADERS= volume.h volumeappletimpl.h
4 SOURCES= volume.cpp volumeappletimpl.cpp
5 TARGET = volumeapplet
6 DESTDIR = ../../plugins/applets
7INCLUDEPATH += $(QPEDIR)/include
8DEPENDPATH += ../$(QPEDIR)/include
9LIBS += -lqpe
10 VERSION = 1.0.0
11
12TRANSLATIONS += ../../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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#include "volume.h"
21#include "volumeappletimpl.h"
22
23
24VolumeAppletImpl::VolumeAppletImpl()
25 : volume(0), ref(0)
26{
27}
28
29VolumeAppletImpl::~VolumeAppletImpl()
30{
31 delete volume;
32}
33
34QWidget *VolumeAppletImpl::applet( QWidget *parent )
35{
36 if ( !volume )
37 volume = new VolumeApplet( parent );
38 return volume;
39}
40
41int VolumeAppletImpl::position() const
42{
43 return 6;
44}
45
46QRESULT VolumeAppletImpl::queryInterface( const QUuid &uuid, QUnknownInterface **iface )
47{
48 *iface = 0;
49 if ( uuid == IID_QUnknown )
50 *iface = this;
51 else if ( uuid == IID_TaskbarApplet )
52 *iface = this;
53
54 if ( *iface )
55 (*iface)->addRef();
56 return QS_OK;
57}
58
59Q_EXPORT_INTERFACE()
60{
61 Q_CREATE_INSTANCE( VolumeAppletImpl )
62}
63
64
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef VOLUMEAPPLETIMPL_H
21#define VOLUMEAPPLETIMPL_H
22
23#include <qpe/taskbarappletinterface.h>
24
25class VolumeApplet;
26
27class VolumeAppletImpl : public TaskbarAppletInterface
28{
29public:
30 VolumeAppletImpl();
31 virtual ~VolumeAppletImpl();
32
33 QRESULT queryInterface( const QUuid&, QUnknownInterface** );
34 Q_REFCOUNT
35
36 virtual QWidget *applet( QWidget *parent );
37 virtual int position() const;
38
39private:
40 VolumeApplet *volume;
41 ulong ref;
42};
43
44#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 @@
1moc_*
2*.moc
3Makefile
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "calibrate.h"
22
23#include <qpe/resource.h>
24
25#include <qapplication.h>
26
27#if defined(Q_WS_QWS) || defined(_WS_QWS_)
28
29#include <qpainter.h>
30#include <qtimer.h>
31#include <qwindowsystem_qws.h>
32#include <qgfx_qws.h>
33
34
35Calibrate::Calibrate(QWidget* parent, const char * name, WFlags wf) :
36 QDialog( parent, name, TRUE, wf | WStyle_Tool | WStyle_Customize | WStyle_StaysOnTop )
37{
38 showCross = TRUE;
39 const int offset = 30;
40 QRect desk = qApp->desktop()->geometry();
41 setGeometry( 0, 0, desk.width(), desk.height() );
42 if ( desk.height() < 250 ) {
43 int w = desk.height()/3;
44 logo.convertFromImage(Resource::loadImage("qtlogo").smoothScale(w,w));
45 } else {
46 logo = Resource::loadPixmap( "qtlogo" );
47 }
48 cd.screenPoints[QWSPointerCalibrationData::TopLeft] = QPoint( offset, offset );
49 cd.screenPoints[QWSPointerCalibrationData::BottomLeft] = QPoint( offset, qt_screen->deviceHeight() - offset );
50 cd.screenPoints[QWSPointerCalibrationData::BottomRight] = QPoint( qt_screen->deviceWidth() - offset, qt_screen->deviceHeight() - offset );
51 cd.screenPoints[QWSPointerCalibrationData::TopRight] = QPoint( qt_screen->deviceWidth() - offset, offset );
52 cd.screenPoints[QWSPointerCalibrationData::Center] = QPoint( qt_screen->deviceWidth()/2, qt_screen->deviceHeight()/2 );
53 goodcd = cd;
54 reset();
55
56 timer = new QTimer( this );
57 connect( timer, SIGNAL(timeout()), this, SLOT(timeout()) );
58}
59
60Calibrate::~Calibrate()
61{
62 store();
63}
64
65void Calibrate::show()
66{
67 grabMouse();
68 QWSServer::mouseHandler()->getCalibration(&goodcd);
69 QWSServer::mouseHandler()->clearCalibration();
70 QDialog::show();
71}
72
73void Calibrate::store()
74{
75 QWSServer::mouseHandler()->calibrate( &goodcd );
76}
77
78void Calibrate::hide()
79{
80 if ( isVisible() )
81 store();
82 QDialog::hide();
83}
84
85void Calibrate::reset()
86{
87 penPos = QPoint();
88 location = QWSPointerCalibrationData::TopLeft;
89 crossPos = fromDevice( cd.screenPoints[location] );
90}
91
92QPoint Calibrate::fromDevice( const QPoint &p )
93{
94 return qt_screen->mapFromDevice( p,
95 QSize(qt_screen->deviceWidth(), qt_screen->deviceHeight()) );
96}
97
98bool Calibrate::sanityCheck()
99{
100 QPoint tl = cd.devPoints[QWSPointerCalibrationData::TopLeft];
101 QPoint tr = cd.devPoints[QWSPointerCalibrationData::TopRight];
102 QPoint bl = cd.devPoints[QWSPointerCalibrationData::BottomLeft];
103 QPoint br = cd.devPoints[QWSPointerCalibrationData::BottomRight];
104
105 int vl = QABS( tl.y() - bl.y() );
106 int vr = QABS( tr.y() - br.y() );
107 int diff = QABS( vl - vr );
108 int avg = ( vl + vr ) / 2;
109 if ( diff > avg / 20 ) // 5% leeway
110 return FALSE;
111
112 int ht = QABS( tl.x() - tr.x() );
113 int hb = QABS( br.x() - bl.x() );
114 diff = QABS( ht - hb );
115 avg = ( ht + hb ) / 2;
116 if ( diff > avg / 20 ) // 5% leeway
117 return FALSE;
118
119 return TRUE;
120}
121
122void Calibrate::moveCrosshair( QPoint pt )
123{
124/*
125 QPainter p( this );
126 p.drawPixmap( crossPos.x()-8, crossPos.y()-8, saveUnder );
127 saveUnder = QPixmap::grabWindow( winId(), pt.x()-8, pt.y()-8, 16, 16 );
128 p.drawRect( pt.x()-1, pt.y()-8, 2, 7 );
129 p.drawRect( pt.x()-1, pt.y()+1, 2, 7 );
130 p.drawRect( pt.x()-8, pt.y()-1, 7, 2 );
131 p.drawRect( pt.x()+1, pt.y()-1, 7, 2 );
132*/
133 showCross = FALSE;
134 repaint( crossPos.x()-8, crossPos.y()-8, 16, 16 );
135 showCross = TRUE;
136 crossPos = pt;
137 repaint( crossPos.x()-8, crossPos.y()-8, 16, 16 );
138}
139
140void Calibrate::paintEvent( QPaintEvent * )
141{
142 QPainter p( this );
143
144 int y;
145
146 if ( !logo.isNull() ) {
147 y = height() / 2 - logo.height() - 15;
148 p.drawPixmap( (width() - logo.width())/2, y, logo );
149 }
150
151 y = height() / 2 + 15;
152
153 p.drawText( 0, y+height()/8, width(), height() - y, AlignHCenter,
154 tr("Touch the crosshairs firmly and\n"
155 "accurately to calibrate your screen.") );
156
157 QFont f = p.font(); f.setBold(TRUE);
158 p.setFont( f );
159 p.drawText( 0, y, width(), height() - y, AlignHCenter|WordBreak,
160 tr("Welcome to Qtopia") );
161
162/*
163 saveUnder = QPixmap::grabWindow( winId(), crossPos.x()-8, crossPos.y()-8,
164 16, 16 );
165 moveCrosshair( crossPos );
166*/
167 if ( showCross ) {
168 p.drawRect( crossPos.x()-1, crossPos.y()-8, 2, 7 );
169 p.drawRect( crossPos.x()-1, crossPos.y()+1, 2, 7 );
170 p.drawRect( crossPos.x()-8, crossPos.y()-1, 7, 2 );
171 p.drawRect( crossPos.x()+1, crossPos.y()-1, 7, 2 );
172 }
173}
174
175void Calibrate::mousePressEvent( QMouseEvent *e )
176{
177 // map to device coordinates
178 QPoint devPos = qt_screen->mapToDevice( e->pos(),
179 QSize(qt_screen->width(), qt_screen->height()) );
180 if ( penPos.isNull() )
181 penPos = devPos;
182 else
183 penPos = QPoint( (penPos.x() + devPos.x())/2,
184 (penPos.y() + devPos.y())/2 );
185}
186
187void Calibrate::mouseReleaseEvent( QMouseEvent * )
188{
189 if ( timer->isActive() )
190 return;
191
192 bool doMove = TRUE;
193
194 cd.devPoints[location] = penPos;
195 if ( location < QWSPointerCalibrationData::LastLocation ) {
196 location = (QWSPointerCalibrationData::Location)((int)location + 1);
197 } else {
198 if ( sanityCheck() ) {
199 reset();
200 goodcd = cd;
201 hide();
202 emit accept();
203 doMove = FALSE;
204 } else {
205 location = QWSPointerCalibrationData::TopLeft;
206 }
207 }
208
209 if ( doMove ) {
210 QPoint target = fromDevice( cd.screenPoints[location] );
211 dx = (target.x() - crossPos.x())/10;
212 dy = (target.y() - crossPos.y())/10;
213 timer->start( 30 );
214 }
215}
216
217void Calibrate::timeout()
218{
219 QPoint target = fromDevice( cd.screenPoints[location] );
220
221 bool doneX = FALSE;
222 bool doneY = FALSE;
223 QPoint newPos( crossPos.x() + dx, crossPos.y() + dy );
224
225 if ( QABS(crossPos.x() - target.x()) <= QABS(dx) ) {
226 newPos.setX( target.x() );
227 doneX = TRUE;
228 }
229
230 if ( QABS(crossPos.y() - target.y()) <= QABS(dy) ) {
231 newPos.setY(target.y());
232 doneY = TRUE;
233 }
234
235 if ( doneX && doneY ) {
236 penPos = QPoint();
237 timer->stop();
238 }
239
240 moveCrosshair( newPos );
241}
242
243#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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include <qwsmouse_qws.h>
22
23#if defined(Q_WS_QWS) || defined(_WS_QWS_)
24
25#include <qdialog.h>
26#include <qpixmap.h>
27
28class QTimer;
29
30class Calibrate : public QDialog
31{
32 Q_OBJECT
33public:
34 Calibrate(QWidget* parent=0, const char * name=0, WFlags=0);
35 ~Calibrate();
36
37 void show();
38 void hide();
39
40private:
41 QPoint fromDevice( const QPoint &p );
42 bool sanityCheck();
43 void moveCrosshair( QPoint pt );
44 void paintEvent( QPaintEvent * );
45 void mousePressEvent( QMouseEvent * );
46 void mouseReleaseEvent( QMouseEvent * );
47
48private slots:
49 void timeout();
50
51private:
52 void store();
53 void reset();
54 QPixmap logo;
55 QWSPointerCalibrationData goodcd,cd;
56 QWSPointerCalibrationData::Location location;
57 QPoint crossPos;
58 QPoint penPos;
59 QPixmap saveUnder;
60 QTimer *timer;
61 int dx;
62 int dy;
63 bool showCross;
64};
65
66#endif // _WS_QWS_
67
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 @@
1moc_*
2Makefile
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 @@
1#############################################################################
2
3####### Compiler, tools and options
4
5 CXX =$(SYSCONF_CXX) $(QT_CXX_MT)
6 CXXFLAGS=$(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
7 CC =$(SYSCONF_CC) $(QT_C_MT)
8 CFLAGS =$(SYSCONF_CFLAGS)
9 INCPATH =-I$(QPEDIR)/include
10 LFLAGS =$(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
11 LIBS =$(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
12 MOC =$(SYSCONF_MOC)
13 UIC =$(SYSCONF_UIC)
14
15####### Target
16
17DESTDIR = $(QPEDIR)/bin/
18VER_MAJ = 1
19VER_MIN = 0
20VER_PATCH = 0
21 TARGET= embeddedkonsole
22TARGET1 = lib$(TARGET).so.$(VER_MAJ)
23
24####### Files
25
26 HEADERS =TEWidget.h \
27 TEScreen.h \
28 TECommon.h \
29 TEHistory.h \
30 TEmulation.h \
31 TEmuVt102.h \
32 session.h \
33 keytrans.h \
34 konsole.h \
35 MyPty.h
36 SOURCES =TEScreen.cpp \
37 TEWidget.cpp \
38 TEHistory.cpp \
39 TEmulation.cpp \
40 TEmuVt102.cpp \
41 session.cpp \
42 keytrans.cpp \
43 konsole.cpp \
44 main.cpp \
45 MyPty.cpp
46 OBJECTS =TEScreen.o \
47 TEWidget.o \
48 TEHistory.o \
49 TEmulation.o \
50 TEmuVt102.o \
51 session.o \
52 keytrans.o \
53 konsole.o \
54 main.o \
55 MyPty.o
56INTERFACES =
57UICDECLS =
58UICIMPLS =
59 SRCMOC =moc_TEWidget.cpp \
60 moc_TEmulation.cpp \
61 moc_TEmuVt102.cpp \
62 moc_session.cpp \
63 moc_konsole.cpp \
64 moc_MyPty.cpp
65 OBJMOC =moc_TEWidget.o \
66 moc_TEmulation.o \
67 moc_TEmuVt102.o \
68 moc_session.o \
69 moc_konsole.o \
70 moc_MyPty.o
71
72
73####### Implicit rules
74
75.SUFFIXES: .cpp .cxx .cc .C .c
76
77.cpp.o:
78 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
79
80.cxx.o:
81 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
82
83.cc.o:
84 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
85
86.C.o:
87 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
88
89.c.o:
90 $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
91
92####### Build rules
93
94
95all: $(DESTDIR)$(TARGET)
96
97$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
98 $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
99
100moc: $(SRCMOC)
101
102tmake:
103 tmake embeddedkonsole.pro
104
105clean:
106 -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
107 -rm -f *~ core
108 -rm -f allmoc.cpp
109
110####### Extension Modules
111
112listpromodules:
113 @echo
114
115listallmodules:
116 @echo
117
118listaddonpromodules:
119 @echo
120
121listaddonentmodules:
122 @echo
123
124
125REQUIRES=embeddedkonsole
126
127####### Sub-libraries
128
129
130###### Combined headers
131
132
133
134####### Compile
135
136TEScreen.o: TEScreen.cpp \
137 TEScreen.h \
138 TECommon.h \
139 TEHistory.h
140
141TEWidget.o: TEWidget.cpp \
142 TEWidget.h \
143 TECommon.h \
144 session.h \
145 MyPty.h \
146 TEmuVt102.h \
147 TEScreen.h \
148 TEHistory.h \
149 TEmulation.h \
150 keytrans.h
151
152TEHistory.o: TEHistory.cpp \
153 TEHistory.h \
154 TECommon.h
155
156TEmulation.o: TEmulation.cpp \
157 TEmulation.h \
158 TEWidget.h \
159 TECommon.h \
160 TEScreen.h \
161 TEHistory.h \
162 keytrans.h
163
164TEmuVt102.o: TEmuVt102.cpp \
165 TEmuVt102.h \
166 TEWidget.h \
167 TECommon.h \
168 TEScreen.h \
169 TEHistory.h \
170 TEmulation.h \
171 keytrans.h
172
173session.o: session.cpp \
174 session.h \
175 MyPty.h \
176 TEWidget.h \
177 TECommon.h \
178 TEmuVt102.h \
179 TEScreen.h \
180 TEHistory.h \
181 TEmulation.h \
182 keytrans.h
183
184keytrans.o: keytrans.cpp \
185 keytrans.h \
186 $(QPEDIR)/include/qpe/qpeapplication.h \
187 default.keytab.h
188
189konsole.o: konsole.cpp \
190 $(QPEDIR)/include/qpe/resource.h \
191 $(QPEDIR)/include/qpe/qpetoolbar.h \
192 $(QPEDIR)/include/qpe/qpemenubar.h \
193 konsole.h \
194 MyPty.h \
195 TEWidget.h \
196 TECommon.h \
197 TEmuVt102.h \
198 TEScreen.h \
199 TEHistory.h \
200 TEmulation.h \
201 keytrans.h \
202 session.h
203
204main.o: main.cpp \
205 konsole.h \
206 MyPty.h \
207 TEWidget.h \
208 TECommon.h \
209 TEmuVt102.h \
210 TEScreen.h \
211 TEHistory.h \
212 TEmulation.h \
213 keytrans.h \
214 session.h \
215 $(QPEDIR)/include/qpe/qpeapplication.h
216
217MyPty.o: MyPty.cpp \
218 MyPty.h
219
220moc_TEWidget.o: moc_TEWidget.cpp \
221 TEWidget.h \
222 TECommon.h
223
224moc_TEmulation.o: moc_TEmulation.cpp \
225 TEmulation.h \
226 TEWidget.h \
227 TECommon.h \
228 TEScreen.h \
229 TEHistory.h \
230 keytrans.h
231
232moc_TEmuVt102.o: moc_TEmuVt102.cpp \
233 TEmuVt102.h \
234 TEWidget.h \
235 TECommon.h \
236 TEScreen.h \
237 TEHistory.h \
238 TEmulation.h \
239 keytrans.h
240
241moc_session.o: moc_session.cpp \
242 session.h \
243 MyPty.h \
244 TEWidget.h \
245 TECommon.h \
246 TEmuVt102.h \
247 TEScreen.h \
248 TEHistory.h \
249 TEmulation.h \
250 keytrans.h
251
252moc_konsole.o: moc_konsole.cpp \
253 konsole.h \
254 MyPty.h \
255 TEWidget.h \
256 TECommon.h \
257 TEmuVt102.h \
258 TEScreen.h \
259 TEHistory.h \
260 TEmulation.h \
261 keytrans.h \
262 session.h
263
264moc_MyPty.o: moc_MyPty.cpp \
265 MyPty.h
266
267moc_TEWidget.cpp: TEWidget.h
268 $(MOC) TEWidget.h -o moc_TEWidget.cpp
269
270moc_TEmulation.cpp: TEmulation.h
271 $(MOC) TEmulation.h -o moc_TEmulation.cpp
272
273moc_TEmuVt102.cpp: TEmuVt102.h
274 $(MOC) TEmuVt102.h -o moc_TEmuVt102.cpp
275
276moc_session.cpp: session.h
277 $(MOC) session.h -o moc_session.cpp
278
279moc_konsole.cpp: konsole.h
280 $(MOC) konsole.h -o moc_konsole.cpp
281
282moc_MyPty.cpp: MyPty.h
283 $(MOC) MyPty.h -o moc_MyPty.cpp
284
285
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 @@
1/* -------------------------------------------------------------------------- */
2/* */
3/* [MyPty.C] Pseudo Terminal Device */
4/* */
5/* -------------------------------------------------------------------------- */
6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */
9/* This file is part of Konsole - an X terminal for KDE */
10/* -------------------------------------------------------------------------- */
11 /* */
12/* Ported Konsole to Qt/Embedded */
13 /* */
14/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
15 /* */
16/* -------------------------------------------------------------------------- */
17
18/* If you're compiling konsole on non-Linux platforms and find
19 problems that you can track down to this file, please have
20 a look into ../README.ports, too.
21*/
22
23/*! \file
24*/
25
26/*! \class TEPty
27
28 \brief Ptys provide a pseudo terminal connection to a program.
29
30 Although closely related to pipes, these pseudo terminal connections have
31 some ability, that makes it nessesary to uses them. Most importent, they
32 know about changing screen sizes and UNIX job control.
33
34 Within the terminal emulation framework, this class represents the
35 host side of the terminal together with the connecting serial line.
36
37 One can create many instances of this class within a program.
38 As a side effect of using this class, a signal(2) handler is
39 installed on SIGCHLD.
40
41 \par FIXME
42
43 [NOTE: much of the technical stuff below will be replaced by forkpty.]
44
45 publish the SIGCHLD signal if not related to an instance.
46
47 clearify TEPty::done vs. TEPty::~TEPty semantics.
48 check if pty is restartable via run after done.
49
50 \par Pseudo terminals
51
52 Pseudo terminals are a unique feature of UNIX, and always come in form of
53 pairs of devices (/dev/ptyXX and /dev/ttyXX), which are connected to each
54 other by the operating system. One may think of them as two serial devices
55 linked by a null-modem cable. Being based on devices the number of
56 simultanous instances of this class is (globally) limited by the number of
57 those device pairs, which is 256.
58
59 Another technic are UNIX 98 PTY's. These are supported also, and prefered
60 over the (obsolete) predecessor.
61
62 There's a sinister ioctl(2), signal(2) and job control stuff
63 nessesary to make everything work as it should.
64*/
65
66
67#include <qapplication.h>
68#include <qsocketnotifier.h>
69#include <qstring.h>
70
71#include <stdlib.h>
72#include <stdio.h>
73#include <signal.h>
74#include <fcntl.h>
75#include <unistd.h>
76#include <termios.h>
77#include <sys/types.h>
78#include <sys/ioctl.h>
79#include <sys/wait.h>
80
81#ifdef HAVE_OPENPTY
82#include <pty.h>
83#endif
84
85#include "MyPty.h"
86
87
88#undef VERBOSE_DEBUG
89
90
91/* -------------------------------------------------------------------------- */
92
93/*!
94 Informs the client program about the
95 actual size of the window.
96*/
97
98void MyPty::setSize(int lines, int columns)
99{
100 struct winsize wsize;
101 wsize.ws_row = (unsigned short)lines;
102 wsize.ws_col = (unsigned short)columns;
103 if(fd < 0) return;
104 ioctl(fd,TIOCSWINSZ,(char *)&wsize);
105}
106
107
108void MyPty::donePty()
109{
110 // This is code from the Qt DumbTerminal example
111 int status = 0;
112
113 ::close(fd);
114
115 if (cpid) {
116 kill(cpid, SIGHUP);
117 waitpid(cpid, &status, 0);
118 }
119
120 emit done(status);
121}
122
123
124const char* MyPty::deviceName()
125{
126 return ttynam;
127}
128
129
130void MyPty::error()
131{
132 // This is code from the Qt DumbTerminal example
133 donePty();
134}
135
136
137/*!
138 start the client program.
139*/
140int MyPty::run(const char* cmd, QStrList &, const char*, int)
141{
142 // This is code from the Qt DumbTerminal example
143 cpid = fork();
144
145 if ( !cpid ) {
146 // child - exec shell on tty
147 for (int sig = 1; sig < NSIG; sig++) signal(sig,SIG_DFL);
148 int ttyfd = open(ttynam, O_RDWR);
149 dup2(ttyfd, STDIN_FILENO);
150 dup2(ttyfd, STDOUT_FILENO);
151 dup2(ttyfd, STDERR_FILENO);
152 // should be done with tty, so close it
153 close(ttyfd);
154 static struct termios ttmode;
155 if ( setsid() < 0 )
156 perror( "failed to set process group" );
157#if defined (TIOCSCTTY)
158 // grabbed from APUE by Stevens
159 ioctl(STDIN_FILENO, TIOCSCTTY, 0);
160#endif
161 tcgetattr( STDIN_FILENO, &ttmode );
162 ttmode.c_cc[VINTR] = 3;
163 ttmode.c_cc[VERASE] = 8;
164 tcsetattr( STDIN_FILENO, TCSANOW, &ttmode );
165 setenv("TERM","vt100",1);
166 setenv("COLORTERM","0",1);
167
168 if (getuid() == 0) {
169 char msg[] = "WARNING: You are running this shell as root!\n";
170 write(ttyfd, msg, sizeof(msg));
171 }
172 execl(cmd, cmd, 0);
173
174 donePty();
175 exit(-1);
176 }
177
178 // parent - continue as a widget
179 QSocketNotifier* sn_r = new QSocketNotifier(fd,QSocketNotifier::Read,this);
180 QSocketNotifier* sn_e = new QSocketNotifier(fd,QSocketNotifier::Exception,this);
181 connect(sn_r,SIGNAL(activated(int)),this,SLOT(readPty()));
182 connect(sn_e,SIGNAL(activated(int)),this,SLOT(error()));
183
184 return 0;
185}
186
187int MyPty::openPty()
188{
189 // This is code from the Qt DumbTerminal example
190 int ptyfd = -1;
191
192#ifdef HAVE_OPENPTY
193 int ttyfd;
194 if ( openpty(&ptyfd,&ttyfd,ttynam,0,0) )
195 ptyfd = -1;
196 else
197 close(ttyfd); // we open the ttynam ourselves.
198#else
199 for (const char* c0 = "pqrstuvwxyzabcde"; ptyfd < 0 && *c0 != 0; c0++) {
200 for (const char* c1 = "0123456789abcdef"; ptyfd < 0 && *c1 != 0; c1++) {
201 sprintf(ptynam,"/dev/pty%c%c",*c0,*c1);
202 sprintf(ttynam,"/dev/tty%c%c",*c0,*c1);
203 if ((ptyfd = ::open(ptynam,O_RDWR)) >= 0) {
204 if (geteuid() != 0 && !access(ttynam,R_OK|W_OK) == 0) {
205 ::close(ptyfd);
206 ptyfd = -1;
207 }
208 }
209 }
210 }
211#endif
212
213 if ( ptyfd < 0 ) {
214 qApp->exit(1);
215 return -1;
216 }
217
218 return ptyfd;
219}
220
221/*!
222 Create an instance.
223*/
224MyPty::MyPty() : cpid(0)
225{
226 fd = openPty();
227}
228
229/*!
230 Destructor.
231 Note that the related client program is not killed
232 (yet) when a instance is deleted.
233*/
234MyPty::~MyPty()
235{
236 donePty();
237}
238
239
240/*! sends len bytes through the line */
241void MyPty::send_bytes(const char* s, int len)
242{
243
244#ifdef VERBOSE_DEBUG
245 // verbose debug
246 printf("sending bytes:\n");
247 for (int i = 0; i < len; i++)
248 printf("%c", s[i]);
249 printf("\n");
250#endif
251
252 ::write(fd, s, len);
253}
254
255/*! indicates that a block of data is received */
256void MyPty::readPty()
257{
258 char buf[4096];
259
260 int len = ::read( fd, buf, 4096 );
261
262 if (len == -1)
263 donePty();
264
265 if (len < 0)
266 return;
267
268 emit block_in(buf,len);
269
270#ifdef VERBOSE_DEBUG
271 // verbose debug
272 printf("read bytes:\n");
273 for (int i = 0; i < len; i++)
274 printf("%c", buf[i]);
275 printf("\n");
276#endif
277
278}
279
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 @@
1/* -------------------------------------------------------------------------- */
2/* */
3/* [MyPty.h] Pseudo Terminal Device */
4/* */
5/* -------------------------------------------------------------------------- */
6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */
9/* This file is part of Konsole - an X terminal for KDE */
10/* */
11/* -------------------------------------------------------------------------- */
12 /* */
13/* Ported Konsole to Qt/Embedded */
14 /* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16 /* */
17/* -------------------------------------------------------------------------- */
18
19/*! \file
20*/
21
22#ifndef MY_PTY_H
23#define MY_PTY_H
24
25#include <qobject.h>
26#include <qstrlist.h>
27
28
29class MyPty : public QObject
30{
31Q_OBJECT
32
33 public:
34
35 MyPty();
36 ~MyPty();
37
38 /*!
39 having a `run' separate from the constructor allows to make
40 the necessary connections to the signals and slots of the
41 instance before starting the execution of the client.
42 */
43 int run(const char* pgm, QStrList & args, const char* term, int addutmp);
44
45 public slots:
46
47 void send_bytes(const char* s, int len);
48 void setSize(int lines, int columns);
49 void error();
50
51 signals:
52
53 /*!
54 emitted when the client program terminates.
55 \param status the wait(2) status code of the terminated client program.
56 */
57 void done(int status);
58
59 /*!
60 emitted when a new block of data comes in.
61 \param s - the data
62 \param len - the length of the block
63 */
64 void block_in(const char* s, int len);
65
66 public:
67
68 void send_byte(char s);
69// void send_string(const char* s);
70
71 const char* deviceName();
72
73 protected slots:
74 void readPty();
75 void donePty();
76
77 private:
78 int openPty();
79
80 private:
81
82 char ptynam[16]; // "/dev/ptyxx" | "/dev/ptmx"
83 char ttynam[16]; // "/dev/ttyxx" | "/dev/pts/########..."
84 int fd;
85 int cpid;
86};
87
88#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 @@
1/* -------------------------------------------------------------------------- */
2/* */
3/* [TECommon.h] Common Definitions */
4/* */
5/* -------------------------------------------------------------------------- */
6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */
9/* This file is part of Konsole - an X terminal for KDE */
10/* */
11/* -------------------------------------------------------------------------- */
12 /* */
13/* Ported Konsole to Qt/Embedded */
14 /* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16 /* */
17/* -------------------------------------------------------------------------- */
18
19/*! \file TECommon.h
20 \brief Definitions shared between TEScreen and TEWidget.
21*/
22
23#ifndef TECOMMON_H
24#define TECOMMON_H
25
26#include <qcolor.h>
27
28#ifndef BOOL
29typedef int BOOL;
30#endif
31
32#ifndef FALSE
33#define FALSE 0
34#endif
35
36#ifndef TRUE
37#define TRUE 1
38#endif
39
40#ifndef UINT8
41typedef unsigned char UINT8;
42#endif
43
44#ifndef UINT16
45typedef unsigned short UINT16;
46#endif
47
48// Attributed Character Representations ///////////////////////////////
49
50// Colors
51
52#define BASE_COLORS (2+8)
53#define INTENSITIES 2
54#define TABLE_COLORS (INTENSITIES*BASE_COLORS)
55
56#define DEFAULT_FORE_COLOR 0
57#define DEFAULT_BACK_COLOR 1
58
59#define DEFAULT_RENDITION 0
60#define RE_BOLD (1 << 0)
61#define RE_BLINK (1 << 1)
62#define RE_UNDERLINE (1 << 2)
63#define RE_REVERSE (1 << 3) // Screen only
64#define RE_INTENSIVE (1 << 3) // Widget only
65
66/*! \class ca
67 * \brief a character with rendition attributes.
68*/
69
70class ca
71{
72public:
73 inline ca(UINT16 _c = ' ',
74 UINT8 _f = DEFAULT_FORE_COLOR,
75 UINT8 _b = DEFAULT_BACK_COLOR,
76 UINT8 _r = DEFAULT_RENDITION)
77 : c(_c), f(_f), b(_b), r(_r) {}
78public:
79 UINT16 c; // character
80 UINT8 f; // foreground color
81 UINT8 b; // background color
82 UINT8 r; // rendition
83public:
84 friend BOOL operator == (ca a, ca b);
85 friend BOOL operator != (ca a, ca b);
86};
87
88inline BOOL operator == (ca a, ca b)
89{
90 return a.c == b.c && a.f == b.f && a.b == b.b && a.r == b.r;
91}
92
93inline BOOL operator != (ca a, ca b)
94{
95 return a.c != b.c || a.f != b.f || a.b != b.b || a.r != b.r;
96}
97
98/*!
99*/
100struct ColorEntry
101{
102 ColorEntry(QColor c, bool tr, bool b) : color(c), transparent(tr), bold(b) {}
103 ColorEntry() : transparent(false), bold(false) {} // default constructors
104 void operator=(const ColorEntry& rhs) {
105 color = rhs.color;
106 transparent = rhs.transparent;
107 bold = rhs.bold;
108 }
109 QColor color;
110 bool transparent; // if used on bg
111 bool bold; // if used on fg
112};
113
114#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 @@
1/* -------------------------------------------------------------------------- */
2/* */
3/* [TEHistory.C] History Buffer */
4/* */
5/* -------------------------------------------------------------------------- */
6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */
9/* This file is part of Konsole - an X terminal for KDE */
10/* */
11/* -------------------------------------------------------------------------- */
12 /* */
13/* Ported Konsole to Qt/Embedded */
14 /* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16 /* */
17/* -------------------------------------------------------------------------- */
18
19#include "TEHistory.h"
20#include <stdlib.h>
21#include <assert.h>
22#include <stdio.h>
23#include <sys/types.h>
24#include <unistd.h>
25#include <errno.h>
26
27#define HERE printf("%s(%d): here\n",__FILE__,__LINE__)
28
29/*
30 An arbitrary long scroll.
31
32 One can modify the scroll only by adding either cells
33 or newlines, but access it randomly.
34
35 The model is that of an arbitrary wide typewriter scroll
36 in that the scroll is a serie of lines and each line is
37 a serie of cells with no overwriting permitted.
38
39 The implementation provides arbitrary length and numbers
40 of cells and line/column indexed read access to the scroll
41 at constant costs.
42
43FIXME: some complain about the history buffer comsuming the
44 memory of their machines. This problem is critical
45 since the history does not behave gracefully in cases
46 where the memory is used up completely.
47
48 I put in a workaround that should handle it problem
49 now gracefully. I'm not satisfied with the solution.
50
51FIXME: Terminating the history is not properly indicated
52 in the menu. We should throw a signal.
53
54FIXME: There is noticable decrease in speed, also. Perhaps,
55 there whole feature needs to be revisited therefore.
56 Disadvantage of a more elaborated, say block-oriented
57 scheme with wrap around would be it's complexity.
58*/
59
60//FIXME: tempory replacement for tmpfile
61// this is here one for debugging purpose.
62
63//#define tmpfile xTmpFile
64
65FILE* xTmpFile()
66{
67 static int fid = 0;
68 char fname[80];
69 sprintf(fname,"TmpFile.%d",fid++);
70 return fopen(fname,"w");
71}
72
73
74// History Buffer ///////////////////////////////////////////
75
76/*
77 A Row(X) data type which allows adding elements to the end.
78*/
79
80HistoryBuffer::HistoryBuffer()
81{
82 ion = -1;
83 length = 0;
84}
85
86HistoryBuffer::~HistoryBuffer()
87{
88 setScroll(FALSE);
89}
90
91void HistoryBuffer::setScroll(bool on)
92{
93 if (on == hasScroll()) return;
94
95 if (on)
96 {
97 assert( ion < 0 );
98 assert( length == 0);
99 FILE* tmp = tmpfile(); if (!tmp) { perror("konsole: cannot open temp file.\n"); return; }
100 ion = dup(fileno(tmp)); if (ion<0) perror("konsole: cannot dup temp file.\n");
101 fclose(tmp);
102 }
103 else
104 {
105 assert( ion >= 0 );
106 close(ion);
107 ion = -1;
108 length = 0;
109 }
110}
111
112bool HistoryBuffer::hasScroll()
113{
114 return ion >= 0;
115}
116
117void HistoryBuffer::add(const unsigned char* bytes, int len)
118{ int rc;
119 assert(hasScroll());
120 rc = lseek(ion,length,SEEK_SET); if (rc < 0) { perror("HistoryBuffer::add.seek"); setScroll(FALSE); return; }
121 rc = write(ion,bytes,len); if (rc < 0) { perror("HistoryBuffer::add.write"); setScroll(FALSE); return; }
122 length += rc;
123}
124
125void HistoryBuffer::get(unsigned char* bytes, int len, int loc)
126{ int rc;
127 assert(hasScroll());
128 if (loc < 0 || len < 0 || loc + len > length)
129 fprintf(stderr,"getHist(...,%d,%d): invalid args.\n",len,loc);
130 rc = lseek(ion,loc,SEEK_SET); if (rc < 0) { perror("HistoryBuffer::get.seek"); setScroll(FALSE); return; }
131 rc = read(ion,bytes,len); if (rc < 0) { perror("HistoryBuffer::get.read"); setScroll(FALSE); return; }
132}
133
134int HistoryBuffer::len()
135{
136 return length;
137}
138
139// History Scroll //////////////////////////////////////
140
141/*
142 The history scroll makes a Row(Row(Cell)) from
143 two history buffers. The index buffer contains
144 start of line positions which refere to the cells
145 buffer.
146
147 Note that index[0] addresses the second line
148 (line #1), while the first line (line #0) starts
149 at 0 in cells.
150*/
151
152HistoryScroll::HistoryScroll()
153{
154}
155
156HistoryScroll::~HistoryScroll()
157{
158}
159
160void HistoryScroll::setScroll(bool on)
161{
162 index.setScroll(on);
163 cells.setScroll(on);
164}
165
166bool HistoryScroll::hasScroll()
167{
168 return index.hasScroll() && cells.hasScroll();
169}
170
171int HistoryScroll::getLines()
172{
173 if (!hasScroll()) return 0;
174 return index.len() / sizeof(int);
175}
176
177int HistoryScroll::getLineLen(int lineno)
178{
179 if (!hasScroll()) return 0;
180 return (startOfLine(lineno+1) - startOfLine(lineno)) / sizeof(ca);
181}
182
183int HistoryScroll::startOfLine(int lineno)
184{
185 if (lineno <= 0) return 0;
186 if (!hasScroll()) return 0;
187 if (lineno <= getLines())
188 { int res;
189 index.get((unsigned char*)&res,sizeof(int),(lineno-1)*sizeof(int));
190 return res;
191 }
192 return cells.len();
193}
194
195void HistoryScroll::getCells(int lineno, int colno, int count, ca res[])
196{
197 assert(hasScroll());
198 cells.get((unsigned char*)res,count*sizeof(ca),startOfLine(lineno)+colno*sizeof(ca));
199}
200
201void HistoryScroll::addCells(ca text[], int count)
202{
203 if (!hasScroll()) return;
204 cells.add((unsigned char*)text,count*sizeof(ca));
205}
206
207void HistoryScroll::addLine()
208{
209 if (!hasScroll()) return;
210 int locn = cells.len();
211 index.add((unsigned char*)&locn,sizeof(int));
212}
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 @@
1/* -------------------------------------------------------------------------- */
2/* */
3/* [TEHistory.H] History Buffer */
4/* */
5/* -------------------------------------------------------------------------- */
6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */
9/* This file is part of Konsole - an X terminal for KDE */
10/* */
11/* -------------------------------------------------------------------------- */
12 /* */
13/* Ported Konsole to Qt/Embedded */
14 /* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16 /* */
17/* -------------------------------------------------------------------------- */
18
19#ifndef TEHISTORY_H
20#define TEHISTORY_H
21
22#include "TECommon.h"
23
24/*
25 An extendable tmpfile(1) based buffer.
26*/
27class HistoryBuffer
28{
29public:
30 HistoryBuffer();
31 ~HistoryBuffer();
32
33public:
34 void setScroll(bool on);
35 bool hasScroll();
36
37public:
38 void add(const unsigned char* bytes, int len);
39 void get(unsigned char* bytes, int len, int loc);
40 int len();
41
42private:
43 int ion;
44 int length;
45};
46
47class HistoryScroll
48{
49public:
50 HistoryScroll();
51 ~HistoryScroll();
52
53public:
54 void setScroll(bool on);
55 bool hasScroll();
56
57public: // access to history
58 int getLines();
59 int getLineLen(int lineno);
60 void getCells(int lineno, int colno, int count, ca res[]);
61
62public: // backward compatibility (obsolete)
63 ca getCell(int lineno, int colno) { ca res; getCells(lineno,colno,1,&res); return res; }
64
65public: // adding lines.
66 void addCells(ca a[], int count);
67 void addLine();
68
69private:
70 int startOfLine(int lineno);
71 HistoryBuffer index; // lines Row(int)
72 HistoryBuffer cells; // text Row(ca)
73};
74
75#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 @@
1/* -------------------------------------------------------------------------- */
2/* */
3/* [TEScreen.C] Screen Data Type */
4/* */
5/* -------------------------------------------------------------------------- */
6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */
9/* This file is part of Konsole - an X terminal for KDE */
10/* */
11/* -------------------------------------------------------------------------- */
12 /* */
13/* Ported Konsole to Qt/Embedded */
14 /* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16 /* */
17/* -------------------------------------------------------------------------- */
18
19/*! \file
20*/
21
22/*! \class TEScreen
23
24 \brief The image manipulated by the emulation.
25
26 This class implements the operations of the terminal emulation framework.
27 It is a complete passive device, driven by the emulation decoder
28 (TEmuVT102). By this it forms in fact an ADT, that defines operations
29 on a rectangular image.
30
31 It does neither know how to display its image nor about escape sequences.
32 It is further independent of the underlying toolkit. By this, one can even
33 use this module for an ordinary text surface.
34
35 Since the operations are called by a specific emulation decoder, one may
36 collect their different operations here.
37
38 The state manipulated by the operations is mainly kept in `image', though
39 it is a little more complex bejond this. See the header file of the class.
40
41 \sa TEWidget \sa VT102Emulation
42*/
43
44#include <stdio.h>
45#include <stdlib.h>
46#include <unistd.h>
47// #include <kdebug.h>
48
49#include <assert.h>
50#include <string.h>
51#include <ctype.h>
52
53#include "TEScreen.h"
54
55#define HERE printf("%s(%d): here\n",__FILE__,__LINE__)
56
57//FIXME: this is emulation specific. Use FALSE for xterm, TRUE for ANSI.
58//FIXME: see if we can get this from terminfo.
59#define BS_CLEARS FALSE
60
61#define loc(X,Y) ((Y)*columns+(X))
62
63/*! creates a `TEScreen' of `lines' lines and `columns' columns.
64*/
65
66TEScreen::TEScreen(int lines, int columns)
67{
68 this->lines = lines;
69 this->columns = columns;
70
71 image = (ca*) malloc(lines*columns*sizeof(ca));
72 tabstops = NULL; initTabStops();
73
74 histCursor = 0;
75
76 clearSelection();
77 reset();
78}
79
80/*! Destructor
81*/
82
83TEScreen::~TEScreen()
84{
85 free(image);
86 if (tabstops) free(tabstops);
87}
88
89/* ------------------------------------------------------------------------- */
90/* */
91/* Normalized Screen Operations */
92/* */
93/* ------------------------------------------------------------------------- */
94
95// Cursor Setting --------------------------------------------------------------
96
97/*! \section Cursor
98
99 The `cursor' is a location within the screen that is implicitely used in
100 many operations. The operations within this section allow to manipulate
101 the cursor explicitly and to obtain it's value.
102
103 The position of the cursor is guarantied to be between (including) 0 and
104 `columns-1' and `lines-1'.
105*/
106
107/*!
108 Move the cursor up.
109
110 The cursor will not be moved beyond the top margin.
111*/
112
113void TEScreen::cursorUp(int n)
114//=CUU
115{
116 if (n == 0) n = 1; // Default
117 int stop = cuY < tmargin ? 0 : tmargin;
118 cuX = QMIN(columns-1,cuX); // nowrap!
119 cuY = QMAX(stop,cuY-n);
120}
121
122/*!
123 Move the cursor down.
124
125 The cursor will not be moved beyond the bottom margin.
126*/
127
128void TEScreen::cursorDown(int n)
129//=CUD
130{
131 if (n == 0) n = 1; // Default
132 int stop = cuY > bmargin ? lines-1 : bmargin;
133 cuX = QMIN(columns-1,cuX); // nowrap!
134 cuY = QMIN(stop,cuY+n);
135}
136
137/*!
138 Move the cursor left.
139
140 The cursor will not move beyond the first column.
141*/
142
143void TEScreen::cursorLeft(int n)
144//=CUB
145{
146 if (n == 0) n = 1; // Default
147 cuX = QMIN(columns-1,cuX); // nowrap!
148 cuX = QMAX(0,cuX-n);
149}
150
151/*!
152 Move the cursor left.
153
154 The cursor will not move beyond the rightmost column.
155*/
156
157void TEScreen::cursorRight(int n)
158//=CUF
159{
160 if (n == 0) n = 1; // Default
161 cuX = QMIN(columns-1,cuX+n);
162}
163
164/*!
165 Set top and bottom margin.
166*/
167
168void TEScreen::setMargins(int top, int bot)
169//=STBM
170{
171 if (top == 0) top = 1; // Default
172 if (bot == 0) bot = lines; // Default
173 top = top - 1; // Adjust to internal lineno
174 bot = bot - 1; // Adjust to internal lineno
175 if ( !( 0 <= top && top < bot && bot < lines ) )
176 { fprintf(stderr,"%s(%d) : setRegion(%d,%d) : bad range.\n",
177 __FILE__,__LINE__,top,bot);
178 return; // Default error action: ignore
179 }
180 tmargin = top;
181 bmargin = bot;
182 cuX = 0;
183 cuY = getMode(MODE_Origin) ? top : 0;
184}
185
186/*!
187 Move the cursor down one line.
188
189 If cursor is on bottom margin, the region between the
190 actual top and bottom margin is scrolled up instead.
191*/
192
193void TEScreen::index()
194//=IND
195{
196 if (cuY == bmargin)
197 {
198 if (tmargin == 0 && bmargin == lines-1) addHistLine(); // hist.history
199 scrollUp(tmargin,1);
200 }
201 else if (cuY < lines-1)
202 cuY += 1;
203}
204
205/*!
206 Move the cursor up one line.
207
208 If cursor is on the top margin, the region between the
209 actual top and bottom margin is scrolled down instead.
210*/
211
212void TEScreen::reverseIndex()
213//=RI
214{
215 if (cuY == tmargin)
216 scrollDown(tmargin,1);
217 else if (cuY > 0)
218 cuY -= 1;
219}
220
221/*!
222 Move the cursor to the begin of the next line.
223
224 If cursor is on bottom margin, the region between the
225 actual top and bottom margin is scrolled up.
226*/
227
228void TEScreen::NextLine()
229//=NEL
230{
231 Return(); index();
232}
233
234// Line Editing ----------------------------------------------------------------
235
236/*! \section inserting / deleting characters
237*/
238
239/*! erase `n' characters starting from (including) the cursor position.
240
241 The line is filled in from the right with spaces.
242*/
243
244void TEScreen::eraseChars(int n)
245{
246 if (n == 0) n = 1; // Default
247 int p = QMAX(0,QMIN(cuX+n-1,columns-1));
248 clearImage(loc(cuX,cuY),loc(p,cuY),' ');
249}
250
251/*! delete `n' characters starting from (including) the cursor position.
252
253 The line is filled in from the right with spaces.
254*/
255
256void TEScreen::deleteChars(int n)
257{
258 if (n == 0) n = 1; // Default
259 int p = QMAX(0,QMIN(cuX+n,columns-1));
260 moveImage(loc(cuX,cuY),loc(p,cuY),loc(columns-1,cuY));
261 clearImage(loc(columns-n,cuY),loc(columns-1,cuY),' ');
262}
263
264/*! insert `n' spaces at the cursor position.
265
266 The cursor is not moved by the operation.
267*/
268
269void TEScreen::insertChars(int n)
270{
271 if (n == 0) n = 1; // Default
272 int p = QMAX(0,QMIN(columns-1-n,columns-1));
273 int q = QMAX(0,QMIN(cuX+n,columns-1));
274 moveImage(loc(q,cuY),loc(cuX,cuY),loc(p,cuY));
275 clearImage(loc(cuX,cuY),loc(q-1,cuY),' ');
276}
277
278/*! delete `n' lines starting from (including) the cursor position.
279
280 The cursor is not moved by the operation.
281*/
282
283void TEScreen::deleteLines(int n)
284{
285 if (n == 0) n = 1; // Default
286 scrollUp(cuY,n);
287}
288
289/*! insert `n' lines at the cursor position.
290
291 The cursor is not moved by the operation.
292*/
293
294void TEScreen::insertLines(int n)
295{
296 if (n == 0) n = 1; // Default
297 scrollDown(cuY,n);
298}
299
300// Mode Operations -----------------------------------------------------------
301
302/*! Set a specific mode. */
303
304void TEScreen::setMode(int m)
305{
306 currParm.mode[m] = TRUE;
307 switch(m)
308 {
309 case MODE_Origin : cuX = 0; cuY = tmargin; break; //FIXME: home
310 }
311}
312
313/*! Reset a specific mode. */
314
315void TEScreen::resetMode(int m)
316{
317 currParm.mode[m] = FALSE;
318 switch(m)
319 {
320 case MODE_Origin : cuX = 0; cuY = 0; break; //FIXME: home
321 }
322}
323
324/*! Save a specific mode. */
325
326void TEScreen::saveMode(int m)
327{
328 saveParm.mode[m] = currParm.mode[m];
329}
330
331/*! Restore a specific mode. */
332
333void TEScreen::restoreMode(int m)
334{
335 currParm.mode[m] = saveParm.mode[m];
336}
337
338//NOTE: this is a helper function
339/*! Return the setting a specific mode. */
340BOOL TEScreen::getMode(int m)
341{
342 return currParm.mode[m];
343}
344
345/*! Save the cursor position and the rendition attribute settings. */
346
347void TEScreen::saveCursor()
348{
349 sa_cuX = cuX;
350 sa_cuY = cuY;
351 sa_cu_re = cu_re;
352 sa_cu_fg = cu_fg;
353 sa_cu_bg = cu_bg;
354}
355
356/*! Restore the cursor position and the rendition attribute settings. */
357
358void TEScreen::restoreCursor()
359{
360 cuX = QMIN(sa_cuX,columns-1);
361 cuY = QMIN(sa_cuY,lines-1);
362 cu_re = sa_cu_re;
363 cu_fg = sa_cu_fg;
364 cu_bg = sa_cu_bg;
365 effectiveRendition();
366}
367
368/* ------------------------------------------------------------------------- */
369/* */
370/* Screen Operations */
371/* */
372/* ------------------------------------------------------------------------- */
373
374/*! Assing a new size to the screen.
375
376 The topmost left position is maintained, while lower lines
377 or right hand side columns might be removed or filled with
378 spaces to fit the new size.
379
380 The region setting is reset to the whole screen and the
381 tab positions reinitialized.
382*/
383
384void TEScreen::resizeImage(int new_lines, int new_columns)
385{
386
387 if (cuY > new_lines-1)
388 { // attempt to preserve focus and lines
389 bmargin = lines-1; //FIXME: margin lost
390 for (int i = 0; i < cuY-(new_lines-1); i++)
391 {
392 addHistLine(); scrollUp(0,1);
393 }
394 }
395
396 // make new image
397 ca* newimg = (ca*)malloc(new_lines*new_columns*sizeof(ca));
398
399 clearSelection();
400
401 // clear new image
402 for (int y = 0; y < new_lines; y++)
403 for (int x = 0; x < new_columns; x++)
404 {
405 newimg[y*new_columns+x].c = ' ';
406 newimg[y*new_columns+x].f = DEFAULT_FORE_COLOR;
407 newimg[y*new_columns+x].b = DEFAULT_BACK_COLOR;
408 newimg[y*new_columns+x].r = DEFAULT_RENDITION;
409 }
410 int cpy_lines = QMIN(new_lines, lines);
411 int cpy_columns = QMIN(new_columns,columns);
412 // copy to new image
413 for (int y = 0; y < cpy_lines; y++)
414 for (int x = 0; x < cpy_columns; x++)
415 {
416 newimg[y*new_columns+x].c = image[loc(x,y)].c;
417 newimg[y*new_columns+x].f = image[loc(x,y)].f;
418 newimg[y*new_columns+x].b = image[loc(x,y)].b;
419 newimg[y*new_columns+x].r = image[loc(x,y)].r;
420 }
421 free(image);
422 image = newimg;
423 lines = new_lines;
424 columns = new_columns;
425 cuX = QMIN(cuX,columns-1);
426 cuY = QMIN(cuY,lines-1);
427
428 // FIXME: try to keep values, evtl.
429 tmargin=0;
430 bmargin=lines-1;
431 initTabStops();
432 clearSelection();
433}
434
435/*
436 Clarifying rendition here and in TEWidget.
437
438 currently, TEWidget's color table is
439 0 1 2 .. 9 10 .. 17
440 dft_fg, dft_bg, dim 0..7, intensive 0..7
441
442 cu_fg, cu_bg contain values 0..8;
443 - 0 = default color
444 - 1..8 = ansi specified color
445
446 re_fg, re_bg contain values 0..17
447 due to the TEWidget's color table
448
449 rendition attributes are
450
451 attr widget screen
452 -------------- ------ ------
453 RE_UNDERLINE XX XX affects foreground only
454 RE_BLINK XX XX affects foreground only
455 RE_BOLD XX XX affects foreground only
456 RE_REVERSE -- XX
457 RE_TRANSPARENT XX -- affects background only
458 RE_INTENSIVE XX -- affects foreground only
459
460 Note that RE_BOLD is used in both widget
461 and screen rendition. Since xterm/vt102
462 is to poor to distinguish between bold
463 (which is a font attribute) and intensive
464 (which is a color attribute), we translate
465 this and RE_BOLD in falls eventually appart
466 into RE_BOLD and RE_INTENSIVE.
467*/
468
469void TEScreen::reverseRendition(ca* p)
470{ UINT8 f = p->f; UINT8 b = p->b;
471 p->f = b; p->b = f; //p->r &= ~RE_TRANSPARENT;
472}
473
474void TEScreen::effectiveRendition()
475// calculate rendition
476{
477 ef_re = cu_re & (RE_UNDERLINE | RE_BLINK);
478 if (cu_re & RE_REVERSE)
479 {
480 ef_fg = cu_bg;
481 ef_bg = cu_fg;
482 }
483 else
484 {
485 ef_fg = cu_fg;
486 ef_bg = cu_bg;
487 }
488 if (cu_re & RE_BOLD)
489 {
490 if (ef_fg < BASE_COLORS)
491 ef_fg += BASE_COLORS;
492 else
493 ef_fg -= BASE_COLORS;
494 }
495}
496
497/*!
498 returns the image.
499
500 Get the size of the image by \sa getLines and \sa getColumns.
501
502 NOTE that the image returned by this function must later be
503 freed.
504
505*/
506
507ca* TEScreen::getCookedImage()
508{ int x,y;
509 ca* merged = (ca*)malloc(lines*columns*sizeof(ca));
510 ca dft(' ',DEFAULT_FORE_COLOR,DEFAULT_BACK_COLOR,DEFAULT_RENDITION);
511
512 for (y = 0; (y < lines) && (y < (hist.getLines()-histCursor)); y++)
513 {
514 int len = QMIN(columns,hist.getLineLen(y+histCursor));
515 int yp = y*columns;
516 int yq = (y+histCursor)*columns;
517
518 hist.getCells(y+histCursor,0,len,merged+yp);
519 for (x = len; x < columns; x++) merged[yp+x] = dft;
520 for (x = 0; x < columns; x++)
521 { int p=x + yp; int q=x + yq;
522 if ( ( q >= sel_TL ) && ( q <= sel_BR ) )
523 reverseRendition(&merged[p]); // for selection
524 }
525 }
526 if (lines >= hist.getLines()-histCursor)
527 {
528 for (y = (hist.getLines()-histCursor); y < lines ; y++)
529 {
530 int yp = y*columns;
531 int yq = (y+histCursor)*columns;
532 int yr = (y-hist.getLines()+histCursor)*columns;
533 for (x = 0; x < columns; x++)
534 { int p = x + yp; int q = x + yq; int r = x + yr;
535 merged[p] = image[r];
536 if ( q >= sel_TL && q <= sel_BR )
537 reverseRendition(&merged[p]); // for selection
538 }
539
540 }
541 }
542 // evtl. inverse display
543 if (getMode(MODE_Screen))
544 { int i,n = lines*columns;
545 for (i = 0; i < n; i++)
546 reverseRendition(&merged[i]); // for reverse display
547 }
548 if (getMode(MODE_Cursor) && (cuY+(hist.getLines()-histCursor) < lines)) // cursor visible
549 reverseRendition(&merged[loc(cuX,cuY+(hist.getLines()-histCursor))]);
550 return merged;
551}
552
553
554/*!
555*/
556
557void TEScreen::reset()
558{
559 setMode(MODE_Wrap ); saveMode(MODE_Wrap ); // wrap at end of margin
560 resetMode(MODE_Origin); saveMode(MODE_Origin); // position refere to [1,1]
561 resetMode(MODE_Insert); saveMode(MODE_Insert); // overstroke
562 setMode(MODE_Cursor); // cursor visible
563 resetMode(MODE_Screen); // screen not inverse
564 resetMode(MODE_NewLine);
565
566 tmargin=0;
567 bmargin=lines-1;
568
569 setDefaultRendition();
570 saveCursor();
571
572 clear();
573}
574
575/*! Clear the entire screen and home the cursor.
576*/
577
578void TEScreen::clear()
579{
580 clearEntireScreen();
581 home();
582}
583
584/*! Moves the cursor left one column.
585*/
586
587void TEScreen::BackSpace()
588{
589 cuX = QMAX(0,cuX-1);
590 if (BS_CLEARS) image[loc(cuX,cuY)].c = ' ';
591}
592
593/*!
594*/
595
596void TEScreen::Tabulate()
597{
598 // note that TAB is a format effector (does not write ' ');
599 cursorRight(1); while(cuX < columns-1 && !tabstops[cuX]) cursorRight(1);
600}
601
602void TEScreen::clearTabStops()
603{
604 for (int i = 0; i < columns; i++) tabstops[i-1] = FALSE;
605}
606
607void TEScreen::changeTabStop(bool set)
608{
609 if (cuX >= columns) return;
610 tabstops[cuX] = set;
611}
612
613void TEScreen::initTabStops()
614{
615 if (tabstops) free(tabstops);
616 tabstops = (bool*)malloc(columns*sizeof(bool));
617 // Arrg! The 1st tabstop has to be one longer than the other.
618 // i.e. the kids start counting from 0 instead of 1.
619 // Other programs might behave correctly. Be aware.
620 for (int i = 0; i < columns; i++) tabstops[i] = (i%8 == 0 && i != 0);
621}
622
623/*!
624 This behaves either as IND (Screen::Index) or as NEL (Screen::NextLine)
625 depending on the NewLine Mode (LNM). This mode also
626 affects the key sequence returned for newline ([CR]LF).
627*/
628
629void TEScreen::NewLine()
630{
631 if (getMode(MODE_NewLine)) Return();
632 index();
633}
634
635/*! put `c' literally onto the screen at the current cursor position.
636
637 VT100 uses the convention to produce an automatic newline (am)
638 with the *first* character that would fall onto the next line (xenl).
639*/
640
641void TEScreen::checkSelection(int from, int to)
642{
643 if (sel_begin == -1) return;
644 int scr_TL = loc(0, hist.getLines());
645 //Clear entire selection if it overlaps region [from, to]
646 if ( (sel_BR > (from+scr_TL) )&&(sel_TL < (to+scr_TL)) )
647 {
648 clearSelection();
649 }
650}
651
652void TEScreen::ShowCharacter(unsigned short c)
653{
654 // Note that VT100 does wrapping BEFORE putting the character.
655 // This has impact on the assumption of valid cursor positions.
656 // We indicate the fact that a newline has to be triggered by
657 // putting the cursor one right to the last column of the screen.
658
659 if (cuX >= columns)
660 {
661 if (getMode(MODE_Wrap)) NextLine(); else cuX = columns-1;
662 }
663
664 if (getMode(MODE_Insert)) insertChars(1);
665
666 int i = loc(cuX,cuY);
667
668 checkSelection(i, i); // check if selection is still valid.
669
670 image[i].c = c;
671 image[i].f = ef_fg;
672 image[i].b = ef_bg;
673 image[i].r = ef_re;
674
675 cuX += 1;
676}
677
678// Region commands -------------------------------------------------------------
679
680
681/*! scroll up `n' lines within current region.
682 The `n' new lines are cleared.
683 \sa setRegion \sa scrollDown
684*/
685
686void TEScreen::scrollUp(int from, int n)
687{
688 if (n <= 0 || from + n > bmargin) return;
689 //FIXME: make sure `tmargin', `bmargin', `from', `n' is in bounds.
690 moveImage(loc(0,from),loc(0,from+n),loc(columns-1,bmargin));
691 clearImage(loc(0,bmargin-n+1),loc(columns-1,bmargin),' ');
692}
693
694/*! scroll down `n' lines within current region.
695 The `n' new lines are cleared.
696 \sa setRegion \sa scrollUp
697*/
698
699void TEScreen::scrollDown(int from, int n)
700{
701//FIXME: make sure `tmargin', `bmargin', `from', `n' is in bounds.
702 if (n <= 0) return;
703 if (from > bmargin) return;
704 if (from + n > bmargin) n = bmargin - from;
705 moveImage(loc(0,from+n),loc(0,from),loc(columns-1,bmargin-n));
706 clearImage(loc(0,from),loc(columns-1,from+n-1),' ');
707}
708
709/*! position the cursor to a specific line and column. */
710void TEScreen::setCursorYX(int y, int x)
711{
712 setCursorY(y); setCursorX(x);
713}
714
715/*! Set the cursor to x-th line. */
716
717void TEScreen::setCursorX(int x)
718{
719 if (x == 0) x = 1; // Default
720 x -= 1; // Adjust
721 cuX = QMAX(0,QMIN(columns-1, x));
722}
723
724/*! Set the cursor to y-th line. */
725
726void TEScreen::setCursorY(int y)
727{
728 if (y == 0) y = 1; // Default
729 y -= 1; // Adjust
730 cuY = QMAX(0,QMIN(lines -1, y + (getMode(MODE_Origin) ? tmargin : 0) ));
731}
732
733/*! set cursor to the `left upper' corner of the screen (1,1).
734*/
735
736void TEScreen::home()
737{
738 cuX = 0;
739 cuY = 0;
740}
741
742/*! set cursor to the begin of the current line.
743*/
744
745void TEScreen::Return()
746{
747 cuX = 0;
748}
749
750/*! returns the current cursor columns.
751*/
752
753int TEScreen::getCursorX()
754{
755 return cuX;
756}
757
758/*! returns the current cursor line.
759*/
760
761int TEScreen::getCursorY()
762{
763 return cuY;
764}
765
766// Erasing ---------------------------------------------------------------------
767
768/*! \section Erasing
769
770 This group of operations erase parts of the screen contents by filling
771 it with spaces colored due to the current rendition settings.
772
773 Althought the cursor position is involved in most of these operations,
774 it is never modified by them.
775*/
776
777/*! fill screen between (including) `loca' and `loce' with spaces.
778
779 This is an internal helper functions. The parameter types are internal
780 addresses of within the screen image and make use of the way how the
781 screen matrix is mapped to the image vector.
782*/
783
784void TEScreen::clearImage(int loca, int loce, char c)
785{ int i;
786 int scr_TL=loc(0,hist.getLines());
787 //FIXME: check positions
788
789 //Clear entire selection if it overlaps region to be moved...
790 if ( (sel_BR > (loca+scr_TL) )&&(sel_TL < (loce+scr_TL)) )
791 {
792 clearSelection();
793 }
794 for (i = loca; i <= loce; i++)
795 {
796 image[i].c = c;
797 image[i].f = ef_fg; //DEFAULT_FORE_COLOR; //FIXME: xterm and linux/ansi
798 image[i].b = ef_bg; //DEFAULT_BACK_COLOR; // many have different
799 image[i].r = ef_re; //DEFAULT_RENDITION; // ideas here.
800 }
801}
802
803/*! move image between (including) `loca' and `loce' to 'dst'.
804
805 This is an internal helper functions. The parameter types are internal
806 addresses of within the screen image and make use of the way how the
807 screen matrix is mapped to the image vector.
808*/
809
810void TEScreen::moveImage(int dst, int loca, int loce)
811{
812//FIXME: check positions
813 if (loce < loca) {
814 // kdDebug() << "WARNING!!! call to TEScreen:moveImage with loce < loca!" << endl;
815 return;
816 }
817 memmove(&image[dst],&image[loca],(loce-loca+1)*sizeof(ca));
818}
819
820/*! clear from (including) current cursor position to end of screen.
821*/
822
823void TEScreen::clearToEndOfScreen()
824{
825 clearImage(loc(cuX,cuY),loc(columns-1,lines-1),' ');
826}
827
828/*! clear from begin of screen to (including) current cursor position.
829*/
830
831void TEScreen::clearToBeginOfScreen()
832{
833 clearImage(loc(0,0),loc(cuX,cuY),' ');
834}
835
836/*! clear the entire screen.
837*/
838
839void TEScreen::clearEntireScreen()
840{
841 clearImage(loc(0,0),loc(columns-1,lines-1),' ');
842}
843
844/*! fill screen with 'E'
845 This is to aid screen alignment
846*/
847
848void TEScreen::helpAlign()
849{
850 clearImage(loc(0,0),loc(columns-1,lines-1),'E');
851}
852
853/*! clear from (including) current cursor position to end of current cursor line.
854*/
855
856void TEScreen::clearToEndOfLine()
857{
858 clearImage(loc(cuX,cuY),loc(columns-1,cuY),' ');
859}
860
861/*! clear from begin of current cursor line to (including) current cursor position.
862*/
863
864void TEScreen::clearToBeginOfLine()
865{
866 clearImage(loc(0,cuY),loc(cuX,cuY),' ');
867}
868
869/*! clears entire current cursor line
870*/
871
872void TEScreen::clearEntireLine()
873{
874 clearImage(loc(0,cuY),loc(columns-1,cuY),' ');
875}
876
877// Rendition ------------------------------------------------------------------
878
879/*!
880 set rendition mode
881*/
882
883void TEScreen::setRendition(int re)
884{
885 cu_re |= re;
886 effectiveRendition();
887}
888
889/*!
890 reset rendition mode
891*/
892
893void TEScreen::resetRendition(int re)
894{
895 cu_re &= ~re;
896 effectiveRendition();
897}
898
899/*!
900*/
901
902void TEScreen::setDefaultRendition()
903{
904 setForeColorToDefault();
905 setBackColorToDefault();
906 cu_re = DEFAULT_RENDITION;
907 effectiveRendition();
908}
909
910/*!
911*/
912
913void TEScreen::setForeColor(int fgcolor)
914{
915 cu_fg = (fgcolor&7)+((fgcolor&8) ? 4+8 : 2);
916 effectiveRendition();
917}
918
919/*!
920*/
921
922void TEScreen::setBackColor(int bgcolor)
923{
924 cu_bg = (bgcolor&7)+((bgcolor&8) ? 4+8 : 2);
925 effectiveRendition();
926}
927
928/*!
929*/
930
931void TEScreen::setBackColorToDefault()
932{
933 cu_bg = DEFAULT_BACK_COLOR;
934 effectiveRendition();
935}
936
937/*!
938*/
939
940void TEScreen::setForeColorToDefault()
941{
942 cu_fg = DEFAULT_FORE_COLOR;
943 effectiveRendition();
944}
945
946/* ------------------------------------------------------------------------- */
947/* */
948/* Marking & Selection */
949/* */
950/* ------------------------------------------------------------------------- */
951
952void TEScreen::clearSelection()
953{
954 sel_BR = -1;
955 sel_TL = -1;
956 sel_begin = -1;
957}
958
959void TEScreen::setSelBeginXY(const int x, const int y)
960{
961 sel_begin = loc(x,y+histCursor) ;
962 sel_BR = sel_begin;
963 sel_TL = sel_begin;
964}
965
966void TEScreen::setSelExtentXY(const int x, const int y)
967{
968 if (sel_begin == -1) return;
969 int l = loc(x,y + histCursor);
970
971 if (l < sel_begin)
972 {
973 sel_TL = l;
974 sel_BR = sel_begin;
975 }
976 else
977 {
978 /* FIXME, HACK to correct for x too far to the right... */
979 if (( x == columns )|| (x == 0)) l--;
980
981 sel_TL = sel_begin;
982 sel_BR = l;
983 }
984}
985
986QString TEScreen::getSelText(const BOOL preserve_line_breaks)
987{
988 if (sel_begin == -1)
989 return QString::null; // Selection got clear while selecting.
990
991 int *m; // buffer to fill.
992 int s, d; // source index, dest. index.
993 int hist_BR = loc(0, hist.getLines());
994 int hY = sel_TL / columns;
995 int hX = sel_TL % columns;
996 int eol; // end of line
997
998 s = sel_TL; // tracks copy in source.
999
1000 // allocate buffer for maximum
1001 // possible size...
1002 d = (sel_BR - sel_TL) / columns + 1;
1003 m = new int[d * (columns + 1) + 2];
1004 d = 0;
1005
1006 while (s <= sel_BR)
1007 {
1008 if (s < hist_BR)
1009 { // get lines from hist.history
1010 // buffer.
1011 eol = hist.getLineLen(hY);
1012
1013 if ((hY == (sel_BR / columns)) &&
1014 (eol >= (sel_BR % columns)))
1015 {
1016 eol = sel_BR % columns + 1;
1017 }
1018
1019 while (hX < eol)
1020 {
1021 m[d++] = hist.getCell(hY, hX++).c;
1022 s++;
1023 }
1024
1025 if (s <= sel_BR)
1026 {
1027 // The line break handling
1028 // It's different from the screen
1029 // image case!
1030 if (eol % columns == 0)
1031 {
1032 // That's either a completely filled
1033 // line or an empty line
1034 if (eol == 0)
1035 {
1036 m[d++] = '\n';
1037 }
1038 else
1039 {
1040 // We have a full line.
1041 // FIXME: How can we handle newlines
1042 // at this position?!
1043 }
1044 }
1045 else if ((eol + 1) % columns == 0)
1046 {
1047 // FIXME: We don't know if this was a
1048 // space at the last position or a
1049 // short line!!
1050 m[d++] = ' ';
1051 }
1052 else
1053 {
1054 // We have a short line here. Put a
1055 // newline or a space into the
1056 // buffer.
1057 m[d++] = preserve_line_breaks ? '\n' : ' ';
1058 }
1059 }
1060
1061 hY++;
1062 hX = 0;
1063 s = hY * columns;
1064 }
1065 else
1066 { // or from screen image.
1067 eol = (s / columns + 1) * columns - 1;
1068
1069 if (eol < sel_BR)
1070 {
1071 while ((eol > s) &&
1072 isspace(image[eol - hist_BR].c))
1073 {
1074 eol--;
1075 }
1076 }
1077 else
1078 {
1079 eol = sel_BR;
1080 }
1081
1082 while (s <= eol)
1083 {
1084 m[d++] = image[s++ - hist_BR].c;
1085 }
1086
1087 if (eol < sel_BR)
1088 {
1089 // eol processing see below ...
1090 if ((eol + 1) % columns == 0)
1091 {
1092 if (image[eol - hist_BR].c == ' ')
1093 {
1094 m[d++] = ' ';
1095 }
1096 }
1097 else
1098 {
1099 m[d++] = ((preserve_line_breaks ||
1100 ((eol % columns) == 0)) ?
1101 '\n' : ' ');
1102 }
1103 }
1104
1105 s = (eol / columns + 1) * columns;
1106 }
1107 }
1108
1109 QChar* qc = new QChar[d];
1110
1111 for (int i = 0; i < d; i++)
1112 {
1113 qc[i] = m[i];
1114 }
1115
1116 QString res(qc, d);
1117
1118 delete m;
1119 delete qc;
1120
1121 return res;
1122}
1123/* above ... end of line processing for selection -- psilva
1124cases:
1125
11261) (eol+1)%columns == 0 --> the whole line is filled.
1127 If the last char is a space, insert (preserve) space. otherwise
1128 leave the text alone, so that words that are broken by linewrap
1129 are preserved.
1130
1131FIXME:
1132 * this suppresses \n for command output that is
1133 sized to the exact column width of the screen.
1134
11352) eol%columns == 0 --> blank line.
1136 insert a \n unconditionally.
1137 Do it either you would because you are in preserve_line_break mode,
1138 or because it's an ASCII paragraph delimiter, so even when
1139 not preserving line_breaks, you want to preserve paragraph breaks.
1140
1141 3) else --> partially filled line
1142 insert a \n in preserve line break mode, else a space
1143 The space prevents concatenation of the last word of one
1144 line with the first of the next.
1145
1146*/
1147
1148void TEScreen::addHistLine()
1149{
1150 assert(hasScroll() || histCursor == 0);
1151
1152 // add to hist buffer
1153 // we have to take care about scrolling, too...
1154
1155 if (hasScroll())
1156 { ca dft;
1157
1158 int end = columns-1;
1159 while (end >= 0 && image[end] == dft)
1160 end -= 1;
1161
1162 hist.addCells(image,end+1);
1163 hist.addLine();
1164
1165 // adjust history cursor
1166 histCursor += (hist.getLines()-1 == histCursor);
1167 }
1168
1169 if (!hasScroll()) histCursor = 0; //FIXME: a poor workaround
1170}
1171
1172void TEScreen::setHistCursor(int cursor)
1173{
1174 histCursor = cursor; //FIXME:rangecheck
1175}
1176
1177int TEScreen::getHistCursor()
1178{
1179 return histCursor;
1180}
1181
1182int TEScreen::getHistLines()
1183{
1184 return hist.getLines();
1185}
1186
1187void TEScreen::setScroll(bool on)
1188{
1189 histCursor = 0;
1190 clearSelection();
1191 hist.setScroll(on);
1192}
1193
1194bool TEScreen::hasScroll()
1195{
1196 return hist.hasScroll();
1197}
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 @@
1/* -------------------------------------------------------------------------- */
2/* */
3/* [te_screen.h] Screen Data Type */
4/* */
5/* -------------------------------------------------------------------------- */
6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */
9/* This file is part of Konsole - an X terminal for KDE */
10/* */
11/* -------------------------------------------------------------------------- */
12 /* */
13/* Ported Konsole to Qt/Embedded */
14 /* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16 /* */
17/* -------------------------------------------------------------------------- */
18
19#ifndef TESCREEN_H
20#define TESCREEN_H
21
22/*! \file
23*/
24
25#include "TECommon.h"
26#include "TEHistory.h"
27
28#define MODE_Origin 0
29#define MODE_Wrap 1
30#define MODE_Insert 2
31#define MODE_Screen 3
32#define MODE_Cursor 4
33#define MODE_NewLine 5
34#define MODES_SCREEN 6
35
36/*!
37*/
38struct ScreenParm
39{
40 int mode[MODES_SCREEN];
41};
42
43
44class TEScreen
45{
46public:
47 TEScreen(int lines, int columns);
48 ~TEScreen();
49
50public: // these are all `Screen' operations
51 //
52 // VT100/2 Operations ------------------
53 //
54 // Cursor Movement
55 //
56 void cursorUp (int n);
57 void cursorDown (int n);
58 void cursorLeft (int n);
59 void cursorRight (int n);
60 void setCursorY (int y);
61 void setCursorX (int x);
62 void setCursorYX (int y, int x);
63 void setMargins (int t, int b);
64 //
65 // Cursor Movement with Scrolling
66 //
67 void NewLine ();
68 void NextLine ();
69 void index ();
70 void reverseIndex();
71 //
72 void Return ();
73 void BackSpace ();
74 void Tabulate ();
75 //
76 // Editing
77 //
78 void eraseChars (int n);
79 void deleteChars (int n);
80 void insertChars (int n);
81 void deleteLines (int n);
82 void insertLines (int n);
83 //
84 // -------------------------------------
85 //
86 void clearTabStops();
87 void changeTabStop(bool set);
88 //
89 void resetMode (int n);
90 void setMode (int n);
91 void saveMode (int n);
92 void restoreMode (int n);
93 //
94 void saveCursor ();
95 void restoreCursor();
96 //
97 // -------------------------------------
98 //
99 void clearEntireScreen();
100 void clearToEndOfScreen();
101 void clearToBeginOfScreen();
102 //
103 void clearEntireLine();
104 void clearToEndOfLine();
105 void clearToBeginOfLine();
106 //
107 void helpAlign ();
108 //
109 // -------------------------------------
110 //
111 void setRendition (int rendition);
112 void resetRendition(int rendition);
113 void setForeColor (int fgcolor);
114 void setBackColor (int bgcolor);
115 //
116 void setDefaultRendition();
117 void setForeColorToDefault();
118 void setBackColorToDefault();
119 //
120 // -------------------------------------
121 //
122 BOOL getMode (int n);
123 //
124 // only for report cursor position
125 //
126 int getCursorX();
127 int getCursorY();
128 //
129 // -------------------------------------
130 //
131 void clear();
132 void home();
133 void reset();
134 //
135 void ShowCharacter(unsigned short c);
136 //
137 void resizeImage(int new_lines, int new_columns);
138 //
139 ca* getCookedImage();
140
141 /*! return the number of lines. */
142 int getLines() { return lines; }
143 /*! return the number of columns. */
144 int getColumns() { return columns; }
145
146 /*! set the position of the history cursor. */
147 void setHistCursor(int cursor);
148 /*! return the position of the history cursor. */
149 int getHistCursor();
150
151 int getHistLines ();
152 void setScroll(bool on);
153 bool hasScroll();
154
155 //
156 // Selection
157 //
158 void setSelBeginXY(const int x, const int y);
159 void setSelExtentXY(const int x, const int y);
160 void clearSelection();
161 QString getSelText(const BOOL preserve_line_breaks);
162
163 void checkSelection(int from, int to);
164
165private: // helper
166
167 void clearImage(int loca, int loce, char c);
168 void moveImage(int dst, int loca, int loce);
169
170 void scrollUp(int from, int i);
171 void scrollDown(int from, int i);
172
173 void addHistLine();
174
175 void initTabStops();
176
177 void effectiveRendition();
178 void reverseRendition(ca* p);
179
180private:
181
182 /*
183 The state of the screen is more complex as one would
184 expect first. The screem does really do part of the
185 emulation providing state informations in form of modes,
186 margins, tabulators, cursor etc.
187
188 Even more unexpected are variables to save and restore
189 parts of the state.
190 */
191
192 // screen image ----------------
193
194 int lines;
195 int columns;
196 ca *image; // [lines][columns]
197
198 // history buffer ---------------
199
200 int histCursor; // display position relative to start of the history buffer
201 HistoryScroll hist;
202
203 // cursor location
204
205 int cuX;
206 int cuY;
207
208 // cursor color and rendition info
209
210 UINT8 cu_fg; // foreground
211 UINT8 cu_bg; // background
212 UINT8 cu_re; // rendition
213
214 // margins ----------------
215
216 int tmargin; // top margin
217 int bmargin; // bottom margin
218
219 // states ----------------
220
221 ScreenParm currParm;
222
223 // ----------------------------
224
225 bool* tabstops;
226
227 // selection -------------------
228
229 int sel_begin; // The first location selected.
230 int sel_TL; // TopLeft Location.
231 int sel_BR; // Bottom Right Location.
232
233 // effective colors and rendition ------------
234
235 UINT8 ef_fg; // These are derived from
236 UINT8 ef_bg; // the cu_* variables above
237 UINT8 ef_re; // to speed up operation
238
239 //
240 // save cursor, rendition & states ------------
241 //
242
243 // cursor location
244
245 int sa_cuX;
246 int sa_cuY;
247
248 // rendition info
249
250 UINT8 sa_cu_re;
251 UINT8 sa_cu_fg;
252 UINT8 sa_cu_bg;
253
254 // modes
255
256 ScreenParm saveParm;
257};
258
259#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 @@
1/* ------------------------------------------------------------------------ */
2/* */
3/* [TEWidget.C] Terminal Emulation Widget */
4/* */
5/* ------------------------------------------------------------------------ */
6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */
9/* This file is part of Konsole - an X terminal for KDE */
10/* */
11/* ------------------------------------------------------------------------ */
12 /* */
13/* Ported Konsole to Qt/Embedded */
14 /* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16 /* */
17/* -------------------------------------------------------------------------- */
18
19/*! \class TEWidget
20
21 \brief Visible screen contents
22
23 This class is responsible to map the `image' of a terminal emulation to the
24 display. All the dependency of the emulation to a specific GUI or toolkit is
25 localized here. Further, this widget has no knowledge about being part of an
26 emulation, it simply work within the terminal emulation framework by exposing
27 size and key events and by being ordered to show a new image.
28
29 <ul>
30 <li> The internal image has the size of the widget (evtl. rounded up)
31 <li> The external image used in setImage can have any size.
32 <li> (internally) the external image is simply copied to the internal
33 when a setImage happens. During a resizeEvent no painting is done
34 a paintEvent is expected to follow anyway.
35 </ul>
36
37 \sa TEScreen \sa Emulation
38*/
39
40/* FIXME:
41 - 'image' may also be used uninitialized (it isn't in fact) in resizeEvent
42 - 'font_a' not used in mouse events
43 - add destructor
44*/
45
46/* TODO
47 - evtl. be sensitive to `paletteChange' while using default colors.
48 - set different 'rounding' styles? I.e. have a mode to show clipped chars?
49*/
50
51// #include "config.h"
52#include "TEWidget.h"
53#include "session.h"
54
55#include <qcursor.h>
56#include <qregexp.h>
57#include <qpainter.h>
58#include <qclipboard.h>
59#include <qstyle.h>
60#include <qfile.h>
61#include <qdragobject.h>
62
63#include <stdio.h>
64#include <stdlib.h>
65#include <unistd.h>
66#include <ctype.h>
67#include <sys/stat.h>
68#include <sys/types.h>
69#include <signal.h>
70
71#include <assert.h>
72
73// #include "TEWidget.moc"
74//#include <kapp.h>
75//#include <kcursor.h>
76//#include <kurl.h>
77//#include <kdebug.h>
78//#include <klocale.h>
79
80#define HERE printf("%s(%d): %s\n",__FILE__,__LINE__,__FUNCTION__)
81#define HCNT(Name) // { static int cnt = 1; printf("%s(%d): %s %d\n",__FILE__,__LINE__,Name,cnt++); }
82
83#define loc(X,Y) ((Y)*columns+(X))
84
85//FIXME: the rim should normally be 1, 0 only when running in full screen mode.
86#define rimX 0 // left/right rim width
87#define rimY 0 // top/bottom rim high
88
89#define SCRWIDTH 16 // width of the scrollbar
90
91#define yMouseScroll 1
92// scroll increment used when dragging selection at top/bottom of window.
93
94/* ------------------------------------------------------------------------- */
95/* */
96/* Colors */
97/* */
98/* ------------------------------------------------------------------------- */
99
100//FIXME: the default color table is in session.C now.
101// We need a way to get rid of this one, here.
102static const ColorEntry base_color_table[TABLE_COLORS] =
103// The following are almost IBM standard color codes, with some slight
104// gamma correction for the dim colors to compensate for bright X screens.
105// It contains the 8 ansiterm/xterm colors in 2 intensities.
106{
107 // Fixme: could add faint colors here, also.
108 // normal
109 ColorEntry(QColor(0x00,0x00,0x00), 0, 0 ), ColorEntry( QColor(0xB2,0xB2,0xB2), 1, 0 ), // Dfore, Dback
110 ColorEntry(QColor(0x00,0x00,0x00), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0x18), 0, 0 ), // Black, Red
111 ColorEntry(QColor(0x18,0xB2,0x18), 0, 0 ), ColorEntry( QColor(0xB2,0x68,0x18), 0, 0 ), // Green, Yellow
112 ColorEntry(QColor(0x18,0x18,0xB2), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0xB2), 0, 0 ), // Blue, Magenta
113 ColorEntry(QColor(0x18,0xB2,0xB2), 0, 0 ), ColorEntry( QColor(0xB2,0xB2,0xB2), 0, 0 ), // Cyan, White
114 // intensiv
115 ColorEntry(QColor(0x00,0x00,0x00), 0, 1 ), ColorEntry( QColor(0xFF,0xFF,0xFF), 1, 0 ),
116 ColorEntry(QColor(0x68,0x68,0x68), 0, 0 ), ColorEntry( QColor(0xFF,0x54,0x54), 0, 0 ),
117 ColorEntry(QColor(0x54,0xFF,0x54), 0, 0 ), ColorEntry( QColor(0xFF,0xFF,0x54), 0, 0 ),
118 ColorEntry(QColor(0x54,0x54,0xFF), 0, 0 ), ColorEntry( QColor(0xFF,0x54,0xFF), 0, 0 ),
119 ColorEntry(QColor(0x54,0xFF,0xFF), 0, 0 ), ColorEntry( QColor(0xFF,0xFF,0xFF), 0, 0 )
120};
121
122/* Note that we use ANSI color order (bgr), while IBMPC color order is (rgb)
123
124 Code 0 1 2 3 4 5 6 7
125 ----------- ------- ------- ------- ------- ------- ------- ------- -------
126 ANSI (bgr) Black Red Green Yellow Blue Magenta Cyan White
127 IBMPC (rgb) Black Blue Green Cyan Red Magenta Yellow White
128*/
129
130QColor TEWidget::getDefaultBackColor()
131{
132 return color_table[DEFAULT_BACK_COLOR].color;
133}
134
135const ColorEntry* TEWidget::getColorTable() const
136{
137 return color_table;
138}
139
140const QPixmap *TEWidget::backgroundPixmap()
141{
142 static QPixmap *bg = new QPixmap("~/qpim/main/pics/faded_bg.xpm");
143 const QPixmap *pm = bg;
144 return pm;
145}
146
147void TEWidget::setColorTable(const ColorEntry table[])
148{
149 for (int i = 0; i < TABLE_COLORS; i++) color_table[i] = table[i];
150
151 const QPixmap* pm = backgroundPixmap();
152 if (!pm) setBackgroundColor(color_table[DEFAULT_BACK_COLOR].color);
153 update();
154}
155
156//FIXME: add backgroundPixmapChanged.
157
158/* ------------------------------------------------------------------------- */
159/* */
160/* Font */
161/* */
162/* ------------------------------------------------------------------------- */
163
164/*
165 The VT100 has 32 special graphical characters. The usual vt100 extended
166 xterm fonts have these at 0x00..0x1f.
167
168 QT's iso mapping leaves 0x00..0x7f without any changes. But the graphicals
169 come in here as proper unicode characters.
170
171 We treat non-iso10646 fonts as VT100 extended and do the requiered mapping
172 from unicode to 0x00..0x1f. The remaining translation is then left to the
173 QCodec.
174*/
175
176// assert for i in [0..31] : vt100extended(vt100_graphics[i]) == i.
177
178unsigned short vt100_graphics[32] =
179{ // 0/8 1/9 2/10 3/11 4/12 5/13 6/14 7/15
180 0x0020, 0x25C6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0,
181 0x00b1, 0x2424, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c,
182 0xF800, 0xF801, 0x2500, 0xF803, 0xF804, 0x251c, 0x2524, 0x2534,
183 0x252c, 0x2502, 0x2264, 0x2265, 0x03C0, 0x2260, 0x00A3, 0x00b7
184};
185
186static QChar vt100extended(QChar c)
187{
188 switch (c.unicode())
189 {
190 case 0x25c6 : return 1;
191 case 0x2592 : return 2;
192 case 0x2409 : return 3;
193 case 0x240c : return 4;
194 case 0x240d : return 5;
195 case 0x240a : return 6;
196 case 0x00b0 : return 7;
197 case 0x00b1 : return 8;
198 case 0x2424 : return 9;
199 case 0x240b : return 10;
200 case 0x2518 : return 11;
201 case 0x2510 : return 12;
202 case 0x250c : return 13;
203 case 0x2514 : return 14;
204 case 0x253c : return 15;
205 case 0xf800 : return 16;
206 case 0xf801 : return 17;
207 case 0x2500 : return 18;
208 case 0xf803 : return 19;
209 case 0xf804 : return 20;
210 case 0x251c : return 21;
211 case 0x2524 : return 22;
212 case 0x2534 : return 23;
213 case 0x252c : return 24;
214 case 0x2502 : return 25;
215 case 0x2264 : return 26;
216 case 0x2265 : return 27;
217 case 0x03c0 : return 28;
218 case 0x2260 : return 29;
219 case 0x00a3 : return 30;
220 case 0x00b7 : return 31;
221 }
222 return c;
223}
224
225static QChar identicalMap(QChar c)
226{
227 return c;
228}
229
230void TEWidget::fontChange(const QFont &)
231{
232 QFontMetrics fm(font());
233 font_h = fm.height();
234 font_w = fm.maxWidth();
235 font_a = fm.ascent();
236//printf("font_h: %d\n",font_h);
237//printf("font_w: %d\n",font_w);
238//printf("font_a: %d\n",font_a);
239//printf("charset: %s\n",QFont::encodingName(font().charSet()).ascii());
240//printf("rawname: %s\n",font().rawName().ascii());
241 fontMap =
242#if QT_VERSION < 300
243 strcmp(QFont::encodingName(font().charSet()).ascii(),"iso10646")
244 ? vt100extended
245 :
246#endif
247 identicalMap;
248 propagateSize();
249 update();
250}
251
252void TEWidget::setVTFont(const QFont& f)
253{
254 QFrame::setFont(f);
255}
256
257QFont TEWidget::getVTFont()
258{
259 return font();
260}
261
262void TEWidget::setFont(const QFont &)
263{
264 // ignore font change request if not coming from konsole itself
265}
266
267/* ------------------------------------------------------------------------- */
268/* */
269/* Constructor / Destructor */
270/* */
271/* ------------------------------------------------------------------------- */
272
273TEWidget::TEWidget(QWidget *parent, const char *name) : QFrame(parent,name)
274{
275#ifndef QT_NO_CLIPBOARD
276 cb = QApplication::clipboard();
277 QObject::connect( (QObject*)cb, SIGNAL(dataChanged()),
278 this, SLOT(onClearSelection()) );
279#endif
280
281 scrollbar = new QScrollBar(this);
282 scrollbar->setCursor( arrowCursor );
283 connect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int)));
284 scrollLoc = SCRNONE;
285
286 blinkT = new QTimer(this);
287 connect(blinkT, SIGNAL(timeout()), this, SLOT(blinkEvent()));
288 // blinking = FALSE;
289 blinking = TRUE;
290
291 resizing = FALSE;
292 actSel = 0;
293 image = 0;
294 lines = 1;
295 columns = 1;
296 font_w = 1;
297 font_h = 1;
298 font_a = 1;
299 word_selection_mode = FALSE;
300
301 setMouseMarks(TRUE);
302 setVTFont( QFont("fixed") );
303 setColorTable(base_color_table); // init color table
304
305 qApp->installEventFilter( this ); //FIXME: see below
306// KCursor::setAutoHideCursor( this, true );
307
308 // Init DnD ////////////////////////////////////////////////////////////////
309 currentSession = NULL;
310// setAcceptDrops(true); // attempt
311// m_drop = new QPopupMenu(this);
312// m_drop->insertItem( QString("Paste"), 0);
313// m_drop->insertItem( QString("cd"), 1);
314// connect(m_drop, SIGNAL(activated(int)), SLOT(drop_menu_activated(int)));
315
316 // we need focus so that the auto-hide cursor feature works
317 setFocus();
318 setFocusPolicy( WheelFocus );
319}
320
321//FIXME: make proper destructor
322// Here's a start (David)
323TEWidget::~TEWidget()
324{
325 qApp->removeEventFilter( this );
326 if (image) free(image);
327}
328
329/* ------------------------------------------------------------------------- */
330/* */
331/* Display Operations */
332/* */
333/* ------------------------------------------------------------------------- */
334
335/*!
336 attributed string draw primitive
337*/
338
339void TEWidget::drawAttrStr(QPainter &paint, QRect rect,
340 QString& str, ca attr, BOOL pm, BOOL clear)
341{
342 if (pm && color_table[attr.b].transparent)
343 {
344 paint.setBackgroundMode( TransparentMode );
345 if (clear) erase(rect);
346 }
347 else
348 {
349 if (blinking)
350 paint.fillRect(rect, color_table[attr.b].color);
351 else
352 {
353 paint.setBackgroundMode( OpaqueMode );
354 paint.setBackgroundColor( color_table[attr.b].color );
355 }
356 }
357
358 if (color_table[attr.f].bold)
359 paint.setPen(QColor( 0x8F, 0x00, 0x00 ));
360 else
361 paint.setPen(color_table[attr.f].color);
362
363 paint.drawText(rect.x(),rect.y()+font_a, str);
364
365 if (attr.r & RE_UNDERLINE)
366 paint.drawLine(rect.left(), rect.y()+font_a+1, rect.right(),rect.y()+font_a+1 );
367}
368
369/*!
370 The image can only be set completely.
371
372 The size of the new image may or may not match the size of the widget.
373*/
374
375void TEWidget::setImage(const ca* const newimg, int lines, int columns)
376{ int y,x,len;
377 const QPixmap* pm = backgroundPixmap();
378 QPainter paint;
379 setUpdatesEnabled(FALSE);
380 paint.begin( this );
381HCNT("setImage");
382
383 QPoint tL = contentsRect().topLeft();
384 int tLx = tL.x();
385 int tLy = tL.y();
386 hasBlinker = FALSE;
387
388 int cf = -1; // undefined
389 int cb = -1; // undefined
390 int cr = -1; // undefined
391
392 int lins = QMIN(this->lines, QMAX(0,lines ));
393 int cols = QMIN(this->columns,QMAX(0,columns));
394 QChar *disstrU = new QChar[cols];
395
396//{ static int cnt = 0; printf("setImage %d\n",cnt++); }
397 for (y = 0; y < lins; y++)
398 {
399 const ca* lcl = &image[y*this->columns];
400 const ca* const ext = &newimg[y*columns];
401 if (!resizing) // not while resizing, we're expecting a paintEvent
402 for (x = 0; x < cols; x++)
403 {
404 hasBlinker |= (ext[x].r & RE_BLINK);
405 if (ext[x] != lcl[x])
406 {
407 cr = ext[x].r;
408 cb = ext[x].b;
409 if (ext[x].f != cf) cf = ext[x].f;
410 int lln = cols - x;
411 disstrU[0] = fontMap(ext[x+0].c);
412 for (len = 1; len < lln; len++)
413 {
414 if (ext[x+len].f != cf || ext[x+len].b != cb || ext[x+len].r != cr ||
415 ext[x+len] == lcl[x+len] )
416 break;
417 disstrU[len] = fontMap(ext[x+len].c);
418 }
419 QString unistr(disstrU,len);
420 drawAttrStr(paint,
421 QRect(blX+tLx+font_w*x,bY+tLy+font_h*y,font_w*len,font_h),
422 unistr, ext[x], pm != NULL, true);
423 x += len - 1;
424 }
425 }
426 // finally, make `image' become `newimg'.
427 memcpy((void*)lcl,(const void*)ext,cols*sizeof(ca));
428 }
429 drawFrame( &paint );
430 paint.end();
431 setUpdatesEnabled(TRUE);
432 if ( hasBlinker && !blinkT->isActive()) blinkT->start(1000); // 1000 ms
433 if (!hasBlinker && blinkT->isActive()) { blinkT->stop(); blinking = FALSE; }
434 delete [] disstrU;
435}
436
437// paint Event ////////////////////////////////////////////////////
438
439/*!
440 The difference of this routine vs. the `setImage' is,
441 that the drawing does not include a difference analysis
442 between the old and the new image. Instead, the internal
443 image is used and the painting bound by the PaintEvent box.
444*/
445
446void TEWidget::paintEvent( QPaintEvent* pe )
447{
448
449//{ static int cnt = 0; printf("paint %d\n",cnt++); }
450 const QPixmap* pm = backgroundPixmap();
451 QPainter paint;
452 setUpdatesEnabled(FALSE);
453 paint.begin( this );
454 paint.setBackgroundMode( TransparentMode );
455HCNT("paintEvent");
456
457 // Note that the actual widget size can be slightly larger
458 // that the image (the size is truncated towards the smaller
459 // number of characters in `resizeEvent'. The paint rectangle
460 // can thus be larger than the image, but less then the size
461 // of one character.
462
463 QRect rect = pe->rect().intersect(contentsRect());
464
465 QPoint tL = contentsRect().topLeft();
466 int tLx = tL.x();
467 int tLy = tL.y();
468
469 int lux = QMIN(columns-1, QMAX(0,(rect.left() - tLx - blX ) / font_w));
470 int luy = QMIN(lines-1, QMAX(0,(rect.top() - tLy - bY ) / font_h));
471 int rlx = QMIN(columns-1, QMAX(0,(rect.right() - tLx - blX ) / font_w));
472 int rly = QMIN(lines-1, QMAX(0,(rect.bottom() - tLy - bY ) / font_h));
473
474 /*
475 printf("paintEvent: %d..%d, %d..%d (%d..%d, %d..%d)\n",lux,rlx,luy,rly,
476 rect.left(), rect.right(), rect.top(), rect.bottom());
477 */
478
479 // if (pm != NULL && color_table[image->b].transparent)
480 // erase(rect);
481 // BL: I have no idea why we need this, and it breaks the refresh.
482
483 QChar *disstrU = new QChar[columns];
484 for (int y = luy; y <= rly; y++)
485 for (int x = lux; x <= rlx; x++)
486 {
487 int len = 1;
488 disstrU[0] = fontMap(image[loc(x,y)].c);
489 int cf = image[loc(x,y)].f;
490 int cb = image[loc(x,y)].b;
491 int cr = image[loc(x,y)].r;
492 while (x+len <= rlx &&
493 image[loc(x+len,y)].f == cf &&
494 image[loc(x+len,y)].b == cb &&
495 image[loc(x+len,y)].r == cr )
496 {
497 disstrU[len] = fontMap(image[loc(x+len,y)].c);
498 len += 1;
499 }
500 QString unistr(disstrU,len);
501 drawAttrStr(paint,
502 QRect(blX+tLx+font_w*x,bY+tLy+font_h*y,font_w*len,font_h),
503 unistr, image[loc(x,y)], pm != NULL, false);
504 x += len - 1;
505 }
506 delete [] disstrU;
507 drawFrame( &paint );
508 paint.end();
509 setUpdatesEnabled(TRUE);
510}
511
512void TEWidget::blinkEvent()
513{
514 blinking = !blinking;
515 repaint(FALSE);
516}
517
518/* ------------------------------------------------------------------------- */
519/* */
520/* Resizing */
521/* */
522/* ------------------------------------------------------------------------- */
523
524void TEWidget::resizeEvent(QResizeEvent* ev)
525{
526 //printf("resize: %d,%d\n",ev->size().width(),ev->size().height());
527 //printf("approx: %d,%d\n",ev->size().width()/font_w,ev->size().height()/font_h);
528 //printf("leaves: %d,%d\n",ev->size().width()%font_w,ev->size().height()%font_h);
529 //printf("curren: %d,%d\n",width(),height());
530HCNT("resizeEvent");
531
532 // see comment in `paintEvent' concerning the rounding.
533 //FIXME: could make a routine here; check width(),height()
534 assert(ev->size().width() == width());
535 assert(ev->size().height() == height());
536
537 propagateSize();
538}
539
540void TEWidget::propagateSize()
541{
542 ca* oldimg = image;
543 int oldlin = lines;
544 int oldcol = columns;
545 makeImage();
546 // we copy the old image to reduce flicker
547 int lins = QMIN(oldlin,lines);
548 int cols = QMIN(oldcol,columns);
549 if (oldimg)
550 {
551 for (int lin = 0; lin < lins; lin++)
552 memcpy((void*)&image[columns*lin],
553 (void*)&oldimg[oldcol*lin],cols*sizeof(ca));
554 free(oldimg); //FIXME: try new,delete
555 }
556 else
557 clearImage();
558
559 //NOTE: control flows from the back through the chest right into the eye.
560 // `emu' will call back via `setImage'.
561
562 resizing = TRUE;
563 emit changedImageSizeSignal(lines, columns); // expose resizeEvent
564 resizing = FALSE;
565}
566
567/* ------------------------------------------------------------------------- */
568/* */
569/* Scrollbar */
570/* */
571/* ------------------------------------------------------------------------- */
572
573void TEWidget::scrollChanged(int)
574{
575 emit changedHistoryCursor(scrollbar->value()); //expose
576}
577
578void TEWidget::setScroll(int cursor, int slines)
579{
580 disconnect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int)));
581 scrollbar->setRange(0,slines);
582 scrollbar->setSteps(1,lines);
583 scrollbar->setValue(cursor);
584 connect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int)));
585}
586
587void TEWidget::setScrollbarLocation(int loc)
588{
589 if (scrollLoc == loc) return; // quickly
590 scrollLoc = loc;
591 propagateSize();
592 update();
593}
594
595/* ------------------------------------------------------------------------- */
596/* */
597/* Mouse */
598/* */
599/* ------------------------------------------------------------------------- */
600
601/*!
602 Three different operations can be performed using the mouse, and the
603 routines in this section serve all of them:
604
605 1) The press/release events are exposed to the application
606 2) Marking (press and move left button) and Pasting (press middle button)
607 3) The right mouse button is used from the configuration menu
608
609 NOTE: During the marking process we attempt to keep the cursor within
610 the bounds of the text as being displayed by setting the mouse position
611 whenever the mouse has left the text area.
612
613 Two reasons to do so:
614 1) QT does not allow the `grabMouse' to confine-to the TEWidget.
615 Thus a `XGrapPointer' would have to be used instead.
616 2) Even if so, this would not help too much, since the text area
617 of the TEWidget is normally not identical with it's bounds.
618
619 The disadvantage of the current handling is, that the mouse can visibly
620 leave the bounds of the widget and is then moved back. Because of the
621 current construction, and the reasons mentioned above, we cannot do better
622 without changing the overall construction.
623*/
624
625/*!
626*/
627
628void TEWidget::mousePressEvent(QMouseEvent* ev)
629{
630//printf("press [%d,%d] %d\n",ev->x()/font_w,ev->y()/font_h,ev->button());
631 if ( !contentsRect().contains(ev->pos()) ) return;
632 QPoint tL = contentsRect().topLeft();
633 int tLx = tL.x();
634 int tLy = tL.y();
635
636 word_selection_mode = FALSE;
637
638//printf("press top left [%d,%d] by=%d\n",tLx,tLy, bY);
639 if ( ev->button() == LeftButton)
640 {
641 QPoint pos = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h);
642
643 if ( ev->state() & ControlButton ) preserve_line_breaks = FALSE ;
644
645 if (mouse_marks || (ev->state() & ShiftButton))
646 {
647 emit clearSelectionSignal();
648 iPntSel = pntSel = pos;
649 actSel = 1; // left mouse button pressed but nothing selected yet.
650 grabMouse( /*crossCursor*/ ); // handle with care!
651 }
652 else
653 {
654 emit mouseSignal( 0, pos.x() + 1, pos.y() + 1 ); // left button
655 }
656 }
657 if ( ev->button() == MidButton )
658 {
659 emitSelection();
660 }
661 if ( ev->button() == RightButton ) // Configure
662 {
663 emit configureRequest( this, ev->state()&(ShiftButton|ControlButton), ev->x(), ev->y() );
664 }
665}
666
667void TEWidget::mouseMoveEvent(QMouseEvent* ev)
668{
669 // for auto-hiding the cursor, we need mouseTracking
670 if (ev->state() == NoButton ) return;
671
672 if (actSel == 0) return;
673
674 // don't extend selection while pasting
675 if (ev->state() & MidButton) return;
676
677 //if ( !contentsRect().contains(ev->pos()) ) return;
678 QPoint tL = contentsRect().topLeft();
679 int tLx = tL.x();
680 int tLy = tL.y();
681 int scroll = scrollbar->value();
682
683 // we're in the process of moving the mouse with the left button pressed
684 // the mouse cursor will kept catched within the bounds of the text in
685 // this widget.
686
687 // Adjust position within text area bounds. See FIXME above.
688 QPoint pos = ev->pos();
689 if ( pos.x() < tLx+blX ) pos.setX( tLx+blX );
690 if ( pos.x() > tLx+blX+columns*font_w-1 ) pos.setX( tLx+blX+columns*font_w );
691 if ( pos.y() < tLy+bY ) pos.setY( tLy+bY );
692 if ( pos.y() > tLy+bY+lines*font_h-1 ) pos.setY( tLy+bY+lines*font_h-1 );
693 // check if we produce a mouse move event by this
694 if ( pos != ev->pos() ) cursor().setPos(mapToGlobal(pos));
695
696 if ( pos.y() == tLy+bY+lines*font_h-1 )
697 {
698 scrollbar->setValue(scrollbar->value()+yMouseScroll); // scrollforward
699 }
700 if ( pos.y() == tLy+bY )
701 {
702 scrollbar->setValue(scrollbar->value()-yMouseScroll); // scrollback
703 }
704
705 QPoint here = QPoint((pos.x()-tLx-blX)/font_w,(pos.y()-tLy-bY)/font_h);
706 QPoint ohere;
707 bool swapping = FALSE;
708
709 if ( word_selection_mode )
710 {
711 // Extend to word boundaries
712 int i;
713 int selClass;
714
715 bool left_not_right = ( here.y() < iPntSel.y() ||
716 here.y() == iPntSel.y() && here.x() < iPntSel.x() );
717 bool old_left_not_right = ( pntSel.y() < iPntSel.y() ||
718 pntSel.y() == iPntSel.y() && pntSel.x() < iPntSel.x() );
719 swapping = left_not_right != old_left_not_right;
720
721 // Find left (left_not_right ? from here : from start)
722 QPoint left = left_not_right ? here : iPntSel;
723 i = loc(left.x(),left.y());
724 selClass = charClass(image[i].c);
725 while ( left.x() > 0 && charClass(image[i-1].c) == selClass )
726 { i--; left.rx()--; }
727
728 // Find left (left_not_right ? from start : from here)
729 QPoint right = left_not_right ? iPntSel : here;
730 i = loc(right.x(),right.y());
731 selClass = charClass(image[i].c);
732 while ( right.x() < columns-1 && charClass(image[i+1].c) == selClass )
733 { i++; right.rx()++; }
734
735 // Pick which is start (ohere) and which is extension (here)
736 if ( left_not_right )
737 {
738 here = left; ohere = right;
739 }
740 else
741 {
742 here = right; ohere = left;
743 }
744 }
745
746 if (here == pntSel && scroll == scrollbar->value()) return; // not moved
747
748 if ( word_selection_mode ) {
749 if ( actSel < 2 || swapping ) {
750 emit beginSelectionSignal( ohere.x(), ohere.y() );
751 }
752 } else if ( actSel < 2 ) {
753 emit beginSelectionSignal( pntSel.x(), pntSel.y() );
754 }
755
756 actSel = 2; // within selection
757 pntSel = here;
758 emit extendSelectionSignal( here.x(), here.y() );
759}
760
761void TEWidget::mouseReleaseEvent(QMouseEvent* ev)
762{
763//printf("release [%d,%d] %d\n",ev->x()/font_w,ev->y()/font_h,ev->button());
764 if ( ev->button() == LeftButton)
765 {
766 if ( actSel > 1 ) emit endSelectionSignal(preserve_line_breaks);
767 preserve_line_breaks = TRUE;
768 actSel = 0;
769
770 //FIXME: emits a release event even if the mouse is
771 // outside the range. The procedure used in `mouseMoveEvent'
772 // applies here, too.
773
774 QPoint tL = contentsRect().topLeft();
775 int tLx = tL.x();
776 int tLy = tL.y();
777
778 if (!mouse_marks && !(ev->state() & ShiftButton))
779 emit mouseSignal( 3, // release
780 (ev->x()-tLx-blX)/font_w + 1,
781 (ev->y()-tLy-bY)/font_h + 1 );
782 releaseMouse();
783 }
784}
785
786void TEWidget::mouseDoubleClickEvent(QMouseEvent* ev)
787{
788 if ( ev->button() != LeftButton) return;
789
790 QPoint tL = contentsRect().topLeft();
791 int tLx = tL.x();
792 int tLy = tL.y();
793 QPoint pos = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h);
794
795 // pass on double click as two clicks.
796 if (!mouse_marks && !(ev->state() & ShiftButton))
797 {
798 emit mouseSignal( 0, pos.x()+1, pos.y()+1 ); // left button
799 emit mouseSignal( 3, pos.x()+1, pos.y()+1 ); // release
800 emit mouseSignal( 0, pos.x()+1, pos.y()+1 ); // left button
801 return;
802 }
803
804
805 emit clearSelectionSignal();
806 QPoint bgnSel = pos;
807 QPoint endSel = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h);
808 int i = loc(bgnSel.x(),bgnSel.y());
809 iPntSel = bgnSel;
810
811 word_selection_mode = TRUE;
812
813 // find word boundaries...
814 int selClass = charClass(image[i].c);
815 {
816 // set the start...
817 int x = bgnSel.x();
818 while ( x > 0 && charClass(image[i-1].c) == selClass )
819 { i--; x--; }
820 bgnSel.setX(x);
821 emit beginSelectionSignal( bgnSel.x(), bgnSel.y() );
822
823 // set the end...
824 i = loc( endSel.x(), endSel.y() );
825 x = endSel.x();
826 while( x < columns-1 && charClass(image[i+1].c) == selClass )
827 { i++; x++ ; }
828 endSel.setX(x);
829 actSel = 2; // within selection
830 emit extendSelectionSignal( endSel.x(), endSel.y() );
831 emit endSelectionSignal(preserve_line_breaks);
832 preserve_line_breaks = TRUE;
833 }
834}
835
836void TEWidget::focusInEvent( QFocusEvent * )
837{
838 // do nothing, to prevent repainting
839}
840
841
842void TEWidget::focusOutEvent( QFocusEvent * )
843{
844 // do nothing, to prevent repainting
845}
846
847bool TEWidget::focusNextPrevChild( bool next )
848{
849 if (next)
850 return false; // This disables changing the active part in konqueror
851 // when pressing Tab
852 return QFrame::focusNextPrevChild( next );
853}
854
855
856int TEWidget::charClass(char ch) const
857{
858 // This might seem like overkill, but imagine if ch was a Unicode
859 // character (Qt 2.0 QChar) - it might then be sensible to separate
860 // the different language ranges, etc.
861
862 if ( isspace(ch) ) return ' ';
863
864 static const char *word_characters = ":@-./_~";
865 if ( isalnum(ch) || strchr(word_characters, ch) )
866 return 'a';
867
868 // Everything else is weird
869 return 1;
870}
871
872void TEWidget::setMouseMarks(bool on)
873{
874 mouse_marks = on;
875 setCursor( mouse_marks ? ibeamCursor : arrowCursor );
876}
877
878/* ------------------------------------------------------------------------- */
879/* */
880/* Clipboard */
881/* */
882/* ------------------------------------------------------------------------- */
883
884#undef KeyPress
885
886void TEWidget::emitSelection()
887// Paste Clipboard by simulating keypress events
888{
889#ifndef QT_NO_CLIPBOARD
890 QString text = QApplication::clipboard()->text();
891 if ( ! text.isNull() )
892 {
893 text.replace(QRegExp("\n"), "\r");
894 QKeyEvent e(QEvent::KeyPress, 0, -1, 0, text);
895 emit keyPressedSignal(&e); // expose as a big fat keypress event
896 emit clearSelectionSignal();
897 }
898#endif
899}
900
901void TEWidget::emitText(QString text)
902{
903 QKeyEvent e(QEvent::KeyPress, 0, -1, 0, text);
904 emit keyPressedSignal(&e); // expose as a big fat keypress event
905}
906
907void TEWidget::pasteClipboard( )
908{
909 emitSelection();
910}
911
912void TEWidget::setSelection(const QString& t)
913{
914#ifndef QT_NO_CLIPBOARD
915 // Disconnect signal while WE set the clipboard
916 QObject *cb = QApplication::clipboard();
917 QObject::disconnect( cb, SIGNAL(dataChanged()),
918 this, SLOT(onClearSelection()) );
919
920 QApplication::clipboard()->setText(t);
921
922 QObject::connect( cb, SIGNAL(dataChanged()),
923 this, SLOT(onClearSelection()) );
924#endif
925}
926
927void TEWidget::onClearSelection()
928{
929 emit clearSelectionSignal();
930}
931
932/* ------------------------------------------------------------------------- */
933/* */
934/* Keyboard */
935/* */
936/* ------------------------------------------------------------------------- */
937
938//FIXME: an `eventFilter' has been installed instead of a `keyPressEvent'
939// due to a bug in `QT' or the ignorance of the author to prevent
940// repaint events being emitted to the screen whenever one leaves
941// or reenters the screen to/from another application.
942//
943// Troll says one needs to change focusInEvent() and focusOutEvent(),
944// which would also let you have an in-focus cursor and an out-focus
945// cursor like xterm does.
946
947// for the auto-hide cursor feature, I added empty focusInEvent() and
948// focusOutEvent() so that update() isn't called.
949// For auto-hide, we need to get keypress-events, but we only get them when
950// we have focus.
951
952void TEWidget::doScroll(int lines)
953{
954 scrollbar->setValue(scrollbar->value()+lines);
955}
956
957bool TEWidget::eventFilter( QObject *obj, QEvent *e )
958{
959 if ( (e->type() == QEvent::Accel ||
960 e->type() == QEvent::AccelAvailable ) && qApp->focusWidget() == this )
961 {
962 static_cast<QKeyEvent *>( e )->ignore();
963 return true;
964 }
965 if ( obj != this /* when embedded */ && obj != parent() /* when standalone */ )
966 return FALSE; // not us
967 if ( e->type() == QEvent::Wheel)
968 {
969 QApplication::sendEvent(scrollbar, e);
970 }
971
972#ifdef FAKE_CTRL_AND_ALT
973 static bool control = FALSE;
974 static bool alt = FALSE;
975 // Has a keyboard with no CTRL and ALT keys, but we fake it:
976 bool dele=FALSE;
977 if ( e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease ) {
978 QKeyEvent* ke = (QKeyEvent*)e;
979 bool keydown = e->type() == QEvent::KeyPress || ke->isAutoRepeat();
980 switch (ke->key()) {
981 case Key_F9: // let this be "Control"
982 control = keydown;
983 e = new QKeyEvent(QEvent::KeyPress, Key_Control, 0, ke->state());
984 dele=TRUE;
985 break;
986 case Key_F13: // let this be "Alt"
987 alt = keydown;
988 e = new QKeyEvent(QEvent::KeyPress, Key_Alt, 0, ke->state());
989 dele=TRUE;
990 break;
991 default:
992 if ( control ) {
993 int a = toupper(ke->ascii())-64;
994 if ( a >= 0 && a < ' ' ) {
995 e = new QKeyEvent(e->type(), ke->key(),
996 a, ke->state()|ControlButton, QChar(a,0));
997 dele=TRUE;
998 }
999 }
1000 if ( alt ) {
1001 e = new QKeyEvent(e->type(), ke->key(),
1002 ke->ascii(), ke->state()|AltButton, ke->text());
1003 dele=TRUE;
1004 }
1005 }
1006 }
1007#endif
1008
1009 if ( e->type() == QEvent::KeyPress )
1010 {
1011 QKeyEvent* ke = (QKeyEvent*)e;
1012
1013 actSel=0; // Key stroke implies a screen update, so TEWidget won't
1014 // know where the current selection is.
1015
1016 emit keyPressedSignal(ke); // expose
1017 ke->accept();
1018#ifdef FAKE_CTRL_AND_ALT
1019 if ( dele ) delete e;
1020#endif
1021 return true; // stop the event
1022 }
1023 if ( e->type() == QEvent::Enter )
1024 {
1025 QObject::disconnect( (QObject*)cb, SIGNAL(dataChanged()),
1026 this, SLOT(onClearSelection()) );
1027 }
1028 if ( e->type() == QEvent::Leave )
1029 {
1030 QObject::connect( (QObject*)cb, SIGNAL(dataChanged()),
1031 this, SLOT(onClearSelection()) );
1032 }
1033 return QFrame::eventFilter( obj, e );
1034}
1035
1036/* ------------------------------------------------------------------------- */
1037/* */
1038/* Frame */
1039/* */
1040/* ------------------------------------------------------------------------- */
1041
1042void TEWidget::frameChanged()
1043{
1044 propagateSize();
1045 update();
1046}
1047
1048/* ------------------------------------------------------------------------- */
1049/* */
1050/* Sound */
1051/* */
1052/* ------------------------------------------------------------------------- */
1053
1054void TEWidget::Bell()
1055{
1056 QApplication::beep();
1057}
1058
1059/* ------------------------------------------------------------------------- */
1060/* */
1061/* Auxiluary */
1062/* */
1063/* ------------------------------------------------------------------------- */
1064
1065void TEWidget::clearImage()
1066// initialize the image
1067// for internal use only
1068{
1069 for (int y = 0; y < lines; y++)
1070 for (int x = 0; x < columns; x++)
1071 {
1072 image[loc(x,y)].c = 0xff; //' ';
1073 image[loc(x,y)].f = 0xff; //DEFAULT_FORE_COLOR;
1074 image[loc(x,y)].b = 0xff; //DEFAULT_BACK_COLOR;
1075 image[loc(x,y)].r = 0xff; //DEFAULT_RENDITION;
1076 }
1077}
1078
1079// Create Image ///////////////////////////////////////////////////////
1080
1081void TEWidget::calcGeometry()
1082{
1083 //FIXME: set rimX == rimY == 0 when running in full screen mode.
1084
1085 scrollbar->resize(QApplication::style().scrollBarExtent().width(),
1086 contentsRect().height());
1087 switch(scrollLoc)
1088 {
1089 case SCRNONE :
1090 columns = ( contentsRect().width() - 2 * rimX ) / font_w;
1091 blX = (contentsRect().width() - (columns*font_w) ) / 2;
1092 brX = blX;
1093 scrollbar->hide();
1094 break;
1095 case SCRLEFT :
1096 columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w;
1097 brX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2;
1098 blX = brX + scrollbar->width();
1099 scrollbar->move(contentsRect().topLeft());
1100 scrollbar->show();
1101 break;
1102 case SCRRIGHT:
1103 columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w;
1104 blX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2;
1105 brX = blX;
1106 scrollbar->move(contentsRect().topRight() - QPoint(scrollbar->width()-1,0));
1107 scrollbar->show();
1108 break;
1109 }
1110 //FIXME: support 'rounding' styles
1111 lines = ( contentsRect().height() - 2 * rimY ) / font_h;
1112 bY = (contentsRect().height() - (lines *font_h)) / 2;
1113}
1114
1115void TEWidget::makeImage()
1116//FIXME: rename 'calcGeometry?
1117{
1118 calcGeometry();
1119 image = (ca*) malloc(lines*columns*sizeof(ca));
1120 clearImage();
1121}
1122
1123// calculate the needed size
1124QSize TEWidget::calcSize(int cols, int lins) const
1125{
1126 int frw = width() - contentsRect().width();
1127 int frh = height() - contentsRect().height();
1128 int scw = (scrollLoc==SCRNONE?0:scrollbar->width());
1129 return QSize( font_w*cols + 2*rimX + frw + scw, font_h*lins + 2*rimY + frh );
1130}
1131
1132QSize TEWidget::sizeHint() const
1133{
1134 return size();
1135}
1136
1137void TEWidget::styleChange(QStyle &)
1138{
1139 propagateSize();
1140}
1141
1142#ifndef QT_NO_DRAGANDDROP
1143
1144/* --------------------------------------------------------------------- */
1145/* */
1146/* Drag & Drop */
1147/* */
1148/* --------------------------------------------------------------------- */
1149
1150
1151void TEWidget::dragEnterEvent(QDragEnterEvent* e)
1152{
1153 e->accept(QTextDrag::canDecode(e) ||
1154 QUriDrag::canDecode(e));
1155}
1156
1157void TEWidget::dropEvent(QDropEvent* event)
1158{
1159 // The current behaviour when url(s) are dropped is
1160 // * if there is only ONE url and if it's a LOCAL one, ask for paste or cd
1161 // * in all other cases, just paste
1162 // (for non-local ones, or for a list of URLs, 'cd' is nonsense)
1163 QStrList strlist;
1164 int file_count = 0;
1165 dropText = "";
1166 bool bPopup = true;
1167
1168 if(QUriDrag::decode(event, strlist)) {
1169 if (strlist.count()) {
1170 for(const char* p = strlist.first(); p; p = strlist.next()) {
1171 if(file_count++ > 0) {
1172 dropText += " ";
1173 bPopup = false; // more than one file, don't popup
1174 }
1175
1176/*
1177 KURL url(p);
1178 if (url.isLocalFile()) {
1179 dropText += url.path(); // local URL : remove protocol
1180 }
1181 else {
1182 dropText += url.prettyURL();
1183 bPopup = false; // a non-local file, don't popup
1184 }
1185*/
1186
1187 }
1188
1189 if (bPopup)
1190 // m_drop->popup(pos() + event->pos());
1191 m_drop->popup(mapToGlobal(event->pos()));
1192 else
1193 {
1194 if (currentSession) {
1195 currentSession->getEmulation()->sendString(dropText.local8Bit());
1196 }
1197 // kdDebug() << "Drop:" << dropText.local8Bit() << "\n";
1198 }
1199 }
1200 }
1201 else if(QTextDrag::decode(event, dropText)) {
1202// kdDebug() << "Drop:" << dropText.local8Bit() << "\n";
1203 if (currentSession) {
1204 currentSession->getEmulation()->sendString(dropText.local8Bit());
1205 }
1206 // Paste it
1207 }
1208}
1209#endif
1210
1211
1212void TEWidget::drop_menu_activated(int item)
1213{
1214#ifndef QT_NO_DRAGANDDROP
1215 switch (item)
1216 {
1217 case 0: // paste
1218 currentSession->getEmulation()->sendString(dropText.local8Bit());
1219// KWM::activate((Window)this->winId());
1220 break;
1221 case 1: // cd ...
1222 currentSession->getEmulation()->sendString("cd ");
1223 struct stat statbuf;
1224 if ( ::stat( QFile::encodeName( dropText ), &statbuf ) == 0 )
1225 {
1226 if ( !S_ISDIR(statbuf.st_mode) )
1227 {
1228/*
1229 KURL url;
1230 url.setPath( dropText );
1231 dropText = url.directory( true, false ); // remove filename
1232*/
1233 }
1234 }
1235 dropText.replace(QRegExp(" "), "\\ "); // escape spaces
1236 currentSession->getEmulation()->sendString(dropText.local8Bit());
1237 currentSession->getEmulation()->sendString("\n");
1238// KWM::activate((Window)this->winId());
1239 break;
1240 }
1241#endif
1242}
1243
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 @@
1/* ----------------------------------------------------------------------- */
2/* */
3/* [te_widget.h] Terminal Emulation Widget */
4/* */
5/* ----------------------------------------------------------------------- */
6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */
9/* This file is part of Konsole - an X terminal for KDE */
10/* */
11/* ----------------------------------------------------------------------- */
12 /* */
13/* Ported Konsole to Qt/Embedded */
14 /* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16 /* */
17/* -------------------------------------------------------------------------- */
18
19#ifndef TE_WIDGET_H
20#define TE_WIDGET_H
21
22#include <qwidget.h>
23#include <qlabel.h>
24#include <qtimer.h>
25#include <qcolor.h>
26#include <qkeycode.h>
27#include <qscrollbar.h>
28
29#include <qpopupmenu.h>
30
31#include "TECommon.h"
32
33extern unsigned short vt100_graphics[32];
34
35class TESession;
36
37// class Konsole;
38
39class TEWidget : public QFrame
40// a widget representing attributed text
41{ Q_OBJECT
42
43// friend class Konsole;
44
45public:
46
47 TEWidget(QWidget *parent=0, const char *name=0);
48 virtual ~TEWidget();
49
50public:
51
52 QColor getDefaultBackColor();
53
54 const ColorEntry* getColorTable() const;
55 void setColorTable(const ColorEntry table[]);
56
57 void setScrollbarLocation(int loc);
58 enum { SCRNONE=0, SCRLEFT=1, SCRRIGHT=2 };
59
60 void setScroll(int cursor, int lines);
61 void doScroll(int lines);
62
63 void emitSelection();
64
65public:
66
67 void setImage(const ca* const newimg, int lines, int columns);
68
69 int Lines() { return lines; }
70 int Columns() { return columns; }
71
72 void calcGeometry();
73 void propagateSize();
74 QSize calcSize(int cols, int lins) const;
75
76 QSize sizeHint() const;
77
78public:
79
80 void Bell();
81 void emitText(QString text);
82 void pasteClipboard();
83
84signals:
85
86 void keyPressedSignal(QKeyEvent *e);
87 void mouseSignal(int cb, int cx, int cy);
88 void changedImageSizeSignal(int lines, int columns);
89 void changedHistoryCursor(int value);
90 void configureRequest( TEWidget*, int state, int x, int y );
91
92 void clearSelectionSignal();
93 void beginSelectionSignal( const int x, const int y );
94 void extendSelectionSignal( const int x, const int y );
95 void endSelectionSignal(const BOOL preserve_line_breaks);
96
97
98protected:
99
100 virtual void styleChange( QStyle& );
101
102 bool eventFilter( QObject *, QEvent * );
103
104 void drawAttrStr(QPainter &paint, QRect rect,
105 QString& str, ca attr, BOOL pm, BOOL clear);
106 void paintEvent( QPaintEvent * );
107
108 void resizeEvent(QResizeEvent*);
109
110 void fontChange(const QFont &font);
111 void frameChanged();
112
113 void mouseDoubleClickEvent(QMouseEvent* ev);
114 void mousePressEvent( QMouseEvent* );
115 void mouseReleaseEvent( QMouseEvent* );
116 void mouseMoveEvent( QMouseEvent* );
117
118 void focusInEvent( QFocusEvent * );
119 void focusOutEvent( QFocusEvent * );
120 bool focusNextPrevChild( bool next );
121
122#ifndef QT_NO_DRAGANDDROP
123 // Dnd
124 void dragEnterEvent(QDragEnterEvent* event);
125 void dropEvent(QDropEvent* event);
126#endif
127
128 virtual int charClass(char) const;
129
130 void clearImage();
131
132public:
133 const QPixmap *backgroundPixmap();
134
135 void setSelection(const QString &t);
136
137 virtual void setFont(const QFont &);
138 void setVTFont(const QFont &);
139 QFont getVTFont();
140
141 void setMouseMarks(bool on);
142
143public slots:
144
145 void onClearSelection();
146
147protected slots:
148
149 void scrollChanged(int value);
150 void blinkEvent();
151
152private:
153
154 QChar (*fontMap)(QChar); // possible vt100 font extention
155
156 bool fixed_font; // has fixed pitch
157 int font_h; // height
158 int font_w; // width
159 int font_a; // ascend
160
161 int blX; // actual offset (left)
162 int brX; // actual offset (right)
163 int bY; // actual offset
164
165 int lines;
166 int columns;
167 ca *image; // [lines][columns]
168
169 ColorEntry color_table[TABLE_COLORS];
170
171 BOOL resizing;
172 bool mouse_marks;
173
174 void makeImage();
175
176 QPoint iPntSel; // initial selection point
177 QPoint pntSel; // current selection point
178 int actSel; // selection state
179 BOOL word_selection_mode;
180 BOOL preserve_line_breaks;
181
182 QClipboard* cb;
183 QScrollBar* scrollbar;
184 int scrollLoc;
185
186//#define SCRNONE 0
187//#define SCRLEFT 1
188//#define SCRRIGHT 2
189
190 BOOL blinking; // hide text in paintEvent
191 BOOL hasBlinker; // has characters to blink
192 QTimer* blinkT; // active when hasBlinker
193 QPopupMenu* m_drop;
194 QString dropText;
195 public:
196 // current session in this widget
197 TESession *currentSession;
198private slots:
199 void drop_menu_activated(int item);
200};
201
202#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 @@
1/* ------------------------------------------------------------------------- */
2/* */
3/* [TEmuVt102.C] VT102 Terminal Emulation */
4/* */
5/* ------------------------------------------------------------------------- */
6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */
9/* This file is part of Konsole - an X terminal for KDE */
10/* */
11/* ------------------------------------------------------------------------- */
12 /* */
13/* Ported Konsole to Qt/Embedded */
14 /* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16 /* */
17/* -------------------------------------------------------------------------- */
18
19/*! \class TEmuVt102
20
21 \brief Actual Emulation for Konsole
22
23 \sa TEWidget \sa TEScreen
24*/
25
26#include "TEmuVt102.h"
27#include "TEWidget.h"
28#include "TEScreen.h"
29#include "keytrans.h"
30
31#include <stdio.h>
32#include <unistd.h>
33#include <qkeycode.h>
34#include <qtextcodec.h>
35
36
37/* VT102 Terminal Emulation
38
39 This class puts together the screens, the pty and the widget to a
40 complete terminal emulation. Beside combining it's componentes, it
41 handles the emulations's protocol.
42
43 This module consists of the following sections:
44
45 - Constructor/Destructor
46 - Incoming Bytes Event pipeline
47 - Outgoing Bytes
48 - Mouse Events
49 - Keyboard Events
50 - Modes and Charset State
51 - Diagnostics
52*/
53
54
55/* ------------------------------------------------------------------------- */
56/* */
57/* Constructor / Destructor */
58/* */
59/* ------------------------------------------------------------------------- */
60
61/*
62 Nothing really intesting happens here.
63*/
64
65/*!
66*/
67
68TEmuVt102::TEmuVt102(TEWidget* gui) : TEmulation(gui)
69{
70 QObject::connect(gui,SIGNAL(mouseSignal(int,int,int)),
71 this,SLOT(onMouse(int,int,int)));
72 initTokenizer();
73 reset();
74}
75
76/*!
77*/
78
79TEmuVt102::~TEmuVt102()
80{
81}
82
83/*!
84*/
85
86void TEmuVt102::reset()
87{
88 resetToken();
89 resetModes();
90 resetCharset(0); screen[0]->reset();
91 resetCharset(1); screen[0]->reset();
92 setCodec(0);
93 setKeytrans("linux.keytab");
94}
95
96/* ------------------------------------------------------------------------- */
97/* */
98/* Processing the incoming byte stream */
99/* */
100/* ------------------------------------------------------------------------- */
101
102/* Incoming Bytes Event pipeline
103
104 This section deals with decoding the incoming character stream.
105 Decoding means here, that the stream is first seperated into `tokens'
106 which are then mapped to a `meaning' provided as operations by the
107 `TEScreen' class or by the emulation class itself.
108
109 The pipeline proceeds as follows:
110
111 - Tokenizing the ESC codes (onRcvChar)
112 - VT100 code page translation of plain characters (applyCharset)
113 - Interpretation of ESC codes (tau)
114
115 The escape codes and their meaning are described in the
116 technical reference of this program.
117*/
118
119// Tokens ------------------------------------------------------------------ --
120
121/*
122 Since the tokens are the central notion if this section, we've put them
123 in front. They provide the syntactical elements used to represent the
124 terminals operations as byte sequences.
125
126 They are encodes here into a single machine word, so that we can later
127 switch over them easily. Depending on the token itself, additional
128 argument variables are filled with parameter values.
129
130 The tokens are defined below:
131
132 - CHR - Printable characters (32..255 but DEL (=127))
133 - CTL - Control characters (0..31 but ESC (= 27), DEL)
134 - ESC - Escape codes of the form <ESC><CHR but `[]()+*#'>
135 - ESC_DE - Escape codes of the form <ESC><any of `()+*#%'> C
136 - CSI_PN - Escape codes of the form <ESC>'[' {Pn} ';' {Pn} C
137 - CSI_PS - Escape codes of the form <ESC>'[' {Pn} ';' ... C
138 - CSI_PR - Escape codes of the form <ESC>'[' '?' {Pn} ';' ... C
139 - VT52 - VT52 escape codes
140 - <ESC><Chr>
141 - <ESC>'Y'{Pc}{Pc}
142 - XTE_HA - Xterm hacks <ESC>`]' {Pn} `;' {Text} <BEL>
143 note that this is handled differently
144
145 The last two forms allow list of arguments. Since the elements of
146 the lists are treated individually the same way, they are passed
147 as individual tokens to the interpretation. Further, because the
148 meaning of the parameters are names (althought represented as numbers),
149 they are includes within the token ('N').
150
151*/
152
153#define TY_CONSTR(T,A,N) ( ((((int)N) & 0xffff) << 16) | ((((int)A) & 0xff) << 8) | (((int)T) & 0xff) )
154
155#define TY_CHR___( ) TY_CONSTR(0,0,0)
156#define TY_CTL___(A ) TY_CONSTR(1,A,0)
157#define TY_ESC___(A ) TY_CONSTR(2,A,0)
158#define TY_ESC_CS(A,B) TY_CONSTR(3,A,B)
159#define TY_ESC_DE(A ) TY_CONSTR(4,A,0)
160#define TY_CSI_PS(A,N) TY_CONSTR(5,A,N)
161#define TY_CSI_PN(A ) TY_CONSTR(6,A,0)
162#define TY_CSI_PR(A,N) TY_CONSTR(7,A,N)
163
164#define TY_VT52__(A ) TY_CONSTR(8,A,0)
165
166// Tokenizer --------------------------------------------------------------- --
167
168/* The tokenizers state
169
170 The state is represented by the buffer (pbuf, ppos),
171 and accompanied by decoded arguments kept in (argv,argc).
172 Note that they are kept internal in the tokenizer.
173*/
174
175void TEmuVt102::resetToken()
176{
177 ppos = 0; argc = 0; argv[0] = 0; argv[1] = 0;
178}
179
180void TEmuVt102::addDigit(int dig)
181{
182 argv[argc] = 10*argv[argc] + dig;
183}
184
185void TEmuVt102::addArgument()
186{
187 argc = QMIN(argc+1,MAXARGS-1);
188 argv[argc] = 0;
189}
190
191void TEmuVt102::pushToToken(int cc)
192{
193 pbuf[ppos] = cc;
194 ppos = QMIN(ppos+1,MAXPBUF-1);
195}
196
197// Character Classes used while decoding
198
199#define CTL 1
200#define CHR 2
201#define CPN 4
202#define DIG 8
203#define SCS 16
204#define GRP 32
205
206void TEmuVt102::initTokenizer()
207{ int i; UINT8* s;
208 for(i = 0; i < 256; i++) tbl[ i] = 0;
209 for(i = 0; i < 32; i++) tbl[ i] |= CTL;
210 for(i = 32; i < 256; i++) tbl[ i] |= CHR;
211 for(s = (UINT8*)"@ABCDGHLMPXcdfry"; *s; s++) tbl[*s] |= CPN;
212 for(s = (UINT8*)"0123456789" ; *s; s++) tbl[*s] |= DIG;
213 for(s = (UINT8*)"()+*%" ; *s; s++) tbl[*s] |= SCS;
214 for(s = (UINT8*)"()+*#[]%" ; *s; s++) tbl[*s] |= GRP;
215 resetToken();
216}
217
218/* Ok, here comes the nasty part of the decoder.
219
220 Instead of keeping an explicit state, we deduce it from the
221 token scanned so far. It is then immediately combined with
222 the current character to form a scanning decision.
223
224 This is done by the following defines.
225
226 - P is the length of the token scanned so far.
227 - L (often P-1) is the position on which contents we base a decision.
228 - C is a character or a group of characters (taken from 'tbl').
229
230 Note that they need to applied in proper order.
231*/
232
233#define lec(P,L,C) (p == (P) && s[(L)] == (C))
234#define lun( ) (p == 1 && cc >= 32 )
235#define les(P,L,C) (p == (P) && s[L] < 256 && (tbl[s[(L)]] & (C)) == (C))
236#define eec(C) (p >= 3 && cc == (C))
237#define ees(C) (p >= 3 && cc < 256 && (tbl[ cc ] & (C)) == (C))
238#define eps(C) (p >= 3 && s[2] != '?' && cc < 256 && (tbl[ cc ] & (C)) == (C))
239#define epp( ) (p >= 3 && s[2] == '?' )
240#define egt( ) (p == 3 && s[2] == '>' )
241#define Xpe (ppos>=2 && pbuf[1] == ']' )
242#define Xte (Xpe && cc == 7 )
243#define ces(C) ( cc < 256 && (tbl[ cc ] & (C)) == (C) && !Xte)
244
245#define ESC 27
246#define CNTL(c) ((c)-'@')
247
248// process an incoming unicode character
249
250void TEmuVt102::onRcvChar(int cc)
251{ int i;
252
253 if (cc == 127) return; //VT100: ignore.
254
255 if (ces( CTL))
256 { // DEC HACK ALERT! Control Characters are allowed *within* esc sequences in VT100
257 // This means, they do neither a resetToken nor a pushToToken. Some of them, do
258 // of course. Guess this originates from a weakly layered handling of the X-on
259 // X-off protocol, which comes really below this level.
260 if (cc == CNTL('X') || cc == CNTL('Z') || cc == ESC) resetToken(); //VT100: CAN or SUB
261 if (cc != ESC) { tau( TY_CTL___(cc+'@' ), 0, 0); return; }
262 }
263
264 pushToToken(cc); // advance the state
265
266 int* s = pbuf;
267 int p = ppos;
268
269 if (getMode(MODE_Ansi)) // decide on proper action
270 {
271 if (lec(1,0,ESC)) { return; }
272 if (les(2,1,GRP)) { return; }
273 if (Xte ) { XtermHack(); resetToken(); return; }
274 if (Xpe ) { return; }
275 if (lec(3,2,'?')) { return; }
276 if (lec(3,2,'>')) { return; }
277 if (lun( )) { tau( TY_CHR___(), applyCharset(cc), 0); resetToken(); return; }
278 if (lec(2,0,ESC)) { tau( TY_ESC___(s[1]), 0, 0); resetToken(); return; }
279 if (les(3,1,SCS)) { tau( TY_ESC_CS(s[1],s[2]), 0, 0); resetToken(); return; }
280 if (lec(3,1,'#')) { tau( TY_ESC_DE(s[2]), 0, 0); resetToken(); return; }
281// if (egt( )) { tau( TY_CSI_PG(cc ), '>', 0); resetToken(); return; }
282 if (eps( CPN)) { tau( TY_CSI_PN(cc), argv[0],argv[1]); resetToken(); return; }
283 if (ees( DIG)) { addDigit(cc-'0'); return; }
284 if (eec( ';')) { addArgument(); return; }
285 for (i=0;i<=argc;i++)
286 if (epp( )) tau( TY_CSI_PR(cc,argv[i]), 0, 0); else
287 tau( TY_CSI_PS(cc,argv[i]), 0, 0);
288 resetToken();
289 }
290 else // mode VT52
291 {
292 if (lec(1,0,ESC)) return;
293 if (les(1,0,CHR)) { tau( TY_CHR___( ), s[0], 0); resetToken(); return; }
294 if (lec(2,1,'Y')) return;
295 if (lec(3,1,'Y')) return;
296 if (p < 4) { tau( TY_VT52__(s[1] ), 0, 0); resetToken(); return; }
297 tau( TY_VT52__(s[1] ), s[2],s[3]); resetToken(); return;
298 }
299}
300
301void TEmuVt102::XtermHack()
302{ int i,arg = 0;
303 for (i = 2; i < ppos && '0'<=pbuf[i] && pbuf[i]<'9' ; i++)
304 arg = 10*arg + (pbuf[i]-'0');
305 if (pbuf[i] != ';') { ReportErrorToken(); return; }
306 QChar *str = new QChar[ppos-i-2];
307 for (int j = 0; j < ppos-i-2; j++) str[j] = pbuf[i+1+j];
308 QString unistr(str,ppos-i-2);
309 // arg == 1 doesn't change the title. In XTerm it only changes the icon name
310 // (btw: arg=0 changes title and icon, arg=1 only icon, arg=2 only title
311 if (arg == 0 || arg == 2) emit changeTitle(arg,unistr);
312 delete [] str;
313}
314
315// Interpreting Codes ---------------------------------------------------------
316
317/*
318 Now that the incoming character stream is properly tokenized,
319 meaning is assigned to them. These are either operations of
320 the current screen, or of the emulation class itself.
321
322 The token to be interpreteted comes in as a machine word
323 possibly accompanied by two parameters.
324
325 Likewise, the operations assigned to, come with up to two
326 arguments. One could consider to make up a proper table
327 from the function below.
328
329 The technical reference manual provides more informations
330 about this mapping.
331*/
332
333void TEmuVt102::tau( int token, int p, int q )
334{
335//scan_buffer_report();
336//if (token == TY_CHR___()) printf("%c",p); else
337//printf("tau(%d,%d,%d, %d,%d)\n",(token>>0)&0xff,(token>>8)&0xff,(token>>16)&0xffff,p,q);
338 switch (token)
339 {
340
341 case TY_CHR___( ) : scr->ShowCharacter (p ); break; //UTF16
342
343 // 127 DEL : ignored on input
344
345 case TY_CTL___('@' ) : /* NUL: ignored */ break;
346 case TY_CTL___('A' ) : /* SOH: ignored */ break;
347 case TY_CTL___('B' ) : /* STX: ignored */ break;
348 case TY_CTL___('C' ) : /* ETX: ignored */ break;
349 case TY_CTL___('D' ) : /* EOT: ignored */ break;
350 case TY_CTL___('E' ) : reportAnswerBack ( ); break; //VT100
351 case TY_CTL___('F' ) : /* ACK: ignored */ break;
352 case TY_CTL___('G' ) : gui->Bell ( ); break; //VT100
353 case TY_CTL___('H' ) : scr->BackSpace ( ); break; //VT100
354 case TY_CTL___('I' ) : scr->Tabulate ( ); break; //VT100
355 case TY_CTL___('J' ) : scr->NewLine ( ); break; //VT100
356 case TY_CTL___('K' ) : scr->NewLine ( ); break; //VT100
357 case TY_CTL___('L' ) : scr->NewLine ( ); break; //VT100
358 case TY_CTL___('M' ) : scr->Return ( ); break; //VT100
359
360 case TY_CTL___('N' ) : useCharset ( 1); break; //VT100
361 case TY_CTL___('O' ) : useCharset ( 0); break; //VT100
362
363 case TY_CTL___('P' ) : /* DLE: ignored */ break;
364 case TY_CTL___('Q' ) : /* DC1: XON continue */ break; //VT100
365 case TY_CTL___('R' ) : /* DC2: ignored */ break;
366 case TY_CTL___('S' ) : /* DC3: XOFF halt */ break; //VT100
367 case TY_CTL___('T' ) : /* DC4: ignored */ break;
368 case TY_CTL___('U' ) : /* NAK: ignored */ break;
369 case TY_CTL___('V' ) : /* SYN: ignored */ break;
370 case TY_CTL___('W' ) : /* ETB: ignored */ break;
371 case TY_CTL___('X' ) : scr->ShowCharacter ( 0x2592); break; //VT100
372 case TY_CTL___('Y' ) : /* EM : ignored */ break;
373 case TY_CTL___('Z' ) : scr->ShowCharacter ( 0x2592); break; //VT100
374 case TY_CTL___('[' ) : /* ESC: cannot be seen here. */ break;
375 case TY_CTL___('\\' ) : /* FS : ignored */ break;
376 case TY_CTL___(']' ) : /* GS : ignored */ break;
377 case TY_CTL___('^' ) : /* RS : ignored */ break;
378 case TY_CTL___('_' ) : /* US : ignored */ break;
379
380 case TY_ESC___('D' ) : scr->index ( ); break; //VT100
381 case TY_ESC___('E' ) : scr->NextLine ( ); break; //VT100
382 case TY_ESC___('H' ) : scr->changeTabStop (TRUE ); break; //VT100
383 case TY_ESC___('M' ) : scr->reverseIndex ( ); break; //VT100
384 case TY_ESC___('Z' ) : reportTerminalType ( ); break;
385 case TY_ESC___('c' ) : reset ( ); break;
386
387 case TY_ESC___('n' ) : useCharset ( 2); break;
388 case TY_ESC___('o' ) : useCharset ( 3); break;
389 case TY_ESC___('7' ) : saveCursor ( ); break;
390 case TY_ESC___('8' ) : restoreCursor ( ); break;
391
392 case TY_ESC___('=' ) : setMode (MODE_AppKeyPad); break;
393 case TY_ESC___('>' ) : resetMode (MODE_AppKeyPad); break;
394 case TY_ESC___('<' ) : setMode (MODE_Ansi ); break; //VT100
395
396 case TY_ESC_CS('(', '0') : setCharset (0, '0'); break; //VT100
397 case TY_ESC_CS('(', 'A') : setCharset (0, 'A'); break; //VT100
398 case TY_ESC_CS('(', 'B') : setCharset (0, 'B'); break; //VT100
399
400 case TY_ESC_CS(')', '0') : setCharset (1, '0'); break; //VT100
401 case TY_ESC_CS(')', 'A') : setCharset (1, 'A'); break; //VT100
402 case TY_ESC_CS(')', 'B') : setCharset (1, 'B'); break; //VT100
403
404 case TY_ESC_CS('*', '0') : setCharset (2, '0'); break; //VT100
405 case TY_ESC_CS('*', 'A') : setCharset (2, 'A'); break; //VT100
406 case TY_ESC_CS('*', 'B') : setCharset (2, 'B'); break; //VT100
407
408 case TY_ESC_CS('+', '0') : setCharset (3, '0'); break; //VT100
409 case TY_ESC_CS('+', 'A') : setCharset (3, 'A'); break; //VT100
410 case TY_ESC_CS('+', 'B') : setCharset (3, 'B'); break; //VT100
411
412 case TY_ESC_CS('%', 'G') : setCodec (1 ); break; //LINUX
413 case TY_ESC_CS('%', '@') : setCodec (0 ); break; //LINUX
414
415 case TY_ESC_DE('3' ) : /* IGNORED: double high, top half */ break;
416 case TY_ESC_DE('4' ) : /* IGNORED: double high, bottom half */ break;
417 case TY_ESC_DE('5' ) : /* IGNORED: single width, single high*/ break;
418 case TY_ESC_DE('6' ) : /* IGNORED: double width, single high*/ break;
419 case TY_ESC_DE('8' ) : scr->helpAlign ( ); break;
420
421 case TY_CSI_PS('K', 0) : scr->clearToEndOfLine ( ); break;
422 case TY_CSI_PS('K', 1) : scr->clearToBeginOfLine ( ); break;
423 case TY_CSI_PS('K', 2) : scr->clearEntireLine ( ); break;
424 case TY_CSI_PS('J', 0) : scr->clearToEndOfScreen ( ); break;
425 case TY_CSI_PS('J', 1) : scr->clearToBeginOfScreen ( ); break;
426 case TY_CSI_PS('J', 2) : scr->clearEntireScreen ( ); break;
427 case TY_CSI_PS('g', 0) : scr->changeTabStop (FALSE ); break; //VT100
428 case TY_CSI_PS('g', 3) : scr->clearTabStops ( ); break; //VT100
429 case TY_CSI_PS('h', 4) : scr-> setMode (MODE_Insert ); break;
430 case TY_CSI_PS('h', 20) : setMode (MODE_NewLine ); break;
431 case TY_CSI_PS('i', 0) : /* IGNORE: attached printer */ break; //VT100
432 case TY_CSI_PS('l', 4) : scr-> resetMode (MODE_Insert ); break;
433 case TY_CSI_PS('l', 20) : resetMode (MODE_NewLine ); break;
434
435 case TY_CSI_PS('m', 0) : scr->setDefaultRendition ( ); break;
436 case TY_CSI_PS('m', 1) : scr-> setRendition (RE_BOLD ); break; //VT100
437 case TY_CSI_PS('m', 4) : scr-> setRendition (RE_UNDERLINE); break; //VT100
438 case TY_CSI_PS('m', 5) : scr-> setRendition (RE_BLINK ); break; //VT100
439 case TY_CSI_PS('m', 7) : scr-> setRendition (RE_REVERSE ); break;
440 case TY_CSI_PS('m', 10) : /* IGNORED: mapping related */ break; //LINUX
441 case TY_CSI_PS('m', 11) : /* IGNORED: mapping related */ break; //LINUX
442 case TY_CSI_PS('m', 12) : /* IGNORED: mapping related */ break; //LINUX
443 case TY_CSI_PS('m', 22) : scr->resetRendition (RE_BOLD ); break;
444 case TY_CSI_PS('m', 24) : scr->resetRendition (RE_UNDERLINE); break;
445 case TY_CSI_PS('m', 25) : scr->resetRendition (RE_BLINK ); break;
446 case TY_CSI_PS('m', 27) : scr->resetRendition (RE_REVERSE ); break;
447
448 case TY_CSI_PS('m', 30) : scr->setForeColor ( 0); break;
449 case TY_CSI_PS('m', 31) : scr->setForeColor ( 1); break;
450 case TY_CSI_PS('m', 32) : scr->setForeColor ( 2); break;
451 case TY_CSI_PS('m', 33) : scr->setForeColor ( 3); break;
452 case TY_CSI_PS('m', 34) : scr->setForeColor ( 4); break;
453 case TY_CSI_PS('m', 35) : scr->setForeColor ( 5); break;
454 case TY_CSI_PS('m', 36) : scr->setForeColor ( 6); break;
455 case TY_CSI_PS('m', 37) : scr->setForeColor ( 7); break;
456 case TY_CSI_PS('m', 39) : scr->setForeColorToDefault( ); break;
457
458 case TY_CSI_PS('m', 40) : scr->setBackColor ( 0); break;
459 case TY_CSI_PS('m', 41) : scr->setBackColor ( 1); break;
460 case TY_CSI_PS('m', 42) : scr->setBackColor ( 2); break;
461 case TY_CSI_PS('m', 43) : scr->setBackColor ( 3); break;
462 case TY_CSI_PS('m', 44) : scr->setBackColor ( 4); break;
463 case TY_CSI_PS('m', 45) : scr->setBackColor ( 5); break;
464 case TY_CSI_PS('m', 46) : scr->setBackColor ( 6); break;
465 case TY_CSI_PS('m', 47) : scr->setBackColor ( 7); break;
466 case TY_CSI_PS('m', 49) : scr->setBackColorToDefault( ); break;
467
468 case TY_CSI_PS('m', 90) : scr->setForeColor ( 8); break;
469 case TY_CSI_PS('m', 91) : scr->setForeColor ( 9); break;
470 case TY_CSI_PS('m', 92) : scr->setForeColor ( 10); break;
471 case TY_CSI_PS('m', 93) : scr->setForeColor ( 11); break;
472 case TY_CSI_PS('m', 94) : scr->setForeColor ( 12); break;
473 case TY_CSI_PS('m', 95) : scr->setForeColor ( 13); break;
474 case TY_CSI_PS('m', 96) : scr->setForeColor ( 14); break;
475 case TY_CSI_PS('m', 97) : scr->setForeColor ( 15); break;
476
477 case TY_CSI_PS('m', 100) : scr->setBackColor ( 8); break;
478 case TY_CSI_PS('m', 101) : scr->setBackColor ( 9); break;
479 case TY_CSI_PS('m', 102) : scr->setBackColor ( 10); break;
480 case TY_CSI_PS('m', 103) : scr->setBackColor ( 11); break;
481 case TY_CSI_PS('m', 104) : scr->setBackColor ( 12); break;
482 case TY_CSI_PS('m', 105) : scr->setBackColor ( 13); break;
483 case TY_CSI_PS('m', 106) : scr->setBackColor ( 14); break;
484 case TY_CSI_PS('m', 107) : scr->setBackColor ( 15); break;
485
486 case TY_CSI_PS('n', 5) : reportStatus ( ); break;
487 case TY_CSI_PS('n', 6) : reportCursorPosition ( ); break;
488 case TY_CSI_PS('q', 0) : /* IGNORED: LEDs off */ break; //VT100
489 case TY_CSI_PS('q', 1) : /* IGNORED: LED1 on */ break; //VT100
490 case TY_CSI_PS('q', 2) : /* IGNORED: LED2 on */ break; //VT100
491 case TY_CSI_PS('q', 3) : /* IGNORED: LED3 on */ break; //VT100
492 case TY_CSI_PS('q', 4) : /* IGNORED: LED4 on */ break; //VT100
493 case TY_CSI_PS('x', 0) : reportTerminalParms ( 2); break; //VT100
494 case TY_CSI_PS('x', 1) : reportTerminalParms ( 3); break; //VT100
495
496 case TY_CSI_PN('@' ) : scr->insertChars (p ); break;
497 case TY_CSI_PN('A' ) : scr->cursorUp (p ); break; //VT100
498 case TY_CSI_PN('B' ) : scr->cursorDown (p ); break; //VT100
499 case TY_CSI_PN('C' ) : scr->cursorRight (p ); break; //VT100
500 case TY_CSI_PN('D' ) : scr->cursorLeft (p ); break; //VT100
501 case TY_CSI_PN('G' ) : scr->setCursorX (p ); break; //LINUX
502 case TY_CSI_PN('H' ) : scr->setCursorYX (p, q); break; //VT100
503 case TY_CSI_PN('L' ) : scr->insertLines (p ); break;
504 case TY_CSI_PN('M' ) : scr->deleteLines (p ); break;
505 case TY_CSI_PN('P' ) : scr->deleteChars (p ); break;
506 case TY_CSI_PN('X' ) : scr->eraseChars (p ); break;
507 case TY_CSI_PN('c' ) : reportTerminalType ( ); break; //VT100
508 case TY_CSI_PN('d' ) : scr->setCursorY (p ); break; //LINUX
509 case TY_CSI_PN('f' ) : scr->setCursorYX (p, q); break; //VT100
510 case TY_CSI_PN('r' ) : scr->setMargins (p, q); break; //VT100
511 case TY_CSI_PN('y' ) : /* IGNORED: Confidence test */ break; //VT100
512
513 case TY_CSI_PR('h', 1) : setMode (MODE_AppCuKeys); break; //VT100
514 case TY_CSI_PR('l', 1) : resetMode (MODE_AppCuKeys); break; //VT100
515 case TY_CSI_PR('s', 1) : saveMode (MODE_AppCuKeys); break; //FIXME
516 case TY_CSI_PR('r', 1) : restoreMode (MODE_AppCuKeys); break; //FIXME
517
518 case TY_CSI_PR('l', 2) : resetMode (MODE_Ansi ); break; //VT100
519
520 case TY_CSI_PR('h', 3) : setColumns ( 132); break; //VT100
521 case TY_CSI_PR('l', 3) : setColumns ( 80); break; //VT100
522
523 case TY_CSI_PR('h', 4) : /* IGNORED: soft scrolling */ break; //VT100
524 case TY_CSI_PR('l', 4) : /* IGNORED: soft scrolling */ break; //VT100
525
526 case TY_CSI_PR('h', 5) : scr-> setMode (MODE_Screen ); break; //VT100
527 case TY_CSI_PR('l', 5) : scr-> resetMode (MODE_Screen ); break; //VT100
528
529 case TY_CSI_PR('h', 6) : scr-> setMode (MODE_Origin ); break; //VT100
530 case TY_CSI_PR('l', 6) : scr-> resetMode (MODE_Origin ); break; //VT100
531 case TY_CSI_PR('s', 6) : scr-> saveMode (MODE_Origin ); break; //FIXME
532 case TY_CSI_PR('r', 6) : scr->restoreMode (MODE_Origin ); break; //FIXME
533
534 case TY_CSI_PR('h', 7) : scr-> setMode (MODE_Wrap ); break; //VT100
535 case TY_CSI_PR('l', 7) : scr-> resetMode (MODE_Wrap ); break; //VT100
536 case TY_CSI_PR('s', 7) : scr-> saveMode (MODE_Wrap ); break; //FIXME
537 case TY_CSI_PR('r', 7) : scr->restoreMode (MODE_Wrap ); break; //FIXME
538
539 case TY_CSI_PR('h', 8) : /* IGNORED: autorepeat on */ break; //VT100
540 case TY_CSI_PR('l', 8) : /* IGNORED: autorepeat off */ break; //VT100
541
542 case TY_CSI_PR('h', 9) : /* IGNORED: interlace */ break; //VT100
543 case TY_CSI_PR('l', 9) : /* IGNORED: interlace */ break; //VT100
544
545 case TY_CSI_PR('h', 25) : setMode (MODE_Cursor ); break; //VT100
546 case TY_CSI_PR('l', 25) : resetMode (MODE_Cursor ); break; //VT100
547
548 case TY_CSI_PR('h', 41) : /* IGNORED: obsolete more(1) fix */ break; //XTERM
549 case TY_CSI_PR('l', 41) : /* IGNORED: obsolete more(1) fix */ break; //XTERM
550 case TY_CSI_PR('s', 41) : /* IGNORED: obsolete more(1) fix */ break; //XTERM
551 case TY_CSI_PR('r', 41) : /* IGNORED: obsolete more(1) fix */ break; //XTERM
552
553 case TY_CSI_PR('h', 47) : setMode (MODE_AppScreen); break; //VT100
554 case TY_CSI_PR('l', 47) : resetMode (MODE_AppScreen); break; //VT100
555
556 case TY_CSI_PR('h', 1000) : setMode (MODE_Mouse1000); break; //XTERM
557 case TY_CSI_PR('l', 1000) : resetMode (MODE_Mouse1000); break; //XTERM
558 case TY_CSI_PR('s', 1000) : saveMode (MODE_Mouse1000); break; //XTERM
559 case TY_CSI_PR('r', 1000) : restoreMode (MODE_Mouse1000); break; //XTERM
560
561 case TY_CSI_PR('h', 1001) : /* IGNORED: hilite mouse tracking */ break; //XTERM
562 case TY_CSI_PR('l', 1001) : /* IGNORED: hilite mouse tracking */ break; //XTERM
563 case TY_CSI_PR('s', 1001) : /* IGNORED: hilite mouse tracking */ break; //XTERM
564 case TY_CSI_PR('r', 1001) : /* IGNORED: hilite mouse tracking */ break; //XTERM
565
566 case TY_CSI_PR('h', 1047) : setMode (MODE_AppScreen); break; //XTERM
567 case TY_CSI_PR('l', 1047) : resetMode (MODE_AppScreen); break; //XTERM
568
569 //FIXME: Unitoken: save translations
570 case TY_CSI_PR('h', 1048) : saveCursor ( ); break; //XTERM
571 case TY_CSI_PR('l', 1048) : restoreCursor ( ); break; //XTERM
572
573 //FIXME: every once new sequences like this pop up in xterm.
574 // Here's a guess of what they could mean.
575 case TY_CSI_PR('h', 1049) : setMode (MODE_AppScreen); break; //XTERM
576 case TY_CSI_PR('l', 1049) : resetMode (MODE_AppScreen); break; //XTERM
577
578 //FIXME: when changing between vt52 and ansi mode evtl do some resetting.
579 case TY_VT52__('A' ) : scr->cursorUp ( 1); break; //VT52
580 case TY_VT52__('B' ) : scr->cursorDown ( 1); break; //VT52
581 case TY_VT52__('C' ) : scr->cursorRight ( 1); break; //VT52
582 case TY_VT52__('D' ) : scr->cursorLeft ( 1); break; //VT52
583
584 case TY_VT52__('F' ) : setAndUseCharset (0, '0'); break; //VT52
585 case TY_VT52__('G' ) : setAndUseCharset (0, 'B'); break; //VT52
586
587 case TY_VT52__('H' ) : scr->setCursorYX (1,1 ); break; //VT52
588 case TY_VT52__('I' ) : scr->reverseIndex ( ); break; //VT52
589 case TY_VT52__('J' ) : scr->clearToEndOfScreen ( ); break; //VT52
590 case TY_VT52__('K' ) : scr->clearToEndOfLine ( ); break; //VT52
591 case TY_VT52__('Y' ) : scr->setCursorYX (p-31,q-31 ); break; //VT52
592 case TY_VT52__('Z' ) : reportTerminalType ( ); break; //VT52
593 case TY_VT52__('<' ) : setMode (MODE_Ansi ); break; //VT52
594 case TY_VT52__('=' ) : setMode (MODE_AppKeyPad); break; //VT52
595 case TY_VT52__('>' ) : resetMode (MODE_AppKeyPad); break; //VT52
596
597 default : ReportErrorToken(); break;
598 };
599}
600
601/* ------------------------------------------------------------------------- */
602/* */
603/* Terminal to Host protocol */
604/* */
605/* ------------------------------------------------------------------------- */
606
607/*
608 Outgoing bytes originate from several sources:
609
610 - Replies to Enquieries.
611 - Mouse Events
612 - Keyboard Events
613*/
614
615/*!
616*/
617
618void TEmuVt102::sendString(const char* s)
619{
620 emit sndBlock(s,strlen(s));
621}
622
623// Replies ----------------------------------------------------------------- --
624
625// This section copes with replies send as response to an enquiery control code.
626
627/*!
628*/
629
630void TEmuVt102::reportCursorPosition()
631{ char tmp[20];
632 sprintf(tmp,"\033[%d;%dR",scr->getCursorY()+1,scr->getCursorX()+1);
633 sendString(tmp);
634}
635
636/*
637 What follows here is rather obsolete and faked stuff.
638 The correspondent enquieries are neverthenless issued.
639*/
640
641/*!
642*/
643
644void TEmuVt102::reportTerminalType()
645{
646//FIXME: should change?
647 if (getMode(MODE_Ansi))
648// sendString("\033[?1;2c"); // I'm a VT100 with AP0 //FIXME: send only in response to ^[[0c
649 sendString("\033[>0;115;0c"); // I'm a VT220 //FIXME: send only in response to ^[[>c
650 else
651 sendString("\033/Z"); // I'm a VT52
652}
653
654void TEmuVt102::reportTerminalParms(int p)
655// DECREPTPARM
656{ char tmp[100];
657 sprintf(tmp,"\033[%d;1;1;112;112;1;0x",p); // not really true.
658 sendString(tmp);
659}
660
661/*!
662*/
663
664void TEmuVt102::reportStatus()
665{
666 sendString("\033[0n"); //VT100. Device status report. 0 = Ready.
667}
668
669/*!
670*/
671
672#define ANSWER_BACK "" // This is really obsolete VT100 stuff.
673
674void TEmuVt102::reportAnswerBack()
675{
676 sendString(ANSWER_BACK);
677}
678
679// Mouse Handling ---------------------------------------------------------- --
680
681/*!
682 Mouse clicks are possibly reported to the client
683 application if it has issued interest in them.
684 They are normally consumed by the widget for copy
685 and paste, but may be propagated from the widget
686 when gui->setMouseMarks is set via setMode(MODE_Mouse1000).
687
688 `x',`y' are 1-based.
689 `ev' (event) indicates the button pressed (0-2)
690 or a general mouse release (3).
691*/
692
693void TEmuVt102::onMouse( int cb, int cx, int cy )
694{ char tmp[20];
695 if (!connected) return;
696 sprintf(tmp,"\033[M%c%c%c",cb+040,cx+040,cy+040);
697 sendString(tmp);
698}
699
700// Keyboard Handling ------------------------------------------------------- --
701
702#define encodeMode(M,B) BITS(B,getMode(M))
703#define encodeStat(M,B) BITS(B,((ev->state() & (M)) == (M)))
704
705/*
706 Keyboard event handling has been simplified somewhat by pushing
707 the complications towards a configuration file [see KeyTrans class].
708*/
709
710void TEmuVt102::onKeyPress( QKeyEvent* ev )
711{
712 if (!connected) return; // someone else gets the keys
713
714//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);
715
716 // revert to non-history when typing
717 if (scr->getHistCursor() != scr->getHistLines());
718 scr->setHistCursor(scr->getHistLines());
719
720 // lookup in keyboard translation table ...
721 int cmd; const char* txt; int len;
722 if (keytrans->findEntry(ev->key(), encodeMode(MODE_NewLine , BITS_NewLine ) + // OLD,
723 encodeMode(MODE_Ansi , BITS_Ansi ) + // OBSOLETE,
724 encodeMode(MODE_AppCuKeys, BITS_AppCuKeys ) + // VT100 stuff
725 encodeStat(ControlButton , BITS_Control ) +
726 encodeStat(ShiftButton , BITS_Shift ) +
727 encodeStat(AltButton , BITS_Alt ),
728 &cmd, &txt, &len ))
729//printf("cmd: %d, %s, %d\n",cmd,txt,len);
730 switch(cmd) // ... and execute if found.
731 {
732 case CMD_emitSelection : gui->emitSelection(); return;
733 case CMD_scrollPageUp : gui->doScroll(-gui->Lines()/2); return;
734 case CMD_scrollPageDown : gui->doScroll(+gui->Lines()/2); return;
735 case CMD_scrollLineUp : gui->doScroll(-1 ); return;
736 case CMD_scrollLineDown : gui->doScroll(+1 ); return;
737 case CMD_send : emit sndBlock(txt,len); return;
738 case CMD_prevSession : emit prevSession(); return;
739 case CMD_nextSession : emit nextSession(); return;
740 }
741
742 // fall back handling
743 if (!ev->text().isEmpty())
744 {
745 if (ev->state() & AltButton) sendString("\033"); // ESC, this is the ALT prefix
746 QCString s = codec->fromUnicode(ev->text()); // encode for application
747 emit sndBlock(s.data(),s.length()); // we may well have s.length() > 1
748 return;
749 }
750}
751
752/* ------------------------------------------------------------------------- */
753/* */
754/* VT100 Charsets */
755/* */
756/* ------------------------------------------------------------------------- */
757
758// Character Set Conversion ------------------------------------------------ --
759
760/*
761 The processing contains a VT100 specific code translation layer.
762 It's still in use and mainly responsible for the line drawing graphics.
763
764 These and some other glyphs are assigned to codes (0x5f-0xfe)
765 normally occupied by the latin letters. Since this codes also
766 appear within control sequences, the extra code conversion
767 does not permute with the tokenizer and is placed behind it
768 in the pipeline. It only applies to tokens, which represent
769 plain characters.
770
771 This conversion it eventually continued in TEWidget.C, since
772 it might involve VT100 enhanced fonts, which have these
773 particular glyphs allocated in (0x00-0x1f) in their code page.
774*/
775
776#define CHARSET charset[scr==screen[1]]
777
778// Apply current character map.
779
780unsigned short TEmuVt102::applyCharset(unsigned short c)
781{
782 if (CHARSET.graphic && 0x5f <= c && c <= 0x7e) return vt100_graphics[c-0x5f];
783 if (CHARSET.pound && c == '#' ) return 0xa3; //This mode is obsolete
784 return c;
785}
786
787/*
788 "Charset" related part of the emulation state.
789 This configures the VT100 charset filter.
790
791 While most operation work on the current screen,
792 the following two are different.
793*/
794
795void TEmuVt102::resetCharset(int scrno)
796{
797 charset[scrno].cu_cs = 0;
798 strncpy(charset[scrno].charset,"BBBB",4);
799 charset[scrno].sa_graphic = FALSE;
800 charset[scrno].sa_pound = FALSE;
801 charset[scrno].graphic = FALSE;
802 charset[scrno].pound = FALSE;
803}
804
805/*!
806*/
807
808void TEmuVt102::setCharset(int n, int cs) // on both screens.
809{
810 charset[0].charset[n&3] = cs; useCharset(charset[0].cu_cs);
811 charset[1].charset[n&3] = cs; useCharset(charset[1].cu_cs);
812}
813
814/*!
815*/
816
817void TEmuVt102::setAndUseCharset(int n, int cs)
818{
819 CHARSET.charset[n&3] = cs;
820 useCharset(n&3);
821}
822
823/*!
824*/
825
826void TEmuVt102::useCharset(int n)
827{
828 CHARSET.cu_cs = n&3;
829 CHARSET.graphic = (CHARSET.charset[n&3] == '0');
830 CHARSET.pound = (CHARSET.charset[n&3] == 'A'); //This mode is obsolete
831}
832
833/*! Save the cursor position and the rendition attribute settings. */
834
835void TEmuVt102::saveCursor()
836{
837 CHARSET.sa_graphic = CHARSET.graphic;
838 CHARSET.sa_pound = CHARSET.pound; //This mode is obsolete
839 // we are not clear about these
840 //sa_charset = charsets[cScreen->charset];
841 //sa_charset_num = cScreen->charset;
842 scr->saveCursor();
843}
844
845/*! Restore the cursor position and the rendition attribute settings. */
846
847void TEmuVt102::restoreCursor()
848{
849 CHARSET.graphic = CHARSET.sa_graphic;
850 CHARSET.pound = CHARSET.sa_pound; //This mode is obsolete
851 scr->restoreCursor();
852}
853
854/* ------------------------------------------------------------------------- */
855/* */
856/* Mode Operations */
857/* */
858/* ------------------------------------------------------------------------- */
859
860/*
861 Some of the emulations state is either added to the state of the screens.
862
863 This causes some scoping problems, since different emulations choose to
864 located the mode either to the current screen or to both.
865
866 For strange reasons, the extend of the rendition attributes ranges over
867 all screens and not over the actual screen.
868
869 We decided on the precise precise extend, somehow.
870*/
871
872// "Mode" related part of the state. These are all booleans.
873
874void TEmuVt102::resetModes()
875{
876 resetMode(MODE_Mouse1000); saveMode(MODE_Mouse1000);
877 resetMode(MODE_AppScreen); saveMode(MODE_AppScreen);
878 // here come obsolete modes
879 resetMode(MODE_AppCuKeys); saveMode(MODE_AppCuKeys);
880 resetMode(MODE_NewLine );
881 setMode(MODE_Ansi );
882}
883
884void TEmuVt102::setMode(int m)
885{
886 currParm.mode[m] = TRUE;
887 switch (m)
888 {
889 case MODE_Mouse1000 : gui->setMouseMarks(FALSE);
890 break;
891 case MODE_AppScreen : screen[1]->clearSelection();
892 screen[1]->clearEntireScreen();
893 setScreen(1);
894 break;
895 }
896 if (m < MODES_SCREEN || m == MODE_NewLine)
897 {
898 screen[0]->setMode(m);
899 screen[1]->setMode(m);
900 }
901}
902
903void TEmuVt102::resetMode(int m)
904{
905 currParm.mode[m] = FALSE;
906 switch (m)
907 {
908 case MODE_Mouse1000 : gui->setMouseMarks(TRUE);
909 break;
910 case MODE_AppScreen : screen[0]->clearSelection();
911 setScreen(0);
912 break;
913 }
914 if (m < MODES_SCREEN || m == MODE_NewLine)
915 {
916 screen[0]->resetMode(m);
917 screen[1]->resetMode(m);
918 }
919}
920
921void TEmuVt102::saveMode(int m)
922{
923 saveParm.mode[m] = currParm.mode[m];
924}
925
926void TEmuVt102::restoreMode(int m)
927{
928 if(saveParm.mode[m]) setMode(m); else resetMode(m);
929}
930
931BOOL TEmuVt102::getMode(int m)
932{
933 return currParm.mode[m];
934}
935
936void TEmuVt102::setConnect(bool c)
937{
938 TEmulation::setConnect(c);
939 if (c)
940 { // refresh mouse mode
941 if (getMode(MODE_Mouse1000))
942 setMode(MODE_Mouse1000);
943 else
944 resetMode(MODE_Mouse1000);
945 }
946}
947
948/* ------------------------------------------------------------------------- */
949/* */
950/* Diagnostic */
951/* */
952/* ------------------------------------------------------------------------- */
953
954/*! shows the contents of the scan buffer.
955
956 This functions is used for diagnostics. It is called by \e ReportErrorToken
957 to inform about strings that cannot be decoded or handled by the emulation.
958
959 \sa ReportErrorToken
960*/
961
962/*!
963*/
964
965static void hexdump(int* s, int len)
966{ int i;
967 for (i = 0; i < len; i++)
968 {
969 if (s[i] == '\\')
970 printf("\\\\");
971 else
972 if ((s[i]) > 32 && s[i] < 127)
973 printf("%c",s[i]);
974 else
975 printf("\\%04x(hex)",s[i]);
976 }
977}
978
979void TEmuVt102::scan_buffer_report()
980{
981 if (ppos == 0 || ppos == 1 && (pbuf[0] & 0xff) >= 32) return;
982 printf("token: "); hexdump(pbuf,ppos); printf("\n");
983}
984
985/*!
986*/
987
988void TEmuVt102::ReportErrorToken()
989{
990 printf("undecodable "); scan_buffer_report();
991}
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 @@
1/* -------------------------------------------------------------------------- */
2/* */
3/* [TEmuVt102.h] X Terminal Emulation */
4/* */
5/* -------------------------------------------------------------------------- */
6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */
9/* This file is part of Konsole - an X terminal for KDE */
10/* */
11/* -------------------------------------------------------------------------- */
12 /* */
13/* Ported Konsole to Qt/Embedded */
14 /* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16 /* */
17/* -------------------------------------------------------------------------- */
18
19#ifndef VT102EMU_H
20#define VT102EMU_H
21
22#include "TEWidget.h"
23#include "TEScreen.h"
24#include "TEmulation.h"
25#include <qtimer.h>
26#include <stdio.h>
27
28//
29
30#define MODE_AppScreen (MODES_SCREEN+0)
31#define MODE_AppCuKeys (MODES_SCREEN+1)
32#define MODE_AppKeyPad (MODES_SCREEN+2)
33#define MODE_Mouse1000 (MODES_SCREEN+3)
34#define MODE_Ansi (MODES_SCREEN+4)
35#define MODE_total (MODES_SCREEN+5)
36
37struct DECpar
38{
39 BOOL mode[MODE_total];
40};
41
42struct CharCodes
43{
44 // coding info
45 char charset[4]; //
46 int cu_cs; // actual charset.
47 bool graphic; // Some VT100 tricks
48 bool pound ; // Some VT100 tricks
49 bool sa_graphic; // saved graphic
50 bool sa_pound; // saved pound
51};
52
53class TEmuVt102 : public TEmulation
54{ Q_OBJECT
55
56public:
57
58 TEmuVt102(TEWidget* gui);
59 ~TEmuVt102();
60
61public slots: // signals incoming from TEWidget
62
63 void onKeyPress(QKeyEvent*);
64 void onMouse(int cb, int cx, int cy);
65
66signals:
67
68 void changeTitle(int,const QString&);
69 void prevSession();
70 void nextSession();
71
72public:
73
74 void reset();
75
76 void onRcvChar(int cc);
77 void sendString(const char *);
78
79public:
80
81 BOOL getMode (int m);
82
83 void setMode (int m);
84 void resetMode (int m);
85 void saveMode (int m);
86 void restoreMode(int m);
87 void resetModes();
88
89 void setConnect(bool r);
90
91private:
92
93 void resetToken();
94#define MAXPBUF 80
95 void pushToToken(int cc);
96 int pbuf[MAXPBUF]; //FIXME: overflow?
97 int ppos;
98#define MAXARGS 15
99 void addDigit(int dig);
100 void addArgument();
101 int argv[MAXARGS];
102 int argc;
103 void initTokenizer();
104 int tbl[256];
105
106 void scan_buffer_report(); //FIXME: rename
107 void ReportErrorToken(); //FIXME: rename
108
109 void tau(int code, int p, int q);
110 void XtermHack();
111
112 //
113
114 void reportTerminalType();
115 void reportStatus();
116 void reportAnswerBack();
117 void reportCursorPosition();
118 void reportTerminalParms(int p);
119
120protected:
121
122 unsigned short applyCharset(unsigned short c);
123 void setCharset(int n, int cs);
124 void useCharset(int n);
125 void setAndUseCharset(int n, int cs);
126 void saveCursor();
127 void restoreCursor();
128 void resetCharset(int scrno);
129 CharCodes charset[2];
130
131 DECpar currParm;
132 DECpar saveParm;
133};
134
135#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 @@
1/* -------------------------------------------------------------------------- */
2/* */
3/* [TEmulation.cpp] Terminal Emulation Decoder */
4/* */
5/* -------------------------------------------------------------------------- */
6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */
9/* This file is part of Konsole - an X terminal for KDE */
10/* */
11/* -------------------------------------------------------------------------- */
12 /* */
13/* Ported Konsole to Qt/Embedded */
14 /* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16 /* */
17/* -------------------------------------------------------------------------- */
18
19/*! \class TEmulation
20
21 \brief Mediator between TEWidget and TEScreen.
22
23 This class is responsible to scan the escapes sequences of the terminal
24 emulation and to map it to their corresponding semantic complements.
25 Thus this module knows mainly about decoding escapes sequences and
26 is a stateless device w.r.t. the semantics.
27
28 It is also responsible to refresh the TEWidget by certain rules.
29
30 \sa TEWidget \sa TEScreen
31
32 \par A note on refreshing
33
34 Although the modifications to the current screen image could immediately
35 be propagated via `TEWidget' to the graphical surface, we have chosen
36 another way here.
37
38 The reason for doing so is twofold.
39
40 First, experiments show that directly displaying the operation results
41 in slowing down the overall performance of emulations. Displaying
42 individual characters using X11 creates a lot of overhead.
43
44 Second, by using the following refreshing method, the screen operations
45 can be completely separated from the displaying. This greatly simplifies
46 the programmer's task of coding and maintaining the screen operations,
47 since one need not worry about differential modifications on the
48 display affecting the operation of concern.
49
50 We use a refreshing algorithm here that has been adoped from rxvt/kvt.
51
52 By this, refreshing is driven by a timer, which is (re)started whenever
53 a new bunch of data to be interpreted by the emulation arives at `onRcvBlock'.
54 As soon as no more data arrive for `BULK_TIMEOUT' milliseconds, we trigger
55 refresh. This rule suits both bulk display operation as done by curses as
56 well as individual characters typed.
57 (BULK_TIMEOUT < 1000 / max characters received from keyboard per second).
58
59 Additionally, we trigger refreshing by newlines comming in to make visual
60 snapshots of lists as produced by `cat', `ls' and likely programs, thereby
61 producing the illusion of a permanent and immediate display operation.
62
63 As a sort of catch-all needed for cases where none of the above
64 conditions catch, the screen refresh is also triggered by a count
65 of incoming bulks (`bulk_incnt').
66*/
67
68/* FIXME
69 - evtl. the bulk operations could be made more transparent.
70*/
71
72#include "TEmulation.h"
73#include "TEWidget.h"
74#include "TEScreen.h"
75#include <stdio.h>
76#include <stdlib.h>
77#include <unistd.h>
78#include <qkeycode.h>
79
80
81/* ------------------------------------------------------------------------- */
82/* */
83/* TEmulation */
84/* */
85/* ------------------------------------------------------------------------- */
86
87#define CNTL(c) ((c)-'@')
88
89/*!
90*/
91
92TEmulation::TEmulation(TEWidget* gui)
93: decoder((QTextDecoder*)NULL)
94{
95 this->gui = gui;
96
97 screen[0] = new TEScreen(gui->Lines(),gui->Columns());
98 screen[1] = new TEScreen(gui->Lines(),gui->Columns());
99 scr = screen[0];
100
101 bulk_nlcnt = 0; // reset bulk newline counter
102 bulk_incnt = 0; // reset bulk counter
103 connected = FALSE;
104
105 QObject::connect(&bulk_timer, SIGNAL(timeout()), this, SLOT(showBulk()) );
106 QObject::connect(gui,SIGNAL(changedImageSizeSignal(int,int)),
107 this,SLOT(onImageSizeChange(int,int)));
108 QObject::connect(gui,SIGNAL(changedHistoryCursor(int)),
109 this,SLOT(onHistoryCursorChange(int)));
110 QObject::connect(gui,SIGNAL(keyPressedSignal(QKeyEvent*)),
111 this,SLOT(onKeyPress(QKeyEvent*)));
112 QObject::connect(gui,SIGNAL(beginSelectionSignal(const int,const int)),
113 this,SLOT(onSelectionBegin(const int,const int)) );
114 QObject::connect(gui,SIGNAL(extendSelectionSignal(const int,const int)),
115 this,SLOT(onSelectionExtend(const int,const int)) );
116 QObject::connect(gui,SIGNAL(endSelectionSignal(const BOOL)),
117 this,SLOT(setSelection(const BOOL)) );
118 QObject::connect(gui,SIGNAL(clearSelectionSignal()),
119 this,SLOT(clearSelection()) );
120}
121
122/*!
123*/
124
125TEmulation::~TEmulation()
126{
127 delete screen[0];
128 delete screen[1];
129 bulk_timer.stop();
130}
131
132/*! change between primary and alternate screen
133*/
134
135void TEmulation::setScreen(int n)
136{
137 scr = screen[n&1];
138}
139
140void TEmulation::setHistory(bool on)
141{
142 screen[0]->setScroll(on);
143 if (!connected) return;
144 showBulk();
145}
146
147bool TEmulation::history()
148{
149 return screen[0]->hasScroll();
150}
151
152void TEmulation::setCodec(int c)
153{
154 //FIXME: check whether we have to free codec
155 codec = c ? QTextCodec::codecForName("utf8")
156 : QTextCodec::codecForLocale();
157 if (decoder) delete decoder;
158 decoder = codec->makeDecoder();
159}
160
161void TEmulation::setKeytrans(int no)
162{
163 keytrans = KeyTrans::find(no);
164}
165
166void TEmulation::setKeytrans(const char * no)
167{
168 keytrans = KeyTrans::find(no);
169}
170
171// Interpreting Codes ---------------------------------------------------------
172
173/*
174 This section deals with decoding the incoming character stream.
175 Decoding means here, that the stream is first seperated into `tokens'
176 which are then mapped to a `meaning' provided as operations by the
177 `Screen' class.
178*/
179
180/*!
181*/
182
183void TEmulation::onRcvChar(int c)
184// process application unicode input to terminal
185// this is a trivial scanner
186{
187 c &= 0xff;
188 switch (c)
189 {
190 case '\b' : scr->BackSpace(); break;
191 case '\t' : scr->Tabulate(); break;
192 case '\n' : scr->NewLine(); break;
193 case '\r' : scr->Return(); break;
194 case 0x07 : gui->Bell(); break;
195 default : scr->ShowCharacter(c); break;
196 };
197}
198
199/* ------------------------------------------------------------------------- */
200/* */
201/* Keyboard Handling */
202/* */
203/* ------------------------------------------------------------------------- */
204
205/*!
206*/
207
208void TEmulation::onKeyPress( QKeyEvent* ev )
209{
210 if (!connected) return; // someone else gets the keys
211 if (scr->getHistCursor() != scr->getHistLines());
212 scr->setHistCursor(scr->getHistLines());
213 if (!ev->text().isEmpty())
214 { // A block of text
215 // Note that the text is proper unicode.
216 // We should do a conversion here, but since this
217 // routine will never be used, we simply emit plain ascii.
218 emit sndBlock(ev->text().ascii(),ev->text().length());
219 }
220 else if (ev->ascii()>0)
221 { unsigned char c[1];
222 c[0] = ev->ascii();
223 emit sndBlock((char*)c,1);
224 }
225}
226
227// Unblocking, Byte to Unicode translation --------------------------------- --
228
229/*
230 We are doing code conversion from locale to unicode first.
231*/
232
233void TEmulation::onRcvBlock(const char *s, int len)
234{
235 bulkStart();
236 bulk_incnt += 1;
237 for (int i = 0; i < len; i++)
238 {
239 QString result = decoder->toUnicode(&s[i],1);
240 int reslen = result.length();
241 for (int j = 0; j < reslen; j++)
242 onRcvChar(result[j].unicode());
243 if (s[i] == '\n') bulkNewline();
244 }
245 bulkEnd();
246}
247
248// Selection --------------------------------------------------------------- --
249
250void TEmulation::onSelectionBegin(const int x, const int y) {
251 if (!connected) return;
252 scr->setSelBeginXY(x,y);
253 showBulk();
254}
255
256void TEmulation::onSelectionExtend(const int x, const int y) {
257 if (!connected) return;
258 scr->setSelExtentXY(x,y);
259 showBulk();
260}
261
262void TEmulation::setSelection(const BOOL preserve_line_breaks) {
263 if (!connected) return;
264 QString t = scr->getSelText(preserve_line_breaks);
265 if (!t.isNull()) gui->setSelection(t);
266}
267
268void TEmulation::clearSelection() {
269 if (!connected) return;
270 scr->clearSelection();
271 showBulk();
272}
273
274// Refreshing -------------------------------------------------------------- --
275
276#define BULK_TIMEOUT 20
277
278/*!
279 called when \n comes in. Evtl. triggers showBulk at endBulk
280*/
281
282void TEmulation::bulkNewline()
283{
284 bulk_nlcnt += 1;
285 bulk_incnt = 0; // reset bulk counter since `nl' rule applies
286}
287
288/*!
289*/
290
291void TEmulation::showBulk()
292{
293 bulk_nlcnt = 0; // reset bulk newline counter
294 bulk_incnt = 0; // reset bulk counter
295 if (connected)
296 {
297 ca* image = scr->getCookedImage(); // get the image
298 gui->setImage(image,
299 scr->getLines(),
300 scr->getColumns()); // actual refresh
301 free(image);
302 //FIXME: check that we do not trigger other draw event here.
303 gui->setScroll(scr->getHistCursor(),scr->getHistLines());
304 }
305}
306
307void TEmulation::bulkStart()
308{
309 if (bulk_timer.isActive()) bulk_timer.stop();
310}
311
312void TEmulation::bulkEnd()
313{
314 if ( bulk_nlcnt > gui->Lines() || bulk_incnt > 20 )
315 showBulk(); // resets bulk_??cnt to 0, too.
316 else
317 bulk_timer.start(BULK_TIMEOUT,TRUE);
318}
319
320void TEmulation::setConnect(bool c)
321{
322 connected = c;
323 if ( connected)
324 {
325 onImageSizeChange(gui->Lines(), gui->Columns());
326 showBulk();
327 }
328 else
329 {
330 scr->clearSelection();
331 }
332}
333
334// ---------------------------------------------------------------------------
335
336/*! triggered by image size change of the TEWidget `gui'.
337
338 This event is simply propagated to the attached screens
339 and to the related serial line.
340*/
341
342void TEmulation::onImageSizeChange(int lines, int columns)
343{
344 if (!connected) return;
345 screen[0]->resizeImage(lines,columns);
346 screen[1]->resizeImage(lines,columns);
347 showBulk();
348 emit ImageSizeChanged(lines,columns); // propagate event to serial line
349}
350
351void TEmulation::onHistoryCursorChange(int cursor)
352{
353 if (!connected) return;
354 scr->setHistCursor(cursor);
355 showBulk();
356}
357
358void TEmulation::setColumns(int columns)
359{
360 //FIXME: this goes strange ways.
361 // Can we put this straight or explain it at least?
362 emit changeColumns(columns);
363}
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 @@
1/* -------------------------------------------------------------------------- */
2/* */
3/* [emulation.h] Fundamental Terminal Emulation */
4/* */
5/* -------------------------------------------------------------------------- */
6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */
9/* This file is part of Konsole - an X terminal for KDE */
10/* */
11/* -------------------------------------------------------------------------- */
12 /* */
13/* Ported Konsole to Qt/Embedded */
14 /* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16 /* */
17/* -------------------------------------------------------------------------- */
18
19#ifndef EMULATION_H
20#define EMULATION_H
21
22#include "TEWidget.h"
23#include "TEScreen.h"
24#include <qtimer.h>
25#include <stdio.h>
26#include <qtextcodec.h>
27#include "keytrans.h"
28
29class TEmulation : public QObject
30{ Q_OBJECT
31
32public:
33
34 TEmulation(TEWidget* gui);
35 ~TEmulation();
36
37public:
38 virtual void setHistory(bool on);
39 virtual bool history();
40
41public slots: // signals incoming from TEWidget
42
43 virtual void onImageSizeChange(int lines, int columns);
44 virtual void onHistoryCursorChange(int cursor);
45 virtual void onKeyPress(QKeyEvent*);
46
47 virtual void clearSelection();
48 virtual void onSelectionBegin(const int x, const int y);
49 virtual void onSelectionExtend(const int x, const int y);
50 virtual void setSelection(const BOOL preserve_line_breaks);
51
52public slots: // signals incoming from data source
53
54 void onRcvBlock(const char* txt,int len);
55
56signals:
57
58 void sndBlock(const char* txt,int len);
59 void ImageSizeChanged(int lines, int columns);
60 void changeColumns(int columns);
61 void changeTitle(int arg, const char* str);
62
63public:
64
65 virtual void onRcvChar(int);
66
67 virtual void setMode (int) = 0;
68 virtual void resetMode(int) = 0;
69
70 virtual void sendString(const char*) = 0;
71
72 virtual void setConnect(bool r);
73 void setColumns(int columns);
74
75 void setKeytrans(int no);
76 void setKeytrans(const char * no);
77
78protected:
79
80 TEWidget* gui;
81 TEScreen* scr; // referes to one `screen'
82 TEScreen* screen[2]; // 0 = primary, 1 = alternate
83 void setScreen(int n); // set `scr' to `screen[n]'
84
85 bool connected; // communicate with widget
86
87 void setCodec(int c); // codec number, 0 = locale, 1=utf8
88
89 QTextCodec* codec;
90 QTextCodec* localeCodec;
91 QTextDecoder* decoder;
92
93 KeyTrans* keytrans;
94
95// refreshing related material.
96// this is localized in the class.
97private slots: // triggered by timer
98
99 void showBulk();
100
101private:
102
103 void bulkNewline();
104 void bulkStart();
105 void bulkEnd();
106
107private:
108
109 QTimer bulk_timer;
110 int bulk_nlcnt; // bulk newline counter
111 char* SelectedText;
112 int bulk_incnt; // bulk counter
113
114
115};
116
117#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 @@
1 /* generated by '../tests/quote ../other/default.Keytab' */
2
3 "# [default.Keytab] Buildin Keyboard Table\n"
4 "\n"
5 "# --------------------------------------------------------------\n"
6 "#\n"
7 "# This file in included only for reference purposes. \n"
8 "#\n"
9 "# Modifying it does not have any effect (unless you\n"
10 "# derive the default.keytab.h and recompile konsole).\n"
11 "#\n"
12 "# To customize your keyboard, copy this file to something\n"
13 "# ending with .keytab and change it to meet you needs.\n"
14 "#\n"
15 "# --------------------------------------------------------------\n"
16 "\n"
17 "keyboard \"xterm (default)\"\n"
18 "\n"
19 "# --------------------------------------------------------------\n"
20 "#\n"
21 "# The syntax of each entry has the form\n"
22 "#\n"
23 "# \"key\" Keyname { (\"+\"|\"-\") Modename } \":\" (String|Operation)\n"
24 "#\n"
25 "# Keynames are those defined in <qnamespace.h>\n"
26 "# with the \"Qt::Key_\" prefix removed.\n"
27 "#\n"
28 "# Mode names are: Shift, Alt, Control.\n"
29 "#\n"
30 "# If the key is not found here, the text of the\n"
31 "# key event as provided by QT is emitted, possibly\n"
32 "# preceeded by ESC if the Alt key is pressed.\n"
33 "#\n"
34 "# --------------------------------------------------------------\n"
35 "#\n"
36 "# Note that this particular table is a \"risc\" version made to\n"
37 "# ease customization without bothering with obsolete details.\n"
38 "# See VT100.keytab for the more hairy stuff.\n"
39 "#\n"
40 "# --------------------------------------------------------------\n"
41 "\n"
42 "# common keys\n"
43 "\n"
44 "key Escape : \"\\E\"\n"
45 "key Tab : \"\\t\"\n"
46 "\n"
47 "key Return-Alt : \"\\r\"\n"
48 "key Return+Alt : \"\\E\\r\"\n"
49 "\n"
50 "# Backspace and Delete codes are preserving CTRL-H.\n"
51 "\n"
52 "key Backspace : \"\\x7f\"\n"
53 "\n"
54 "# cursor keys\n"
55 "\n"
56 "key Up -Shift : \"\\EOA\"\n"
57 "key Down -Shift : \"\\EOB\"\n"
58 "key Right -Shift : \"\\EOC\"\n"
59 "key Left -Shift : \"\\EOD\"\n"
60 "\n"
61 "# other grey PC keys\n"
62 "\n"
63 "key Enter : \"\\r\"\n"
64 "\n"
65 "key Home : \"\\E[1~\"\n"
66 "key Insert-Shift : \"\\E[2~\"\n"
67 "key Delete : \"\\E[3~\"\n"
68 "key End : \"\\E[4~\"\n"
69 "key Prior -Shift : \"\\E[5~\"\n"
70 "key Next -Shift : \"\\E[6~\"\n"
71 "\n"
72 "# function keys\n"
73 "\n"
74 "key F1 : \"\\E[11~\"\n"
75 "key F2 : \"\\E[12~\"\n"
76 "key F3 : \"\\E[13~\"\n"
77 "key F4 : \"\\E[14~\"\n"
78 "key F5 : \"\\E[15~\"\n"
79 "key F6 : \"\\E[17~\"\n"
80 "key F7 : \"\\E[18~\"\n"
81 "key F8 : \"\\E[19~\"\n"
82 "key F9 : \"\\E[20~\"\n"
83 "key F10 : \"\\E[21~\"\n"
84 "key F11 : \"\\E[23~\"\n"
85 "key F12 : \"\\E[24~\"\n"
86 "\n"
87 "# Work around dead keys\n"
88 "\n"
89 "key Space +Control : \"\\x00\"\n"
90 "\n"
91 "# Some keys are used by konsole to cause operations.\n"
92 "# The scroll* operations refer to the history buffer.\n"
93 "\n"
94 "key Left +Shift : prevSession\n"
95 "key Right +Shift : nextSession\n"
96 "key Up +Shift : scrollLineUp\n"
97 "key Prior +Shift : scrollPageUp\n"
98 "key Down +Shift : scrollLineDown\n"
99 "key Next +Shift : scrollPageDown\n"
100 "key Insert+Shift : emitSelection\n"
101 "\n"
102 "# keypad characters are not offered differently by Qt.\n"
103 ""
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 @@
1 TEMPLATE= app
2
3 CONFIG += qt warn_on release
4
5 DESTDIR = $(QPEDIR)/bin
6
7 HEADERS = TEWidget.h \
8 TEScreen.h \
9 TECommon.h \
10 TEHistory.h \
11 TEmulation.h \
12 TEmuVt102.h \
13 session.h \
14 keytrans.h \
15 konsole.h \
16 MyPty.h
17
18 SOURCES = TEScreen.cpp \
19 TEWidget.cpp \
20 TEHistory.cpp \
21 TEmulation.cpp \
22 TEmuVt102.cpp \
23 session.cpp \
24 keytrans.cpp \
25 konsole.cpp \
26 main.cpp \
27 MyPty.cpp
28
29 TARGET = embeddedkonsole
30
31INCLUDEPATH += $(QPEDIR)/include
32
33 DEPENDPATH+= $(QPEDIR)/include
34
35LIBS += -lqpe
36
37 REQUIRES= embeddedkonsole
38
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 @@
1/* -------------------------------------------------------------------------- */
2/* */
3/* [keytrans.C] Keyboard Translation */
4/* */
5/* -------------------------------------------------------------------------- */
6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */
9/* This file is part of Konsole - an X terminal for KDE */
10/* */
11/* -------------------------------------------------------------------------- */
12 /* */
13/* Ported Konsole to Qt/Embedded */
14 /* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16 /* */
17/* -------------------------------------------------------------------------- */
18
19/*
20 The keyboard translation table allows to configure konsoles behavior
21 on key strokes.
22
23 FIXME: some bug crept in, disallowing '\0' to be emitted.
24*/
25
26#include "keytrans.h"
27
28#include <qpe/qpeapplication.h>
29
30#include <qnamespace.h>
31#include <qbuffer.h>
32#include <qobject.h>
33#include <qdict.h>
34#include <qintdict.h>
35#include <qfile.h>
36#include <qglobal.h>
37#include <qdir.h>
38
39//#include <kstddirs.h>
40//nclude <klocale.h>
41
42#include <stdio.h>
43
44
45#undef USE_APPDATA_DIR
46
47
48#define HERE printf("%s(%d): here\n",__FILE__,__LINE__)
49
50/* KeyEntry
51
52 instances represent the individual assignments
53*/
54
55KeyTrans::KeyEntry::KeyEntry(int _ref, int _key, int _bits, int _mask, int _cmd, QString _txt)
56: ref(_ref), key(_key), bits(_bits), mask(_mask), cmd(_cmd), txt(_txt)
57{
58}
59
60KeyTrans::KeyEntry::~KeyEntry()
61{
62}
63
64bool KeyTrans::KeyEntry::matches(int _key, int _bits, int _mask)
65{ int m = mask & _mask;
66 return _key == key && (bits & m) == (_bits & m);
67}
68
69QString KeyTrans::KeyEntry::text()
70{
71 return txt;
72}
73
74/* KeyTrans
75
76 combines the individual assignments to a proper map
77 Takes part in a collection themself.
78*/
79
80KeyTrans::KeyTrans()
81{
82 path = "";
83 numb = 0;
84}
85
86KeyTrans::~KeyTrans()
87{
88}
89
90KeyTrans::KeyEntry* KeyTrans::addEntry(int ref, int key, int bits, int mask, int cmd, QString txt)
91// returns conflicting entry
92{
93 for (QListIterator<KeyEntry> it(table); it.current(); ++it)
94 {
95 if (it.current()->matches(key,bits,mask))
96 {
97 return it.current();
98 }
99 }
100 table.append(new KeyEntry(ref,key,bits,mask,cmd,txt));
101 return (KeyEntry*)NULL;
102}
103
104bool KeyTrans::findEntry(int key, int bits, int* cmd, const char** txt, int* len)
105{
106 for (QListIterator<KeyEntry> it(table); it.current(); ++it)
107 if (it.current()->matches(key,bits,0xffff))
108 {
109 *cmd = it.current()->cmd;
110 *txt = it.current()->txt.ascii();
111 *len = it.current()->txt.length();
112 return TRUE;
113 }
114 return FALSE;
115}
116
117/* ------------------------------------------------------------------------- */
118/* */
119/* Scanner for keyboard configuration */
120/* */
121/* ------------------------------------------------------------------------- */
122
123// regular tokenizer
124/* Tokens
125 - Spaces
126 - Name (A-Za-z0-9)+
127 - String
128 - Opr on of +-:
129*/
130
131#define SYMName 0
132#define SYMString 1
133#define SYMEol 2
134#define SYMEof 3
135#define SYMOpr 4
136#define SYMError 5
137
138#define inRange(L,X,H) ((L <= X) && (X <= H))
139#define isNibble(X) (inRange('A',X,'F')||inRange('a',X,'f')||inRange('0',X,'9'))
140#define convNibble(X) (inRange('0',X,'9')?X-'0':X+10-(inRange('A',X,'F')?'A':'a'))
141
142class KeytabReader
143{
144public:
145 KeytabReader(QString p, QIODevice &d);
146public:
147 void getCc();
148 void getSymbol();
149 void parseTo(KeyTrans* kt);
150 void ReportError(const char* msg);
151 void ReportToken(); // diagnostic
152private:
153 int sym;
154 QString res;
155 int len;
156 int slinno;
157 int scolno;
158private:
159 int cc;
160 int linno;
161 int colno;
162 QIODevice* buf;
163 QString path;
164};
165
166
167KeytabReader::KeytabReader(QString p, QIODevice &d)
168{
169 path = p;
170 buf = &d;
171 cc = 0;
172}
173
174void KeytabReader::getCc()
175{
176 if (cc == '\n') { linno += 1; colno = 0; }
177 if (cc < 0) return;
178 cc = buf->getch();
179 colno += 1;
180}
181
182void KeytabReader::getSymbol()
183{
184 res = ""; len = 0; sym = SYMError;
185 while (cc == ' ') getCc(); // skip spaces
186 if (cc == '#') // skip comment
187 {
188 while (cc != '\n' && cc > 0) getCc();
189 }
190 slinno = linno;
191 scolno = colno;
192 if (cc <= 0)
193 {
194 sym = SYMEof; return; // eos
195 }
196 if (cc == '\n')
197 {
198 getCc();
199 sym = SYMEol; return; // eol
200 }
201 if (inRange('A',cc,'Z')||inRange('a',cc,'z')||inRange('0',cc,'9'))
202 {
203 while (inRange('A',cc,'Z') || inRange('a',cc,'z') || inRange('0',cc,'9'))
204 {
205 res = res + (char)cc;
206 getCc();
207 }
208 sym = SYMName;
209 return;
210 }
211 if (strchr("+-:",cc))
212 {
213 res = "";
214 res = res + (char)cc;
215 getCc();
216 sym = SYMOpr; return;
217 }
218 if (cc == '"')
219 {
220 getCc();
221 while (cc >= ' ' && cc != '"')
222 { int sc;
223 if (cc == '\\') // handle quotation
224 {
225 getCc();
226 switch (cc)
227 {
228 case 'E' : sc = 27; getCc(); break;
229 case 'b' : sc = 8; getCc(); break;
230 case 'f' : sc = 12; getCc(); break;
231 case 't' : sc = 9; getCc(); break;
232 case 'r' : sc = 13; getCc(); break;
233 case 'n' : sc = 10; getCc(); break;
234 case '\\' : // fall thru
235 case '"' : sc = cc; getCc(); break;
236 case 'x' : getCc();
237 sc = 0;
238 if (!isNibble(cc)) return; sc = 16*sc + convNibble(cc); getCc();
239 if (!isNibble(cc)) return; sc = 16*sc + convNibble(cc); getCc();
240 break;
241 default : return;
242 }
243 }
244 else
245 {
246 // regular char
247 sc = cc; getCc();
248 }
249 res = res + (char)sc;
250 len = len + 1;
251 }
252 if (cc != '"') return;
253 getCc();
254 sym = SYMString; return;
255 }
256}
257
258void KeytabReader::ReportToken() // diagnostic
259{
260 printf("sym(%d): ",slinno);
261 switch(sym)
262 {
263 case SYMEol : printf("End of line"); break;
264 case SYMEof : printf("End of file"); break;
265 case SYMName : printf("Name: %s",res.latin1()); break;
266 case SYMOpr : printf("Opr : %s",res.latin1()); break;
267 case SYMString : printf("String len %d,%d ",res.length(),len);
268 for (unsigned i = 0; i < res.length(); i++)
269 printf(" %02x(%c)",res.latin1()[i],res.latin1()[i]>=' '?res.latin1()[i]:'?');
270 break;
271 }
272 printf("\n");
273}
274
275void KeytabReader::ReportError(const char* msg) // diagnostic
276{
277 fprintf(stderr,"%s(%d,%d):error: %s.\n",path.ascii(),slinno,scolno,msg);
278}
279
280// local symbol tables ---------------------------------------------------------------------
281
282class KeyTransSymbols
283{
284public:
285 KeyTransSymbols();
286protected:
287 void defOprSyms();
288 void defModSyms();
289 void defKeySyms();
290 void defKeySym(const char* key, int val);
291 void defOprSym(const char* key, int val);
292 void defModSym(const char* key, int val);
293public:
294 QDict<QObject> keysyms;
295 QDict<QObject> modsyms;
296 QDict<QObject> oprsyms;
297};
298
299static KeyTransSymbols * syms = 0L;
300
301// parser ----------------------------------------------------------------------------------
302/* Syntax
303 - Line :: [KeyName { ("+" | "-") ModeName } ":" (String|CommandName)] "\n"
304 - Comment :: '#' (any but \n)*
305*/
306
307KeyTrans* KeyTrans::fromDevice(QString path, QIODevice &buf)
308{
309 KeyTrans* kt = new KeyTrans;
310 kt->path = path;
311 KeytabReader ktr(path,buf); ktr.parseTo(kt);
312 return kt;
313}
314
315
316#define assertSyntax(Cond,Message) if (!(Cond)) { ReportError(Message); goto ERROR; }
317
318void KeytabReader::parseTo(KeyTrans* kt)
319{
320 // Opening sequence
321
322 buf->open(IO_ReadOnly);
323 getCc();
324 linno = 1;
325 colno = 1;
326 getSymbol();
327
328Loop:
329 // syntax: ["key" KeyName { ("+" | "-") ModeName } ":" String/CommandName] ["#" Comment]
330 if (sym == SYMName && !strcmp(res.latin1(),"keyboard"))
331 {
332 getSymbol(); assertSyntax(sym == SYMString, "Header expected")
333 kt->hdr = res.latin1();
334 getSymbol(); assertSyntax(sym == SYMEol, "Text unexpected")
335 getSymbol(); // eoln
336 goto Loop;
337 }
338 if (sym == SYMName && !strcmp(res.latin1(),"key"))
339 {
340//printf("line %3d: ",startofsym);
341 getSymbol(); assertSyntax(sym == SYMName, "Name expected")
342 assertSyntax(syms->keysyms[res], "Unknown key name")
343 int key = (int)syms->keysyms[res]-1;
344//printf(" key %s (%04x)",res.latin1(),(int)syms->keysyms[res]-1);
345 getSymbol(); // + - :
346 int mode = 0;
347 int mask = 0;
348 while (sym == SYMOpr && (!strcmp(res.latin1(),"+") || !strcmp(res.latin1(),"-")))
349 {
350 bool on = !strcmp(res.latin1(),"+");
351 getSymbol();
352 // mode name
353 assertSyntax(sym == SYMName, "Name expected")
354 assertSyntax(syms->modsyms[res], "Unknown mode name")
355 int bits = (int)syms->modsyms[res]-1;
356 if (mask & (1 << bits))
357 {
358 fprintf(stderr,"%s(%d,%d): mode name used multible times.\n",path.ascii(),slinno,scolno);
359 }
360 else
361 {
362 mode |= (on << bits);
363 mask |= (1 << bits);
364 }
365//printf(", mode %s(%d) %s",res.latin1(),(int)syms->modsyms[res]-1,on?"on":"off");
366 getSymbol();
367 }
368 assertSyntax(sym == SYMOpr && !strcmp(res.latin1(),":"), "':' expected")
369 getSymbol();
370 // string or command
371 assertSyntax(sym == SYMName || sym == SYMString,"Command or string expected")
372 int cmd = 0;
373 if (sym == SYMName)
374 {
375 assertSyntax(syms->oprsyms[res], "Unknown operator name")
376 cmd = (int)syms->oprsyms[res]-1;
377//printf(": do %s(%d)",res.latin1(),(int)syms->oprsyms[res]-1);
378 }
379 if (sym == SYMString)
380 {
381 cmd = CMD_send;
382//printf(": send");
383//for (unsigned i = 0; i < res.length(); i++)
384//printf(" %02x(%c)",res.latin1()[i],res.latin1()[i]>=' '?res.latin1()[i]:'?');
385 }
386//printf(". summary %04x,%02x,%02x,%d\n",key,mode,mask,cmd);
387 KeyTrans::KeyEntry* ke = kt->addEntry(slinno,key,mode,mask,cmd,res);
388 if (ke)
389 {
390 fprintf(stderr,"%s(%d): keystroke already assigned in line %d.\n",path.ascii(),slinno,ke->ref);
391 }
392 getSymbol();
393 assertSyntax(sym == SYMEol, "Unexpected text")
394 goto Loop;
395 }
396 if (sym == SYMEol)
397 {
398 getSymbol();
399 goto Loop;
400 }
401
402 assertSyntax(sym == SYMEof, "Undecodable Line")
403
404 buf->close();
405 return;
406
407ERROR:
408 while (sym != SYMEol && sym != SYMEof) getSymbol(); // eoln
409 goto Loop;
410}
411
412
413KeyTrans* KeyTrans::defaultKeyTrans()
414{
415 QCString txt =
416#include "default.keytab.h"
417 ;
418 QBuffer buf(txt);
419 return fromDevice("[buildin]",buf);
420}
421
422KeyTrans* KeyTrans::fromFile(const char* path)
423{
424 QFile file(path);
425 return fromDevice(path,file);
426}
427
428// local symbol tables ---------------------------------------------------------------------
429// material needed for parsing the config file.
430// This is incomplete work.
431
432void KeyTransSymbols::defKeySym(const char* key, int val)
433{
434 keysyms.insert(key,(QObject*)(val+1));
435}
436
437void KeyTransSymbols::defOprSym(const char* key, int val)
438{
439 oprsyms.insert(key,(QObject*)(val+1));
440}
441
442void KeyTransSymbols::defModSym(const char* key, int val)
443{
444 modsyms.insert(key,(QObject*)(val+1));
445}
446
447void KeyTransSymbols::defOprSyms()
448{
449 // Modifier
450 defOprSym("scrollLineUp", CMD_scrollLineUp );
451 defOprSym("scrollLineDown",CMD_scrollLineDown);
452 defOprSym("scrollPageUp", CMD_scrollPageUp );
453 defOprSym("scrollPageDown",CMD_scrollPageDown);
454 defOprSym("emitSelection", CMD_emitSelection );
455 defOprSym("prevSession", CMD_prevSession );
456 defOprSym("nextSession", CMD_nextSession );
457}
458
459void KeyTransSymbols::defModSyms()
460{
461 // Modifier
462 defModSym("Shift", BITS_Shift );
463 defModSym("Control", BITS_Control );
464 defModSym("Alt", BITS_Alt );
465 // Modes
466 defModSym("BsHack", BITS_BsHack ); // deprecated
467 defModSym("Ansi", BITS_Ansi );
468 defModSym("NewLine", BITS_NewLine );
469 defModSym("AppCuKeys", BITS_AppCuKeys );
470}
471
472void KeyTransSymbols::defKeySyms()
473{
474 // Grey keys
475 defKeySym("Escape", Qt::Key_Escape );
476 defKeySym("Tab", Qt::Key_Tab );
477 defKeySym("Backtab", Qt::Key_Backtab );
478 defKeySym("Backspace", Qt::Key_Backspace );
479 defKeySym("Return", Qt::Key_Return );
480 defKeySym("Enter", Qt::Key_Enter );
481 defKeySym("Insert", Qt::Key_Insert );
482 defKeySym("Delete", Qt::Key_Delete );
483 defKeySym("Pause", Qt::Key_Pause );
484 defKeySym("Print", Qt::Key_Print );
485 defKeySym("SysReq", Qt::Key_SysReq );
486 defKeySym("Home", Qt::Key_Home );
487 defKeySym("End", Qt::Key_End );
488 defKeySym("Left", Qt::Key_Left );
489 defKeySym("Up", Qt::Key_Up );
490 defKeySym("Right", Qt::Key_Right );
491 defKeySym("Down", Qt::Key_Down );
492 defKeySym("Prior", Qt::Key_Prior );
493 defKeySym("Next", Qt::Key_Next );
494 defKeySym("Shift", Qt::Key_Shift );
495 defKeySym("Control", Qt::Key_Control );
496 defKeySym("Meta", Qt::Key_Meta );
497 defKeySym("Alt", Qt::Key_Alt );
498 defKeySym("CapsLock", Qt::Key_CapsLock );
499 defKeySym("NumLock", Qt::Key_NumLock );
500 defKeySym("ScrollLock", Qt::Key_ScrollLock );
501 defKeySym("F1", Qt::Key_F1 );
502 defKeySym("F2", Qt::Key_F2 );
503 defKeySym("F3", Qt::Key_F3 );
504 defKeySym("F4", Qt::Key_F4 );
505 defKeySym("F5", Qt::Key_F5 );
506 defKeySym("F6", Qt::Key_F6 );
507 defKeySym("F7", Qt::Key_F7 );
508 defKeySym("F8", Qt::Key_F8 );
509 defKeySym("F9", Qt::Key_F9 );
510 defKeySym("F10", Qt::Key_F10 );
511 defKeySym("F11", Qt::Key_F11 );
512 defKeySym("F12", Qt::Key_F12 );
513 defKeySym("F13", Qt::Key_F13 );
514 defKeySym("F14", Qt::Key_F14 );
515 defKeySym("F15", Qt::Key_F15 );
516 defKeySym("F16", Qt::Key_F16 );
517 defKeySym("F17", Qt::Key_F17 );
518 defKeySym("F18", Qt::Key_F18 );
519 defKeySym("F19", Qt::Key_F19 );
520 defKeySym("F20", Qt::Key_F20 );
521 defKeySym("F21", Qt::Key_F21 );
522 defKeySym("F22", Qt::Key_F22 );
523 defKeySym("F23", Qt::Key_F23 );
524 defKeySym("F24", Qt::Key_F24 );
525 defKeySym("F25", Qt::Key_F25 );
526 defKeySym("F26", Qt::Key_F26 );
527 defKeySym("F27", Qt::Key_F27 );
528 defKeySym("F28", Qt::Key_F28 );
529 defKeySym("F29", Qt::Key_F29 );
530 defKeySym("F30", Qt::Key_F30 );
531 defKeySym("F31", Qt::Key_F31 );
532 defKeySym("F32", Qt::Key_F32 );
533 defKeySym("F33", Qt::Key_F33 );
534 defKeySym("F34", Qt::Key_F34 );
535 defKeySym("F35", Qt::Key_F35 );
536 defKeySym("Super_L", Qt::Key_Super_L );
537 defKeySym("Super_R", Qt::Key_Super_R );
538 defKeySym("Menu", Qt::Key_Menu );
539 defKeySym("Hyper_L", Qt::Key_Hyper_L );
540 defKeySym("Hyper_R", Qt::Key_Hyper_R );
541
542 // Regular keys
543 defKeySym("Space", Qt::Key_Space );
544 defKeySym("Exclam", Qt::Key_Exclam );
545 defKeySym("QuoteDbl", Qt::Key_QuoteDbl );
546 defKeySym("NumberSign", Qt::Key_NumberSign );
547 defKeySym("Dollar", Qt::Key_Dollar );
548 defKeySym("Percent", Qt::Key_Percent );
549 defKeySym("Ampersand", Qt::Key_Ampersand );
550 defKeySym("Apostrophe", Qt::Key_Apostrophe );
551 defKeySym("ParenLeft", Qt::Key_ParenLeft );
552 defKeySym("ParenRight", Qt::Key_ParenRight );
553 defKeySym("Asterisk", Qt::Key_Asterisk );
554 defKeySym("Plus", Qt::Key_Plus );
555 defKeySym("Comma", Qt::Key_Comma );
556 defKeySym("Minus", Qt::Key_Minus );
557 defKeySym("Period", Qt::Key_Period );
558 defKeySym("Slash", Qt::Key_Slash );
559 defKeySym("0", Qt::Key_0 );
560 defKeySym("1", Qt::Key_1 );
561 defKeySym("2", Qt::Key_2 );
562 defKeySym("3", Qt::Key_3 );
563 defKeySym("4", Qt::Key_4 );
564 defKeySym("5", Qt::Key_5 );
565 defKeySym("6", Qt::Key_6 );
566 defKeySym("7", Qt::Key_7 );
567 defKeySym("8", Qt::Key_8 );
568 defKeySym("9", Qt::Key_9 );
569 defKeySym("Colon", Qt::Key_Colon );
570 defKeySym("Semicolon", Qt::Key_Semicolon );
571 defKeySym("Less", Qt::Key_Less );
572 defKeySym("Equal", Qt::Key_Equal );
573 defKeySym("Greater", Qt::Key_Greater );
574 defKeySym("Question", Qt::Key_Question );
575 defKeySym("At", Qt::Key_At );
576 defKeySym("A", Qt::Key_A );
577 defKeySym("B", Qt::Key_B );
578 defKeySym("C", Qt::Key_C );
579 defKeySym("D", Qt::Key_D );
580 defKeySym("E", Qt::Key_E );
581 defKeySym("F", Qt::Key_F );
582 defKeySym("G", Qt::Key_G );
583 defKeySym("H", Qt::Key_H );
584 defKeySym("I", Qt::Key_I );
585 defKeySym("J", Qt::Key_J );
586 defKeySym("K", Qt::Key_K );
587 defKeySym("L", Qt::Key_L );
588 defKeySym("M", Qt::Key_M );
589 defKeySym("N", Qt::Key_N );
590 defKeySym("O", Qt::Key_O );
591 defKeySym("P", Qt::Key_P );
592 defKeySym("Q", Qt::Key_Q );
593 defKeySym("R", Qt::Key_R );
594 defKeySym("S", Qt::Key_S );
595 defKeySym("T", Qt::Key_T );
596 defKeySym("U", Qt::Key_U );
597 defKeySym("V", Qt::Key_V );
598 defKeySym("W", Qt::Key_W );
599 defKeySym("X", Qt::Key_X );
600 defKeySym("Y", Qt::Key_Y );
601 defKeySym("Z", Qt::Key_Z );
602 defKeySym("BracketLeft", Qt::Key_BracketLeft );
603 defKeySym("Backslash", Qt::Key_Backslash );
604 defKeySym("BracketRight", Qt::Key_BracketRight);
605 defKeySym("AsciiCircum", Qt::Key_AsciiCircum );
606 defKeySym("Underscore", Qt::Key_Underscore );
607 defKeySym("QuoteLeft", Qt::Key_QuoteLeft );
608 defKeySym("BraceLeft", Qt::Key_BraceLeft );
609 defKeySym("Bar", Qt::Key_Bar );
610 defKeySym("BraceRight", Qt::Key_BraceRight );
611 defKeySym("AsciiTilde", Qt::Key_AsciiTilde );
612}
613
614KeyTransSymbols::KeyTransSymbols()
615{
616 defModSyms();
617 defOprSyms();
618 defKeySyms();
619}
620
621// Global material -----------------------------------------------------------
622
623static int keytab_serial = 0; //FIXME: remove,localize
624
625static QIntDict<KeyTrans> * numb2keymap = 0L;
626static QDict<KeyTrans> * path2keymap = 0L;
627
628KeyTrans* KeyTrans::find(int numb)
629{
630 KeyTrans* res = numb2keymap->find(numb);
631 return res ? res : numb2keymap->find(0);
632}
633
634KeyTrans* KeyTrans::find(const char* path)
635{
636 KeyTrans* res = path2keymap->find(path);
637 return res ? res : numb2keymap->find(0);
638}
639
640int KeyTrans::count()
641{
642 return numb2keymap->count();
643}
644
645void KeyTrans::addKeyTrans()
646{
647 this->numb = keytab_serial ++;
648 numb2keymap->insert(numb,this);
649 path2keymap->insert(path,this);
650}
651
652void KeyTrans::loadAll()
653{
654 if (!numb2keymap)
655 numb2keymap = new QIntDict<KeyTrans>;
656 if (!path2keymap)
657 path2keymap = new QDict<KeyTrans>;
658 if (!syms)
659 syms = new KeyTransSymbols;
660
661 defaultKeyTrans()->addKeyTrans();
662
663
664 QString path = QPEApplication::qpeDir() + "etc/keytabs";
665 QDir dir(path);
666 QStringList lst = dir.entryList("*.keytab");
667
668 for(QStringList::Iterator it = lst.begin(); it != lst.end(); ++it ) {
669 QFile file(path + "/" + *it);
670 KeyTrans* sc = KeyTrans::fromDevice(*it, file);
671 if (sc) {
672 sc->addKeyTrans();
673 }
674 }
675
676}
677
678// Debugging material -----------------------------------------------------------
679/*
680void TestTokenizer(QBuffer &buf)
681{
682 // opening sequence
683
684 buf.open(IO_ReadOnly);
685 cc = buf.getch();
686 lineno = 1;
687
688 // Test tokenizer
689
690 while (getSymbol(buf)) ReportToken();
691
692 buf.close();
693}
694
695void test()
696{
697 // Opening sequence
698
699 QCString txt =
700#include "default.keytab.h"
701 ;
702 QBuffer buf(txt);
703 if (0) TestTokenizer(buf);
704 if (1) { KeyTrans kt; kt.scanTable(buf); }
705}
706*/
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 @@
1/* -------------------------------------------------------------------------- */
2/* */
3/* [keytrans.h] X Terminal Emulation */
4/* */
5/* -------------------------------------------------------------------------- */
6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */
9/* This file is part of Konsole - an X terminal for KDE */
10/* */
11/* -------------------------------------------------------------------------- */
12 /* */
13/* Ported Konsole to Qt/Embedded */
14 /* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16 /* */
17/* -------------------------------------------------------------------------- */
18
19#ifndef KEYTRANS_H
20#define KEYTRANS_H
21
22#include <qstring.h>
23#include <qlist.h>
24#include <qiodevice.h>
25
26#define BITS_NewLine 0
27#define BITS_BsHack 1
28#define BITS_Ansi 2
29#define BITS_AppCuKeys 3
30#define BITS_Control 4
31#define BITS_Shift 5
32#define BITS_Alt 6
33#define BITS_COUNT 7
34
35#define CMD_send 0
36#define CMD_emitSelection 1
37#define CMD_scrollPageUp 2
38#define CMD_scrollPageDown 3
39#define CMD_scrollLineUp 4
40#define CMD_scrollLineDown 5
41#define CMD_prevSession 6
42#define CMD_nextSession 7
43
44#define BITS(x,v) ((((v)!=0)<<(x)))
45
46
47class KeyTrans
48{
49public:
50 KeyTrans();
51 ~KeyTrans();
52 static KeyTrans* defaultKeyTrans();
53 static KeyTrans* fromFile(const char* path);
54 static KeyTrans* find(int numb);
55 static KeyTrans* find(const char* path);
56public:
57 static int count();
58 static void loadAll();
59public:
60 bool findEntry(int key, int bits, int* cmd, const char** txt, int* len);
61private:
62 void addKeyTrans();
63 static KeyTrans* fromDevice(QString path, QIODevice &buf);
64public:
65 class KeyEntry
66 {
67 public:
68 KeyEntry(int ref, int key, int bits, int mask, int cmd, QString txt);
69 ~KeyEntry();
70 public:
71 bool matches(int key, int bits, int mask);
72 QString text();
73 public:
74 int ref;
75 private:
76 int key;
77 int bits;
78 int mask;
79 public:
80 int cmd;
81 QString txt;
82 };
83public:
84 KeyEntry* addEntry(int ref, int key, int bits, int mask, int cmd, QString txt);
85private:
86 QList<KeyEntry> table;
87public: //FIXME: we'd do better
88 QString hdr;
89 int numb;
90 QString path;
91};
92
93#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 @@
1/* ---------------------------------------------------------------------- */
2/* */
3/* [main.C] Konsole */
4/* */
5/* ---------------------------------------------------------------------- */
6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */
9/* This file is part of Konsole, an X terminal. */
10/* */
11/* The material contained in here more or less directly orginates from */
12/* kvt, which is copyright (c) 1996 by Matthias Ettrich <ettrich@kde.org> */
13/* */
14/* ---------------------------------------------------------------------- */
15 /* */
16/* Ported Konsole to Qt/Embedded */
17 /* */
18/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
19 /* */
20/* -------------------------------------------------------------------------- */
21
22#include <qpe/resource.h>
23
24#include <qdir.h>
25#include <qevent.h>
26#include <qdragobject.h>
27#include <qobjectlist.h>
28#include <qtoolbutton.h>
29#include <qpe/qpetoolbar.h>
30#include <qpushbutton.h>
31#include <qfontdialog.h>
32#include <qglobal.h>
33#include <qpainter.h>
34#include <qpe/qpemenubar.h>
35#include <qmessagebox.h>
36#include <qaction.h>
37#include <qapplication.h>
38#include <qfontmetrics.h>
39#include <qcombobox.h>
40#include <qevent.h>
41#include <qtabwidget.h>
42#include <qtabbar.h>
43#include <qpe/config.h>
44
45#include <sys/wait.h>
46#include <stdio.h>
47#include <stdlib.h>
48#include <assert.h>
49
50#include "konsole.h"
51#include "keytrans.h"
52
53class EKNumTabBar : public QTabBar {
54public:
55 void numberTabs()
56 {
57 // Yes, it really is this messy. QTabWidget needs functions
58 // that provide acces to tabs in a sequential way.
59 int m=INT_MIN;
60 for (int i=0; i<count(); i++) {
61 QTab* left=0;
62 QListIterator<QTab> it(*tabList());
63 int x=INT_MAX;
64 for( QTab* t; (t=it.current()); ++it ) {
65 int tx = t->rect().x();
66 if ( tx<x && tx>m ) {
67 x = tx;
68 left = t;
69 }
70 }
71 if ( left ) {
72 left->setText(QString::number(i+1));
73 m = left->rect().x();
74 }
75 }
76 }
77};
78
79class EKNumTabWidget : public QTabWidget {
80public:
81 EKNumTabWidget(QWidget* parent) : QTabWidget(parent)
82 {
83 }
84
85 void addTab(QWidget* w)
86 {
87 QTab* t = new QTab(QString::number(tabBar()->count()+1));
88 QTabWidget::addTab(w,t);
89 }
90
91 void removeTab(QWidget* w)
92 {
93 removePage(w);
94 ((EKNumTabBar*)tabBar())->numberTabs();
95 }
96};
97
98// This could be configurable or dynamicly generated from the bash history
99// file of the user
100static const char *commonCmds[] =
101{
102 "ls ",
103 //"ls -la ",
104 "cd ",
105 "pwd",
106 //"cat",
107 //"less ",
108 //"vi ",
109 //"man ",
110 "echo ",
111 "set ",
112 //"ps",
113 "ps aux",
114 //"tar",
115 //"tar -zxf",
116 "grep ",
117 //"grep -i",
118 //"mkdir",
119 "cp ",
120 "mv ",
121 "rm ",
122 "rmdir ",
123 //"chmod",
124 //"su",
125// "top",
126 //"find",
127 //"make",
128 //"tail",
129 "cardctl eject",
130 "ifconfig ",
131// "iwconfig eth0 ",
132 "nc localhost 7777",
133 "nc localhost 7776",
134 //"mount /dev/hda1",
135
136/*
137 "gzip",
138 "gunzip",
139 "chgrp",
140 "chown",
141 "date",
142 "dd",
143 "df",
144 "dmesg",
145 "fuser",
146 "hostname",
147 "kill",
148 "killall",
149 "ln",
150 "ping",
151 "mount",
152 "more",
153 "sort",
154 "touch",
155 "umount",
156 "mknod",
157 "netstat",
158*/
159
160 "exit",
161 NULL
162};
163
164
165Konsole::Konsole(QWidget* parent, const char* name, WFlags fl) :
166 QMainWindow(parent, name, fl)
167{
168 QStrList args;
169 init("/bin/sh",args);
170}
171
172Konsole::Konsole(const char* name, const char* _pgm, QStrList & _args, int)
173 : QMainWindow(0, name)
174{
175 init(_pgm,_args);
176}
177
178void Konsole::init(const char* _pgm, QStrList & _args)
179{
180 b_scroll = TRUE; // histon;
181 n_keytab = 0;
182 n_render = 0;
183
184 setCaption( tr("Terminal") );
185 setIcon( Resource::loadPixmap( "konsole" ) );
186
187 Config cfg("Konsole");
188 cfg.setGroup("Konsole");
189
190 // initialize the list of allowed fonts ///////////////////////////////////
191 cfont = cfg.readNumEntry("FontID", 1);
192 QFont f = QFont("Micro", 4, QFont::Normal);
193 f.setFixedPitch(TRUE);
194 fonts.append(new VTFont(tr("Micro"), f));
195
196 f = QFont("Fixed", 7, QFont::Normal);
197 f.setFixedPitch(TRUE);
198 fonts.append(new VTFont(tr("Small Fixed"), f));
199
200 f = QFont("Fixed", 12, QFont::Normal);
201 f.setFixedPitch(TRUE);
202 fonts.append(new VTFont(tr("Medium Fixed"), f));
203
204 // create terminal emulation framework ////////////////////////////////////
205 nsessions = 0;
206 tab = new EKNumTabWidget(this);
207 tab->setTabPosition(QTabWidget::Bottom);
208 connect(tab, SIGNAL(currentChanged(QWidget*)), this, SLOT(switchSession(QWidget*)));
209
210 // create terminal toolbar ////////////////////////////////////////////////
211 setToolBarsMovable( FALSE );
212 QPEToolBar *menuToolBar = new QPEToolBar( this );
213 menuToolBar->setHorizontalStretchable( TRUE );
214
215 QPEMenuBar *menuBar = new QPEMenuBar( menuToolBar );
216
217 fontList = new QPopupMenu( this );
218 for(uint i = 0; i < fonts.count(); i++) {
219 VTFont *fnt = fonts.at(i);
220 fontList->insertItem(fnt->getName(), i);
221 }
222 fontChanged(cfont);
223
224 connect( fontList, SIGNAL( activated(int) ), this, SLOT( fontChanged(int) ));
225
226 menuBar->insertItem( tr("Font"), fontList );
227
228 QPEToolBar *toolbar = new QPEToolBar( this );
229
230 QAction *a;
231
232 // Button Commands
233 a = new QAction( tr("New"), Resource::loadPixmap( "konsole" ), QString::null, 0, this, 0 );
234 connect( a, SIGNAL( activated() ), this, SLOT( newSession() ) ); a->addTo( toolbar );
235 a = new QAction( tr("Enter"), Resource::loadPixmap( "konsole/enter" ), QString::null, 0, this, 0 );
236 connect( a, SIGNAL( activated() ), this, SLOT( hitEnter() ) ); a->addTo( toolbar );
237 a = new QAction( tr("Space"), Resource::loadPixmap( "konsole/space" ), QString::null, 0, this, 0 );
238 connect( a, SIGNAL( activated() ), this, SLOT( hitSpace() ) ); a->addTo( toolbar );
239 a = new QAction( tr("Tab"), Resource::loadPixmap( "konsole/tab" ), QString::null, 0, this, 0 );
240 connect( a, SIGNAL( activated() ), this, SLOT( hitTab() ) ); a->addTo( toolbar );
241 a = new QAction( tr("Up"), Resource::loadPixmap( "konsole/up" ), QString::null, 0, this, 0 );
242 connect( a, SIGNAL( activated() ), this, SLOT( hitUp() ) ); a->addTo( toolbar );
243 a = new QAction( tr("Down"), Resource::loadPixmap( "konsole/down" ), QString::null, 0, this, 0 );
244 connect( a, SIGNAL( activated() ), this, SLOT( hitDown() ) ); a->addTo( toolbar );
245 a = new QAction( tr("Paste"), Resource::loadPixmap( "paste" ), QString::null, 0, this, 0 );
246 connect( a, SIGNAL( activated() ), this, SLOT( hitPaste() ) ); a->addTo( toolbar );
247/*
248 a = new QAction( tr("Up"), Resource::loadPixmap( "up" ), QString::null, 0, this, 0 );
249 connect( a, SIGNAL( activated() ), this, SLOT( hitUp() ) ); a->addTo( toolbar );
250 a = new QAction( tr("Down"), Resource::loadPixmap( "down" ), QString::null, 0, this, 0 );
251 connect( a, SIGNAL( activated() ), this, SLOT( hitDown() ) ); a->addTo( toolbar );
252*/
253
254 QPEToolBar *secondToolBar = new QPEToolBar( this );
255 secondToolBar->setHorizontalStretchable( TRUE );
256
257 QComboBox *commonCombo = new QComboBox( secondToolBar );
258// commonCombo->setEditable( TRUE );
259 for (int i = 0; commonCmds[i] != NULL; i++)
260 commonCombo->insertItem( commonCmds[i], i );
261 connect( commonCombo, SIGNAL( activated(int) ), this, SLOT( enterCommand(int) ));
262
263 // create applications /////////////////////////////////////////////////////
264 setCentralWidget(tab);
265
266 // load keymaps ////////////////////////////////////////////////////////////
267 KeyTrans::loadAll();
268 for (int i = 0; i < KeyTrans::count(); i++)
269 { KeyTrans* s = KeyTrans::find(i);
270 assert( s );
271 }
272
273 se_pgm = _pgm;
274 se_args = _args;
275
276 // read and apply default values ///////////////////////////////////////////
277 resize(321, 321); // Dummy.
278 QSize currentSize = size();
279 if (currentSize != size())
280 defaultSize = size();
281}
282
283void Konsole::show()
284{
285 if ( !nsessions ) {
286 newSession();
287 }
288 QMainWindow::show();
289}
290
291void Konsole::initSession(const char*, QStrList &)
292{
293 QMainWindow::show();
294}
295
296Konsole::~Konsole()
297{
298 while (nsessions > 0) {
299 doneSession(getTe()->currentSession, 0);
300 }
301
302 Config cfg("Konsole");
303 cfg.setGroup("Konsole");
304 cfg.writeEntry("FontID", cfont);
305}
306
307void Konsole::fontChanged(int f)
308{
309 VTFont* font = fonts.at(f);
310 if (font != 0) {
311 for(uint i = 0; i < fonts.count(); i++) {
312 fontList->setItemChecked(i, (i == (uint) f) ? TRUE : FALSE);
313 }
314
315 cfont = f;
316
317 TEWidget* te = getTe();
318 if (te != 0) {
319 te->setVTFont(font->getFont());
320 }
321 }
322}
323
324void Konsole::enterCommand(int c)
325{
326 TEWidget* te = getTe();
327 if (te != 0) {
328 QString text = commonCmds[c];
329 te->emitText(text);
330 }
331}
332
333void Konsole::hitEnter()
334{
335 TEWidget* te = getTe();
336 if (te != 0) {
337 te->emitText(QString("\r"));
338 }
339}
340
341void Konsole::hitSpace()
342{
343 TEWidget* te = getTe();
344 if (te != 0) {
345 te->emitText(QString(" "));
346 }
347}
348
349void Konsole::hitTab()
350{
351 TEWidget* te = getTe();
352 if (te != 0) {
353 te->emitText(QString("\t"));
354 }
355}
356
357void Konsole::hitPaste()
358{
359 TEWidget* te = getTe();
360 if (te != 0) {
361 te->pasteClipboard();
362 }
363}
364
365void Konsole::hitUp()
366{
367 TEWidget* te = getTe();
368 if (te != 0) {
369 QKeyEvent ke( QKeyEvent::KeyPress, Qt::Key_Up, 0, 0);
370 QApplication::sendEvent( te, &ke );
371 }
372}
373
374void Konsole::hitDown()
375{
376 TEWidget* te = getTe();
377 if (te != 0) {
378 QKeyEvent ke( QKeyEvent::KeyPress, Qt::Key_Down, 0, 0);
379 QApplication::sendEvent( te, &ke );
380 }
381}
382
383/**
384 This function calculates the size of the external widget
385 needed for the internal widget to be
386 */
387QSize Konsole::calcSize(int columns, int lines) {
388 TEWidget* te = getTe();
389 if (te != 0) {
390 QSize size = te->calcSize(columns, lines);
391 return size;
392 } else {
393 QSize size;
394 return size;
395 }
396}
397
398/**
399 sets application window to a size based on columns X lines of the te
400 guest widget. Call with (0,0) for setting default size.
401*/
402
403void Konsole::setColLin(int columns, int lines)
404{
405 if ((columns==0) || (lines==0))
406 {
407 if (defaultSize.isEmpty()) // not in config file : set default value
408 {
409 defaultSize = calcSize(80,24);
410 // notifySize(24,80); // set menu items (strange arg order !)
411 }
412 resize(defaultSize);
413 } else {
414 resize(calcSize(columns, lines));
415 // notifySize(lines,columns); // set menu items (strange arg order !)
416 }
417}
418
419/*
420void Konsole::setFont(int fontno)
421{
422 QFont f;
423 if (fontno == 0)
424 f = defaultFont = QFont( "Helvetica", 12 );
425 else
426 if (fonts[fontno][0] == '-')
427 f.setRawName( fonts[fontno] );
428 else
429 {
430 f.setFamily(fonts[fontno]);
431 f.setRawMode( TRUE );
432 }
433 if ( !f.exactMatch() && fontno != 0)
434 {
435 QString msg = i18n("Font `%1' not found.\nCheck README.linux.console for help.").arg(fonts[fontno]);
436 QMessageBox(this, msg);
437 return;
438 }
439 if (se) se->setFontNo(fontno);
440 te->setVTFont(f);
441 n_font = fontno;
442}
443*/
444
445// --| color selection |-------------------------------------------------------
446
447void Konsole::changeColumns(int columns)
448{
449 TEWidget* te = getTe();
450 if (te != 0) {
451 setColLin(columns,te->Lines());
452 te->update();
453 }
454}
455
456//FIXME: If a child dies during session swap,
457// this routine might be called before
458// session swap is completed.
459
460void Konsole::doneSession(TESession*, int )
461{
462 TEWidget *te = getTe();
463 if (te != 0) {
464 te->currentSession->setConnect(FALSE);
465 tab->removeTab(te);
466 delete te->currentSession;
467 delete te;
468 nsessions--;
469 }
470
471 if (nsessions == 0) {
472 close();
473 }
474}
475
476
477void Konsole::newSession() {
478 TEWidget* te = new TEWidget(tab);
479 te->setBackgroundMode(PaletteBase);
480 te->setVTFont(fonts.at(cfont)->getFont());
481 tab->addTab(te);
482 TESession* se = new TESession(this, te, se_pgm, se_args, "xterm");
483 te->currentSession = se;
484 connect( se, SIGNAL(done(TESession*,int)), this, SLOT(doneSession(TESession*,int)) );
485 se->run();
486 se->setConnect(TRUE);
487 se->setHistory(b_scroll);
488 tab->setCurrentPage(nsessions);
489 nsessions++;
490}
491
492TEWidget* Konsole::getTe() {
493 if (nsessions) {
494 return (TEWidget *) tab->currentPage();
495 } else {
496 return 0;
497 }
498 }
499
500void Konsole::switchSession(QWidget* w) {
501 TEWidget* te = (TEWidget *) w;
502
503 QFont teFnt = te->getVTFont();
504 for(uint i = 0; i < fonts.count(); i++) {
505 VTFont *fnt = fonts.at(i);
506 bool cf = fnt->getFont() == teFnt;
507 fontList->setItemChecked(i, cf);
508 if (cf) {
509 cfont = i;
510 }
511 }
512}
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 @@
1/* ----------------------------------------------------------------------- */
2/* */
3/* [konsole.h] Konsole */
4/* */
5/* -------------------------------------------------------------------------- */
6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */
9/* This file is part of Konsole, an X terminal. */
10/* */
11/* The material contained in here more or less directly orginates from */
12/* kvt, which is copyright (c) 1996 by Matthias Ettrich <ettrich@kde.org> */
13/* */
14/* -------------------------------------------------------------------------- */
15 /* */
16/* Ported Konsole to Qt/Embedded */
17 /* */
18/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
19 /* */
20/* -------------------------------------------------------------------------- */
21
22#ifndef KONSOLE_H
23#define KONSOLE_H
24
25
26#include <qmainwindow.h>
27#include <qaction.h>
28#include <qpopupmenu.h>
29#include <qstrlist.h>
30#include <qintdict.h>
31#include <qptrdict.h>
32#include <qtabwidget.h>
33
34#include "MyPty.h"
35#include "TEWidget.h"
36#include "TEmuVt102.h"
37#include "session.h"
38
39class EKNumTabWidget;
40
41class Konsole : public QMainWindow
42{
43Q_OBJECT
44
45public:
46
47 Konsole(QWidget* parent = 0, const char* name = 0, WFlags fl = 0);
48 Konsole(const char * name, const char* pgm, QStrList & _args, int histon);
49 ~Konsole();
50 void setColLin(int columns, int lines);
51
52 void show();
53
54private slots:
55 void doneSession(TESession*,int);
56 void changeColumns(int);
57 void fontChanged(int);
58 void enterCommand(int);
59 void hitEnter();
60 void hitSpace();
61 void hitTab();
62 void hitPaste();
63 void hitUp();
64 void hitDown();
65 void switchSession(QWidget *);
66 void newSession();
67
68private:
69 void init(const char* _pgm, QStrList & _args);
70 void initSession(const char* _pgm, QStrList & _args);
71 void runSession(TESession* s);
72 void setColorPixmaps();
73 void setHistory(bool);
74 QSize calcSize(int columns, int lines);
75 TEWidget* getTe();
76
77private:
78 class VTFont
79 {
80 public:
81 VTFont(QString name, QFont& font)
82 {
83 this->name = name;
84 this->font = font;
85 }
86
87 QFont& getFont()
88 {
89 return font;
90 }
91
92 QString getName()
93 {
94 return name;
95 }
96
97 private:
98 QString name;
99 QFont font;
100 };
101
102 EKNumTabWidget* tab;
103 int nsessions;
104 QList<VTFont> fonts;
105 int cfont;
106 QCString se_pgm;
107 QStrList se_args;
108
109 QPopupMenu* fontList;
110
111 // history scrolling I think
112 bool b_scroll;
113
114 int n_keytab;
115 int n_scroll;
116 int n_render;
117 QString pmPath; // pixmap path
118 QString dropText;
119 QFont defaultFont;
120 QSize defaultSize;
121
122};
123
124#endif
125
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 @@
1/* ---------------------------------------------------------------------- */
2/* */
3/* [main.C] Konsole */
4/* */
5/* ---------------------------------------------------------------------- */
6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */
9/* This file is part of Konsole, an X terminal. */
10/* */
11/* The material contained in here more or less directly orginates from */
12/* kvt, which is copyright (c) 1996 by Matthias Ettrich <ettrich@kde.org> */
13/* */
14/* ---------------------------------------------------------------------- */
15 /* */
16/* Ported Konsole to Qt/Embedded */
17 /* */
18/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
19 /* */
20/* -------------------------------------------------------------------------- */
21
22#include "konsole.h"
23
24#include <qpe/qpeapplication.h>
25
26#include <qfile.h>
27
28#include <unistd.h>
29#include <stdio.h>
30#include <stdlib.h>
31
32
33/* --| main |------------------------------------------------------ */
34int main(int argc, char* argv[])
35{
36 setuid(getuid()); setgid(getgid()); // drop privileges
37
38 QPEApplication a( argc, argv );
39
40#ifdef FAKE_CTRL_AND_ALT
41 QPEApplication::grabKeyboard(); // for CTRL and ALT
42#endif
43
44 QStrList tmp;
45 const char* shell = getenv("SHELL");
46 if (shell == NULL || *shell == '\0')
47 shell = "/bin/sh";
48
49 // sh is completely broken on familiar. Let's try to get something better
50 if ( qstrcmp( shell, "/bin/shell" ) == 0 && QFile::exists( "/bin/bash" ) )
51 shell = "/bin/bash";
52
53 putenv((char*)"COLORTERM="); // to trigger mc's color detection
54
55 Konsole m( "test", shell, tmp, TRUE );
56 m.setCaption( Konsole::tr("Terminal") );
57 a.showMainWidget( &m );
58
59 return a.exec();
60}
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 @@
1Files: bin/embeddedkonsole apps/Applications/embeddedkonsole.desktop pics/konsole etc/keytabs/*
2Priority: optional
3Section: qpe/applications
4Maintainer: Warwick Allison <warwick@trolltech.com>
5Architecture: arm
6Version: $QPE_VERSION-4
7Depends: qpe-base ($QPE_VERSION), ptydevs
8Description: KDE's konsole (shell terminal)
9 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 @@
1/* -------------------------------------------------------------------------- */
2 /* */
3/* Ported Konsole to Qt/Embedded */
4 /* */
5/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
6 /* */
7/* -------------------------------------------------------------------------- */
8#include "session.h"
9#include <qpushbutton.h>
10// #include <kdebug.h>
11
12#include <stdlib.h>
13
14#define HERE fprintf(stderr,"%s(%d): here\n",__FILE__,__LINE__)
15
16/*! \class TESession
17
18 Sessions are combinations of TEPTy and Emulations.
19
20 The stuff in here does not belong to the terminal emulation framework,
21 but to main.C. It serves it's duty by providing a single reference
22 to TEPTy/Emulation pairs. In fact, it is only there to demonstrate one
23 of the abilities of the framework - multible sessions.
24*/
25
26TESession::TESession(QMainWindow* main, TEWidget* te, const char* _pgm, QStrList & _args, const char *_term) : schema_no(0), font_no(3), pgm(_pgm), args(_args)
27{
28 // sh = new TEPty();
29 sh = new MyPty();
30 em = new TEmuVt102(te);
31
32 term = _term;
33
34 sh->setSize(te->Lines(),te->Columns()); // not absolutely nessesary
35 QObject::connect( sh,SIGNAL(block_in(const char*,int)),
36 em,SLOT(onRcvBlock(const char*,int)) );
37 QObject::connect( em,SIGNAL(ImageSizeChanged(int,int)),
38 sh,SLOT(setSize(int,int)));
39
40 // 'main' should do those connects itself, somehow.
41 // These aren't KTMW's slots, but konsole's.(David)
42
43/*
44 QObject::connect( em,SIGNAL(ImageSizeChanged(int,int)),
45 main,SLOT(notifySize(int,int)));
46*/
47 QObject::connect( em,SIGNAL(sndBlock(const char*,int)),
48 sh,SLOT(send_bytes(const char*,int)) );
49 QObject::connect( em,SIGNAL(changeColumns(int)),
50 main,SLOT(changeColumns(int)) );
51/*
52 QObject::connect( em,SIGNAL(changeTitle(int, const QString&)),
53 main,SLOT(changeTitle(int, const QString&)) );
54*/
55 QObject::connect( sh,SIGNAL(done(int)), this,SLOT(done(int)) );
56}
57
58
59
60void TESession::run()
61{
62 //kdDebug() << "Running the session!" << pgm << "\n";
63 sh->run(pgm,args,term.data(),FALSE);
64}
65
66void TESession::kill(int ) // signal)
67{
68// sh->kill(signal);
69}
70
71TESession::~TESession()
72{
73 QObject::disconnect( sh, SIGNAL( done( int ) ),
74 this, SLOT( done( int ) ) );
75 delete em;
76 delete sh;
77}
78
79void TESession::setConnect(bool c)
80{
81 em->setConnect(c);
82}
83
84void TESession::done(int status)
85{
86 emit done(this,status);
87}
88
89void TESession::terminate()
90{
91 delete this;
92}
93
94TEmulation* TESession::getEmulation()
95{
96 return em;
97}
98
99// following interfaces might be misplaced ///
100
101int TESession::schemaNo()
102{
103 return schema_no;
104}
105
106int TESession::keymap()
107{
108 return keymap_no;
109}
110
111int TESession::fontNo()
112{
113 return font_no;
114}
115
116const char* TESession::emuName()
117{
118 return term.data();
119}
120
121void TESession::setSchemaNo(int sn)
122{
123 schema_no = sn;
124}
125
126void TESession::setKeymapNo(int kn)
127{
128 keymap_no = kn;
129 em->setKeytrans(kn);
130}
131
132void TESession::setFontNo(int fn)
133{
134 font_no = fn;
135}
136
137void TESession::setTitle(const QString& title)
138{
139 this->title = title;
140}
141
142const QString& TESession::Title()
143{
144 return title;
145}
146
147void TESession::setHistory(bool on)
148{
149 em->setHistory( on );
150}
151
152bool TESession::history()
153{
154 return em->history();
155}
156
157// #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 @@
1/* -------------------------------------------------------------------------- */
2/* */
3/* [session.h] Testbed for TE framework */
4/* */
5/* -------------------------------------------------------------------------- */
6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */
9/* This file is part of Konsole, an X terminal. */
10/* */
11/* -------------------------------------------------------------------------- */
12 /* */
13/* Ported Konsole to Qt/Embedded */
14 /* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16 /* */
17/* -------------------------------------------------------------------------- */
18
19#ifndef SESSION_H
20#define SESSION_H
21
22#include <qapplication.h>
23#include <qmainwindow.h>
24#include <qstrlist.h>
25
26#include "MyPty.h"
27#include "TEWidget.h"
28#include "TEmuVt102.h"
29
30class TESession : public QObject
31{ Q_OBJECT
32
33public:
34
35 TESession(QMainWindow* main, TEWidget* w,
36 const char* pgm, QStrList & _args,
37 const char* term);
38 ~TESession();
39
40public:
41
42 void setConnect(bool r);
43 TEmulation* getEmulation(); // to control emulation
44 bool isSecure();
45
46public:
47
48 int schemaNo();
49 int fontNo();
50 const char* emuName();
51 const QString& Title();
52 bool history();
53 int keymap();
54
55 void setHistory(bool on);
56 void setSchemaNo(int sn);
57 void setKeymapNo(int kn);
58 void setFontNo(int fn);
59 void setTitle(const QString& title);
60 void kill(int signal);
61
62public slots:
63
64 void run();
65 void done(int status);
66 void terminate();
67
68signals:
69
70 void done(TESession*, int);
71
72private:
73
74 // TEPty* sh;
75 MyPty* sh;
76 TEWidget* te;
77 TEmulation* em;
78
79 //FIXME: using the indices here
80 // is propably very bad. We should
81 // use a persistent reference instead.
82 int schema_no;
83 int font_no;
84 int keymap_no;
85 QString title;
86
87 const char* pgm;
88 QStrList args;
89
90 QCString term;
91};
92
93#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 @@
1moc_*
2Makefile
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 @@
1#############################################################################
2
3####### Compiler, tools and options
4
5 CXX =$(SYSCONF_CXX) $(QT_CXX_MT)
6 CXXFLAGS=$(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
7 CC =$(SYSCONF_CC) $(QT_C_MT)
8 CFLAGS =$(SYSCONF_CFLAGS)
9 INCPATH =-I$(QPEDIR)/include
10 LFLAGS =$(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
11 LIBS =$(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
12 MOC =$(SYSCONF_MOC)
13 UIC =$(SYSCONF_UIC)
14
15####### Target
16
17DESTDIR = $(QPEDIR)/bin/
18VER_MAJ = 1
19VER_MIN = 0
20VER_PATCH = 0
21 TARGET= helpbrowser
22TARGET1 = lib$(TARGET).so.$(VER_MAJ)
23
24####### Files
25
26 HEADERS =helpbrowser.h
27 SOURCES =helpbrowser.cpp \
28 main.cpp
29 OBJECTS =helpbrowser.o \
30 main.o
31INTERFACES =
32UICDECLS =
33UICIMPLS =
34 SRCMOC =moc_helpbrowser.cpp
35 OBJMOC =moc_helpbrowser.o
36
37
38####### Implicit rules
39
40.SUFFIXES: .cpp .cxx .cc .C .c
41
42.cpp.o:
43 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
44
45.cxx.o:
46 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
47
48.cc.o:
49 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
50
51.C.o:
52 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
53
54.c.o:
55 $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
56
57####### Build rules
58
59
60all: $(DESTDIR)$(TARGET)
61
62$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
63 $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
64
65moc: $(SRCMOC)
66
67tmake:
68 tmake helpbrowser.pro
69
70clean:
71 -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
72 -rm -f *~ core
73 -rm -f allmoc.cpp
74
75####### Extension Modules
76
77listpromodules:
78 @echo
79
80listallmodules:
81 @echo
82
83listaddonpromodules:
84 @echo
85
86listaddonentmodules:
87 @echo
88
89
90REQUIRES=
91
92####### Sub-libraries
93
94
95###### Combined headers
96
97
98
99####### Compile
100
101helpbrowser.o: helpbrowser.cpp \
102 helpbrowser.h \
103 $(QPEDIR)/include/qpe/qpeapplication.h \
104 $(QPEDIR)/include/qpe/resource.h \
105 $(QPEDIR)/include/qpe/global.h \
106 $(QPEDIR)/include/qpe/qpemenubar.h \
107 $(QPEDIR)/include/qpe/qpetoolbar.h
108
109main.o: main.cpp \
110 helpbrowser.h \
111 $(QPEDIR)/include/qpe/qpeapplication.h
112
113moc_helpbrowser.o: moc_helpbrowser.cpp \
114 helpbrowser.h
115
116moc_helpbrowser.cpp: helpbrowser.h
117 $(MOC) helpbrowser.h -o moc_helpbrowser.cpp
118
119
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "helpbrowser.h"
22
23#include <qpe/qpeapplication.h>
24#include <qpe/resource.h>
25#include <qpe/global.h>
26
27#include <qstatusbar.h>
28#include <qdragobject.h>
29#include <qpixmap.h>
30#include <qpopupmenu.h>
31#include <qpe/qpemenubar.h>
32#include <qpe/qpetoolbar.h>
33#include <qtoolbutton.h>
34#include <qiconset.h>
35#include <qfile.h>
36#include <qtextstream.h>
37#include <qstylesheet.h>
38#include <qmessagebox.h>
39#include <qfiledialog.h>
40#include <qevent.h>
41#include <qlineedit.h>
42#include <qobjectlist.h>
43#include <qfileinfo.h>
44#include <qfile.h>
45#include <qdatastream.h>
46#include <qprinter.h>
47#include <qsimplerichtext.h>
48#include <qpaintdevicemetrics.h>
49#include <qaction.h>
50
51#include <ctype.h>
52
53
54HelpBrowser::HelpBrowser( QWidget* parent, const char *name, WFlags f )
55 : QMainWindow( parent, name, f ),
56 selectedURL()
57{
58 init( "index.html" );
59}
60
61void HelpBrowser::init( const QString& _home )
62{
63 setIcon( Resource::loadPixmap( "help_icon" ) );
64
65 browser = new QTextBrowser( this );
66 browser->setFrameStyle( QFrame::Panel | QFrame::Sunken );
67 connect( browser, SIGNAL( textChanged() ),
68 this, SLOT( textChanged() ) );
69
70 setCentralWidget( browser );
71 setToolBarsMovable( FALSE );
72
73 if ( !_home.isEmpty() )
74 browser->setSource( _home );
75
76 QPEToolBar* toolbar = new QPEToolBar( this );
77 toolbar->setHorizontalStretchable( TRUE );
78 QPEMenuBar *menu = new QPEMenuBar( toolbar );
79
80 toolbar = new QPEToolBar( this );
81 // addToolBar( toolbar, "Toolbar");
82
83 //QPopupMenu* go = new QPopupMenu( this );
84 backAction = new QAction( tr( "Backward" ), Resource::loadIconSet( "back" ), QString::null, 0, this, 0 );
85 connect( backAction, SIGNAL( activated() ), browser, SLOT( backward() ) );
86 connect( browser, SIGNAL( backwardAvailable( bool ) ),
87 backAction, SLOT( setEnabled( bool ) ) );
88 //backAction->addTo( go );
89 backAction->addTo( toolbar );
90 backAction->setEnabled( FALSE );
91
92 forwardAction = new QAction( tr( "Forward" ), Resource::loadIconSet( "forward" ), QString::null, 0, this, 0 );
93 connect( forwardAction, SIGNAL( activated() ), browser, SLOT( forward() ) );
94 connect( browser, SIGNAL( forwardAvailable( bool ) ),
95 forwardAction, SLOT( setEnabled( bool ) ) );
96 //forwardAction->addTo( go );
97 forwardAction->addTo( toolbar );
98 forwardAction->setEnabled( FALSE );
99
100 QAction *a = new QAction( tr( "Home" ), Resource::loadPixmap( "home" ), QString::null, 0, this, 0 );
101 connect( a, SIGNAL( activated() ), browser, SLOT( home() ) );
102 //a->addTo( go );
103 a->addTo( toolbar );
104
105 bookm = new QPopupMenu( this );
106 bookm->insertItem( tr( "Add Bookmark" ), this, SLOT( addBookmark() ) );
107 bookm->insertItem( tr( "Remove from Bookmarks" ), this, SLOT( removeBookmark() ) );
108 bookm->insertSeparator();
109 connect( bookm, SIGNAL( activated( int ) ),
110 this, SLOT( bookmChosen( int ) ) );
111
112 readBookmarks();
113
114 //menu->insertItem( tr("Go"), go );
115 menu->insertItem( tr( "Bookmarks" ), bookm );
116
117 resize( 240, 300 );
118 browser->setFocus();
119
120 connect( qApp, SIGNAL(appMessage(const QCString&, const QByteArray&)),
121 this, SLOT(appMessage(const QCString&, const QByteArray&)) );
122}
123
124void HelpBrowser::appMessage(const QCString& msg, const QByteArray& data)
125{
126 if ( msg == "showFile(QString)" ) {
127 QDataStream ds(data,IO_ReadOnly);
128 QString fn;
129 ds >> fn;
130 setDocument( fn );
131 }
132}
133
134void HelpBrowser::setDocument( const QString &doc )
135{
136 if ( !doc.isEmpty() )
137 browser->setSource( doc );
138 raise();
139}
140
141
142void HelpBrowser::textChanged()
143{
144 if ( browser->documentTitle().isNull() )
145 setCaption( tr("Help Browser") );
146 else
147 setCaption( browser->documentTitle() ) ;
148
149 selectedURL = caption();
150}
151
152HelpBrowser::~HelpBrowser()
153{
154 QStringList bookmarks;
155 QMap<int, Bookmark>::Iterator it2 = mBookmarks.begin();
156 for ( ; it2 != mBookmarks.end(); ++it2 )
157 bookmarks.append( (*it2).name + "=" + (*it2).file );
158
159 QFile f2( Global::applicationFileName("helpbrowser", "bookmarks") );
160 if ( f2.open( IO_WriteOnly ) ) {
161 QDataStream s2( &f2 );
162 s2 << bookmarks;
163 f2.close();
164 }
165}
166
167void HelpBrowser::pathSelected( const QString &_path )
168{
169 browser->setSource( _path );
170}
171
172void HelpBrowser::readBookmarks()
173{
174 QString file = Global::applicationFileName("helpbrowser", "bookmarks");
175 if ( QFile::exists( file ) ) {
176 QStringList bookmarks;
177 QFile f( file );
178 if ( f.open( IO_ReadOnly ) ) {
179 QDataStream s( &f );
180 s >> bookmarks;
181 f.close();
182 }
183 QStringList::Iterator it = bookmarks.begin();
184 for ( ; it != bookmarks.end(); ++it ) {
185 Bookmark b;
186 QString current = *it;
187 int equal = current.find( "=" );
188 if ( equal < 1 || equal == (int)current.length() - 1 )
189 continue;
190 b.name = current.left( equal );
191 b.file = current.mid( equal + 1 );
192 mBookmarks[ bookm->insertItem( b.name ) ] = b;
193 }
194 }
195}
196
197void HelpBrowser::bookmChosen( int i )
198{
199 if ( mBookmarks.contains( i ) )
200 browser->setSource( mBookmarks[ i ].file );
201}
202
203void HelpBrowser::addBookmark()
204{
205 Bookmark b;
206 b.name = browser->documentTitle();
207 b.file = browser->source();
208 if (b.name.isEmpty() ) {
209 b.name = b.file.left( b.file.length() - 5 ); // remove .html
210 }
211 QMap<int, Bookmark>::Iterator it;
212 for( it = mBookmarks.begin(); it != mBookmarks.end(); ++it )
213 if ( (*it).file == b.file ) return;
214 mBookmarks[ bookm->insertItem( b.name ) ] = b;
215}
216
217void HelpBrowser::removeBookmark()
218{
219 QString file = browser->source();
220 QMap<int, Bookmark>::Iterator it = mBookmarks.begin();
221 for( ; it != mBookmarks.end(); ++it )
222 if ( (*it).file == file ) {
223 bookm->removeItem( it.key() );
224 mBookmarks.remove( it );
225 break;
226 }
227}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#ifndef HELPWINDOW_H
22#define HELPWINDOW_H
23
24#include <qmainwindow.h>
25#include <qtextbrowser.h>
26#include <qstringlist.h>
27#include <qmap.h>
28
29class QPopupMenu;
30class QAction;
31
32class HelpBrowser : public QMainWindow
33{
34 Q_OBJECT
35public:
36 HelpBrowser( QWidget* parent = 0, const char *name=0, WFlags f=0 );
37 ~HelpBrowser();
38
39public slots:
40 void setDocument( const QString &doc );
41
42private slots:
43 void appMessage(const QCString& msg, const QByteArray& data);
44 void textChanged();
45
46 void pathSelected( const QString & );
47 void bookmChosen( int );
48 void addBookmark();
49 void removeBookmark();
50
51private:
52 void init( const QString & );
53 void readBookmarks();
54
55 QTextBrowser* browser;
56 QAction *backAction;
57 QAction *forwardAction;
58 QString selectedURL;
59 struct Bookmark {
60 QString name;
61 QString file;
62 };
63 QMap<int, Bookmark> mBookmarks;
64 QMenuBar *menu;
65 QPopupMenu *bookm;
66};
67
68#endif
69
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 @@
1 TEMPLATE= app
2 CONFIG = qt warn_on release
3 DESTDIR = $(QPEDIR)/bin
4 HEADERS = helpbrowser.h
5 SOURCES = helpbrowser.cpp \
6 main.cpp
7INCLUDEPATH += $(QPEDIR)/include
8 DEPENDPATH+= $(QPEDIR)/include
9LIBS += -lqpe
10 INTERFACES=
11
12TRANSLATIONS = ../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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "helpbrowser.h"
22
23#include <qpe/qpeapplication.h>
24
25int main( int argc, char ** argv )
26{
27 QPEApplication a( argc, argv );
28
29 HelpBrowser mw;
30 mw.setCaption( HelpBrowser::tr("HelpBrowser") );
31 a.showMainDocumentWidget( &mw );
32
33 return a.exec();
34}
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 @@
1Files: bin/helpbrowser apps/Applications/helpbrowser.desktop docs
2Priority: optional
3Section: qpe/applications
4Maintainer: Warwick Allison <warwick@trolltech.com>
5Architecture: arm
6Arch: iPAQ
7Version: $QPE_VERSION-3
8Depends: qpe-base ($QPE_VERSION)
9Description: Browse HTML help documents
10 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 @@
1moc_*
2*.moc
3Makefile
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 @@
1#############################################################################
2
3####### Compiler, tools and options
4
5 CXX =$(SYSCONF_CXX) $(QT_CXX_MT)
6 CXXFLAGS=$(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
7 CC =$(SYSCONF_CC) $(QT_C_MT)
8 CFLAGS =$(SYSCONF_CFLAGS)
9 INCPATH =-I$(QPEDIR)/include
10 LFLAGS =$(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
11 LIBS =$(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
12 MOC =$(SYSCONF_MOC)
13 UIC =$(SYSCONF_UIC)
14
15####### Target
16
17DESTDIR = ../bin/
18VER_MAJ = 1
19VER_MIN = 0
20VER_PATCH = 0
21 TARGET= qcop
22TARGET1 = lib$(TARGET).so.$(VER_MAJ)
23
24####### Files
25
26 HEADERS =
27 SOURCES =main.cpp
28 OBJECTS =main.o
29INTERFACES =
30UICDECLS =
31UICIMPLS =
32 SRCMOC =
33 OBJMOC =
34
35
36####### Implicit rules
37
38.SUFFIXES: .cpp .cxx .cc .C .c
39
40.cpp.o:
41 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
42
43.cxx.o:
44 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
45
46.cc.o:
47 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
48
49.C.o:
50 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
51
52.c.o:
53 $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
54
55####### Build rules
56
57
58all: $(DESTDIR)$(TARGET)
59
60$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
61 $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
62
63moc: $(SRCMOC)
64
65tmake:
66 tmake qcop.pro
67
68clean:
69 -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
70 -rm -f *~ core
71 -rm -f allmoc.cpp
72
73####### Extension Modules
74
75listpromodules:
76 @echo
77
78listallmodules:
79 @echo
80
81listaddonpromodules:
82 @echo
83
84listaddonentmodules:
85 @echo
86
87
88REQUIRES=
89
90####### Sub-libraries
91
92
93###### Combined headers
94
95
96
97####### Compile
98
99main.o: main.cpp \
100 $(QPEDIR)/include/qpe/qcopenvelope_qws.h
101
102
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include <qpe/qcopenvelope_qws.h>
22
23#include <qapplication.h>
24#include <qstringlist.h>
25#include <qdatastream.h>
26#include <qtimer.h>
27
28#include <stdlib.h>
29#include <stdio.h>
30
31static void usage()
32{
33 fprintf( stderr, "Usage: qcop channel command [parameters]\n" );
34}
35
36static void syntax( const QString &where, const QString &what )
37{
38 fprintf( stderr, "Syntax error in %s: %s\n", where.latin1(), what.latin1() );
39 exit(1);
40}
41
42int main( int argc, char *argv[] )
43{
44 QApplication app( argc, argv );
45
46 if ( argc < 3 ) {
47 usage();
48 exit(1);
49 }
50
51 QString channel = argv[1];
52 QString command = argv[2];
53 command.stripWhiteSpace();
54
55 int paren = command.find( "(" );
56 if ( paren <= 0 )
57 syntax( "command", command );
58
59 QString params = command.mid( paren + 1 );
60 if ( params[params.length()-1] != ')' )
61 syntax( "command", command );
62
63 params.truncate( params.length()-1 );
64 QCopEnvelope env(channel.latin1(), command.latin1());
65
66 int argIdx = 3;
67
68 QStringList paramList = QStringList::split( ",", params );
69 QStringList::Iterator it;
70 for ( it = paramList.begin(); it != paramList.end(); ++it ) {
71 QString arg = argv[argIdx];
72 if ( *it == "QString" ) {
73 env << arg;
74 } else if ( *it == "int" ) {
75 env << arg.toInt();
76 } else {
77 syntax( "paramter type", *it );
78 }
79 argIdx++;
80 }
81
82 QTimer::singleShot( 0, &app, SLOT(quit()) );
83 return app.exec();
84}
85
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 @@
1 TEMPLATE= app
2 CONFIG = qt warn_on release
3 DESTDIR = ../bin
4 HEADERS =
5 SOURCES = main.cpp
6INCLUDEPATH += $(QPEDIR)/include
7 DEPENDPATH+= $(QPEDIR)/include
8LIBS += -lqpe
9 INTERFACES=
10 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 @@
1Files: bin/qcop
2Priority: required
3Section: qpe/system
4Maintainer: Martin Jones <mjones@trolltech.com>
5Architecture: arm
6Version: $QPE_VERSION-3
7Depends: qt-embedded (>=$QTE_VERSION)
8Description: Interprocess communication client
9 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 @@
1moc_*
2*.moc
3Makefile
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 @@
1#############################################################################
2
3####### Compiler, tools and options
4
5 CXX =$(SYSCONF_CXX) $(QT_CXX_MT)
6 CXXFLAGS=$(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
7 CC =$(SYSCONF_CC) $(QT_C_MT)
8 CFLAGS =$(SYSCONF_CFLAGS)
9 INCPATH =-I$(QPEDIR)/include
10 LFLAGS =$(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
11 LIBS =$(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
12 MOC =$(SYSCONF_MOC)
13 UIC =$(SYSCONF_UIC)
14
15####### Target
16
17DESTDIR = $(QPEDIR)/bin/
18VER_MAJ = 1
19VER_MIN = 0
20VER_PATCH = 0
21 TARGET= textedit
22TARGET1 = lib$(TARGET).so.$(VER_MAJ)
23
24####### Files
25
26 HEADERS =textedit.h
27 SOURCES =main.cpp \
28 textedit.cpp
29 OBJECTS =main.o \
30 textedit.o
31INTERFACES =
32UICDECLS =
33UICIMPLS =
34 SRCMOC =moc_textedit.cpp
35 OBJMOC =moc_textedit.o
36
37
38####### Implicit rules
39
40.SUFFIXES: .cpp .cxx .cc .C .c
41
42.cpp.o:
43 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
44
45.cxx.o:
46 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
47
48.cc.o:
49 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
50
51.C.o:
52 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
53
54.c.o:
55 $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
56
57####### Build rules
58
59
60all: $(DESTDIR)$(TARGET)
61
62$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
63 $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
64
65moc: $(SRCMOC)
66
67tmake:
68 tmake textedit.pro
69
70clean:
71 -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
72 -rm -f *~ core
73 -rm -f allmoc.cpp
74
75####### Extension Modules
76
77listpromodules:
78 @echo
79
80listallmodules:
81 @echo
82
83listaddonpromodules:
84 @echo
85
86listaddonentmodules:
87 @echo
88
89
90REQUIRES=
91
92####### Sub-libraries
93
94
95###### Combined headers
96
97
98
99####### Compile
100
101main.o: main.cpp \
102 textedit.h \
103 $(QPEDIR)/include/qpe/filemanager.h \
104 $(QPEDIR)/include/qpe/qpeapplication.h
105
106textedit.o: textedit.cpp \
107 textedit.h \
108 $(QPEDIR)/include/qpe/filemanager.h \
109 $(QPEDIR)/include/qpe/global.h \
110 $(QPEDIR)/include/qpe/fileselector.h \
111 $(QPEDIR)/include/qpe/applnk.h \
112 $(QPEDIR)/include/qpe/resource.h \
113 $(QPEDIR)/include/qpe/config.h \
114 $(QPEDIR)/include/qpe/qpeapplication.h \
115 $(QPEDIR)/include/qpe/qpemenubar.h \
116 $(QPEDIR)/include/qpe/qpetoolbar.h
117
118moc_textedit.o: moc_textedit.cpp \
119 textedit.h \
120 $(QPEDIR)/include/qpe/filemanager.h
121
122moc_textedit.cpp: textedit.h
123 $(MOC) textedit.h -o moc_textedit.cpp
124
125
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 @@
1<!DOCTYPE UI><UI>
2<class>InsertTable</class><comment>*********************************************************************
3** Copyright (C) 2000 Trolltech AS. All rights reserved.
4**
5** This file is part of Qtopia Environment.
6**
7** This file may be distributed and/or modified under the terms of the
8** GNU General Public License version 2 as published by the Free Software
9** Foundation and appearing in the file LICENSE.GPL included in the
10** packaging of this file.
11**
12** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
13** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
14**
15** See http://www.trolltech.com/gpl/ for GPL licensing information.
16**
17** Contact info@trolltech.com if any conditions of this licensing are
18** not clear to you.
19**
20*********************************************************************</comment>
21<widget>
22 <class>QDialog</class>
23 <property stdset="1">
24 <name>name</name>
25 <cstring>InsertTable</cstring>
26 </property>
27 <property stdset="1">
28 <name>geometry</name>
29 <rect>
30 <x>0</x>
31 <y>0</y>
32 <width>165</width>
33 <height>79</height>
34 </rect>
35 </property>
36 <property stdset="1">
37 <name>caption</name>
38 <string>Insert Table</string>
39 </property>
40 <grid>
41 <property stdset="1">
42 <name>margin</name>
43 <number>11</number>
44 </property>
45 <property stdset="1">
46 <name>spacing</name>
47 <number>6</number>
48 </property>
49 <widget row="0" column="0" >
50 <class>QLabel</class>
51 <property stdset="1">
52 <name>name</name>
53 <cstring>TextLabel1</cstring>
54 </property>
55 <property stdset="1">
56 <name>text</name>
57 <string>Rows:</string>
58 </property>
59 </widget>
60 <widget row="0" column="1" >
61 <class>QSpinBox</class>
62 <property stdset="1">
63 <name>name</name>
64 <cstring>spinRows</cstring>
65 </property>
66 <property stdset="1">
67 <name>minValue</name>
68 <number>1</number>
69 </property>
70 <property stdset="1">
71 <name>value</name>
72 <number>1</number>
73 </property>
74 </widget>
75 <widget row="1" column="1" >
76 <class>QSpinBox</class>
77 <property stdset="1">
78 <name>name</name>
79 <cstring>spinColumns</cstring>
80 </property>
81 <property stdset="1">
82 <name>minValue</name>
83 <number>1</number>
84 </property>
85 <property stdset="1">
86 <name>value</name>
87 <number>1</number>
88 </property>
89 </widget>
90 <widget row="1" column="0" >
91 <class>QLabel</class>
92 <property stdset="1">
93 <name>name</name>
94 <cstring>TextLabel1_2</cstring>
95 </property>
96 <property stdset="1">
97 <name>text</name>
98 <string>Columns:</string>
99 </property>
100 </widget>
101 </grid>
102</widget>
103</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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "textedit.h"
22
23#include <qpe/qpeapplication.h>
24
25int main( int argc, char **argv )
26{
27 QPEApplication a( argc, argv );
28
29 TextEdit e;
30 a.showMainDocumentWidget(&e);
31 if ( argc == 3 && argv[1] == QCString("-f") )
32 e.openFile(argv[2]);
33
34 a.exec();
35}
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 @@
1Files: bin/textedit apps/Applications/textedit.desktop
2Priority: optional
3Section: qpe/applications
4Maintainer: Warwick Allison <warwick@trolltech.com>
5Architecture: arm
6Version: $QPE_VERSION-3
7Depends: qpe-base ($QPE_VERSION)
8Description: Text Editor
9 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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#ifndef QTEXTEDIT_H
22#define QTEXTEDIT_H
23
24#include <qscrollview.h>
25#include <qstylesheet.h>
26#include <qpainter.h>
27
28class QPainter;
29class QTextDocument;
30class QTextCursor;
31class QKeyEvent;
32class QResizeEvent;
33class QMouseEvent;
34class QTimer;
35class QTextString;
36class QVBox;
37class QListBox;
38class QTextCommand;
39class QTextParag;
40class QTextFormat;
41class QFont;
42class QColor;
43
44class QTextEdit : public QScrollView
45{
46 Q_OBJECT
47
48public:
49 QTextEdit( QWidget *parent, const QString &fn, bool tabify = FALSE );
50 QTextEdit( QWidget *parent = 0, const char *name = 0 );
51 virtual ~QTextEdit();
52
53#if defined(QTEXTEDIT_OPEN_API)
54 QTextDocument *document() const;
55 QTextCursor *textCursor() const;
56#endif
57
58 QString text() const;
59 QString text( int parag, bool formatted = FALSE ) const;
60 Qt::TextFormat textFormat() const;
61 QString fileName() const;
62
63 void cursorPosition( int &parag, int &index );
64 void selection( int &parag_from, int &index_from,
65 int &parag_to, int &index_to );
66 virtual bool find( const QString &expr, bool cs, bool wo, bool forward = TRUE,
67 int *parag = 0, int *index = 0 );
68 void insert( const QString &text, bool indent = FALSE, bool checkNewLine = FALSE );
69
70 int paragraphs() const;
71 int lines() const;
72 int linesOfParagraph( int parag ) const;
73 int lineOfChar( int parag, int chr );
74
75 bool isModified() const;
76
77 bool italic() const;
78 bool bold() const;
79 bool underline() const;
80 QString family() const;
81 int pointSize() const;
82 QColor color() const;
83 QFont font() const;
84 int alignment() const;
85 int maxLines() const;
86
87 const QStyleSheet* styleSheet() const;
88 void setStyleSheet( const QStyleSheet* styleSheet );
89
90 void setPaper( const QBrush& pap);
91 QBrush paper() const;
92
93 void setLinkColor( const QColor& );
94 QColor linkColor() const;
95
96 void setLinkUnderline( bool );
97 bool linkUnderline() const;
98
99 void setMimeSourceFactory( const QMimeSourceFactory* factory );
100 const QMimeSourceFactory* mimeSourceFactory() const;
101
102 int heightForWidth( int w ) const;
103
104 void append( const QString& text );
105
106 bool hasSelectedText() const;
107 QString selectedText() const;
108
109 QString context() const;
110
111 QString documentTitle() const;
112
113 void scrollToAnchor( const QString& name );
114 QString anchorAt(const QPoint& pos);
115
116public slots:
117 virtual void undo();
118 virtual void redo();
119
120 virtual void cut();
121 virtual void copy();
122 virtual void paste();
123
124 virtual void indent();
125
126 virtual void setItalic( bool b );
127 virtual void setBold( bool b );
128 virtual void setUnderline( bool b );
129 virtual void setFamily( const QString &f );
130 virtual void setPointSize( int s );
131 virtual void setColor( const QColor &c );
132 virtual void setFont( const QFont &f );
133
134 virtual void setAlignment( int );
135
136 virtual void setParagType( QStyleSheetItem::DisplayMode, int listStyle );
137
138 virtual void setTextFormat( Qt::TextFormat f );
139 virtual void setText( const QString &txt, const QString &context = QString::null ) { setText( txt, context, FALSE ); }
140 virtual void setText( const QString &txt, const QString &context, bool tabify );
141
142 virtual void load( const QString &fn ) { load( fn, FALSE ); }
143 virtual void load( const QString &fn, bool tabify );
144 virtual void save( bool untabify = FALSE ) { save( QString::null, untabify ); }
145 virtual void save( const QString &fn, bool untabify = FALSE );
146
147 virtual void setCursorPosition( int parag, int index );
148 virtual void setSelection( int parag_from, int index_from,
149 int parag_to, int index_to );
150
151 virtual void setModified( bool m );
152 virtual void selectAll( bool select );
153
154 virtual void setMaxLines( int l );
155 virtual void resetFormat();
156
157signals:
158 void currentFontChanged( const QFont &f );
159 void currentColorChanged( const QColor &c );
160 void currentAlignmentChanged( int );
161 void textChanged();
162 void highlighted( const QString& );
163 void linkClicked( const QString& );
164
165protected:
166 void setFormat( QTextFormat *f, int flags );
167 void drawContents( QPainter *p, int cx, int cy, int cw, int ch );
168 void keyPressEvent( QKeyEvent *e );
169 void resizeEvent( QResizeEvent *e );
170 void contentsMousePressEvent( QMouseEvent *e );
171 void contentsMouseMoveEvent( QMouseEvent *e );
172 void contentsMouseReleaseEvent( QMouseEvent *e );
173 void contentsMouseDoubleClickEvent( QMouseEvent *e );
174#ifndef QT_NO_DRAGANDDROP
175 void contentsDragEnterEvent( QDragEnterEvent *e );
176 void contentsDragMoveEvent( QDragMoveEvent *e );
177 void contentsDragLeaveEvent( QDragLeaveEvent *e );
178 void contentsDropEvent( QDropEvent *e );
179#endif
180 bool eventFilter( QObject *o, QEvent *e );
181 bool focusNextPrevChild( bool next );
182#if !defined(QTEXTEDIT_OPEN_API)
183 QTextDocument *document() const;
184 QTextCursor *textCursor() const;
185#endif
186
187private slots:
188 void formatMore();
189 void doResize();
190 void doAutoScroll();
191 void doChangeInterval();
192 void blinkCursor();
193 void setModified();
194 void startDrag();
195
196private:
197 enum MoveDirection {
198 MoveLeft,
199 MoveRight,
200 MoveUp,
201 MoveDown,
202 MoveHome,
203 MoveEnd,
204 MovePgUp,
205 MovePgDown
206 };
207 enum KeyboardAction {
208 ActionBackspace,
209 ActionDelete,
210 ActionReturn
211 };
212
213 struct UndoRedoInfo {
214 enum Type { Invalid, Insert, Delete, Backspace, Return, RemoveSelected };
215 UndoRedoInfo( QTextDocument *d ) : type( Invalid ), doc( d )
216 { text = QString::null; id = -1; index = -1; }
217 void clear();
218 inline bool valid() const { return !text.isEmpty() && id >= 0&& index >= 0; }
219
220 QString text;
221 int id;
222 int index;
223 Type type;
224 QTextDocument *doc;
225 };
226
227private:
228 virtual bool isReadOnly() const { return FALSE; }
229 virtual bool linksEnabled() const { return TRUE; }
230 void init();
231 void ensureCursorVisible();
232 void drawCursor( bool visible );
233 void placeCursor( const QPoint &pos, QTextCursor *c = 0 );
234 void moveCursor( int direction, bool shift, bool control );
235 void moveCursor( int direction, bool control );
236 void removeSelectedText();
237 void doKeyboardAction( int action );
238 bool doCompletion();
239 void checkUndoRedoInfo( UndoRedoInfo::Type t );
240 void repaintChanged();
241 void updateCurrentFormat();
242 void handleReadOnlyKeyEvent( QKeyEvent *e );
243 void makeParagVisible( QTextParag *p );
244
245private:
246 QTextDocument *doc;
247 QTextCursor *cursor;
248 bool drawAll;
249 bool mousePressed;
250 QTimer *formatTimer, *scrollTimer, *changeIntervalTimer, *blinkTimer, *dragStartTimer, *resizeTimer;
251 QTextParag *lastFormatted;
252 int interval;
253 QVBox *completionPopup;
254 QListBox *completionListBox;
255 int completionOffset;
256 UndoRedoInfo undoRedoInfo;
257 QTextFormat *currentFormat;
258 QPainter painter;
259 int currentAlignment;
260 bool inDoubleClick;
261 QPoint oldMousePos, mousePos;
262 QPixmap *buf_pixmap;
263 bool cursorVisible, blinkCursorVisible;
264 bool readOnly, modified, mightStartDrag;
265 QPoint dragStartPos;
266 int mLines;
267 bool firstResize;
268 QString onLink;
269
270};
271
272inline QTextDocument *QTextEdit::document() const
273{
274 return doc;
275}
276
277inline QTextCursor *QTextEdit::textCursor() const
278{
279 return cursor;
280}
281
282#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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "textedit.h"
22
23#include <qpe/global.h>
24#include <qpe/fileselector.h>
25#include <qpe/applnk.h>
26#include <qpe/resource.h>
27#include <qpe/config.h>
28#include <qpe/qpeapplication.h>
29#include <qpe/qpemenubar.h>
30#include <qpe/qpetoolbar.h>
31//#include <qpe/finddialog.h>
32
33#include <qaction.h>
34#include <qcolordialog.h>
35#include <qfileinfo.h>
36#include <qlineedit.h>
37#include <qmessagebox.h>
38#include <qobjectlist.h>
39#include <qpopupmenu.h>
40#include <qspinbox.h>
41#include <qtoolbutton.h>
42#include <qwidgetstack.h>
43
44#include <stdlib.h> //getenv
45
46
47#if QT_VERSION < 300
48
49class QpeEditor : public QMultiLineEdit
50{
51 // Q_OBJECT
52public:
53 QpeEditor( QWidget *parent, const char * name = 0 )
54 : QMultiLineEdit( parent, name ) {}
55
56 //public slots:
57 void find( const QString &txt, bool caseSensitive,
58 bool backwards );
59 /*
60signals:
61 void notFound();
62 void searchWrapped();
63 */
64
65private:
66
67};
68
69
70void QpeEditor::find ( const QString &txt, bool caseSensitive,
71 bool backwards )
72{
73 static bool wrap = FALSE;
74 int line, col;
75 if ( wrap ) {
76 if ( !backwards )
77 line = col = 0;
78 wrap = FALSE;
79 //emit searchWrapped();
80 } else {
81 getCursorPosition( &line, &col );
82 }
83 //ignore backwards for now....
84 if ( !backwards ) {
85 for ( ; ; ) {
86 if ( line >= numLines() ) {
87 wrap = TRUE;
88 //emit notFound();
89 break;
90 }
91 int findCol = getString( line )->find( txt, col, caseSensitive );
92 if ( findCol >= 0 ) {
93 setCursorPosition( line, findCol, FALSE );
94 col = findCol + txt.length();
95 setCursorPosition( line, col, TRUE );
96
97 //found = TRUE;
98 break;
99 }
100 line++;
101 col = 0;
102 }
103
104 }
105
106}
107
108
109#else
110
111#error "Must make a QpeEditor that inherits QTextEdit"
112
113#endif
114
115
116
117
118static int u_id = 1;
119static int get_unique_id()
120{
121 return u_id++;
122}
123
124static const int nfontsizes = 6;
125static const int fontsize[nfontsizes] = {8,10,12,14,18,24};
126
127TextEdit::TextEdit( QWidget *parent, const char *name, WFlags f )
128 : QMainWindow( parent, name, f ), bFromDocView( FALSE )
129{
130 doc = 0;
131
132 QString lang = getenv( "LANG" );
133
134 setToolBarsMovable( FALSE );
135
136 setIcon( Resource::loadPixmap( "TextEditor" ) );
137
138 QPEToolBar *bar = new QPEToolBar( this );
139 bar->setHorizontalStretchable( TRUE );
140 menu = bar;
141
142 QPEMenuBar *mb = new QPEMenuBar( bar );
143 QPopupMenu *file = new QPopupMenu( this );
144 QPopupMenu *edit = new QPopupMenu( this );
145 QPopupMenu *font = new QPopupMenu( this );
146
147 bar = new QPEToolBar( this );
148 editBar = bar;
149
150 QAction *a = new QAction( tr( "New" ), Resource::loadPixmap( "new" ), QString::null, 0, this, 0 );
151 connect( a, SIGNAL( activated() ), this, SLOT( fileNew() ) );
152 a->addTo( bar );
153 a->addTo( file );
154
155 a = new QAction( tr( "Open" ), Resource::loadPixmap( "fileopen" ), QString::null, 0, this, 0 );
156 connect( a, SIGNAL( activated() ), this, SLOT( fileOpen() ) );
157 a->addTo( bar );
158 a->addTo( file );
159
160 a = new QAction( tr( "Cut" ), Resource::loadPixmap( "cut" ), QString::null, 0, this, 0 );
161 connect( a, SIGNAL( activated() ), this, SLOT( editCut() ) );
162 a->addTo( editBar );
163 a->addTo( edit );
164
165 a = new QAction( tr( "Copy" ), Resource::loadPixmap( "copy" ), QString::null, 0, this, 0 );
166 connect( a, SIGNAL( activated() ), this, SLOT( editCopy() ) );
167 a->addTo( editBar );
168 a->addTo( edit );
169
170 a = new QAction( tr( "Paste" ), Resource::loadPixmap( "paste" ), QString::null, 0, this, 0 );
171 connect( a, SIGNAL( activated() ), this, SLOT( editPaste() ) );
172 a->addTo( editBar );
173 a->addTo( edit );
174
175 a = new QAction( tr( "Find..." ), Resource::loadPixmap( "find" ), QString::null, 0, this, 0 );
176 connect( a, SIGNAL( activated() ), this, SLOT( editFind() ) );
177 edit->insertSeparator();
178 a->addTo( bar );
179 a->addTo( edit );
180
181 int defsize;
182 bool defb, defi, wrap;
183 {
184 Config cfg("TextEdit");
185 cfg.setGroup("View");
186 defsize = cfg.readNumEntry("FontSize",10);
187 defb = cfg.readBoolEntry("Bold",FALSE);
188 defi = cfg.readBoolEntry("Italic",FALSE);
189 wrap = cfg.readBoolEntry("Wrap",TRUE);
190 }
191
192 zin = new QAction( tr("Zoom in"), QString::null, 0, this, 0 );
193 connect( zin, SIGNAL( activated() ), this, SLOT( zoomIn() ) );
194 zin->addTo( font );
195
196 zout = new QAction( tr("Zoom out"), QString::null, 0, this, 0 );
197 connect( zout, SIGNAL( activated() ), this, SLOT( zoomOut() ) );
198 zout->addTo( font );
199
200 font->insertSeparator();
201
202#if 0
203 QAction *ba = new QAction( tr("Bold"), QString::null, 0, this, 0 );
204 connect( ba, SIGNAL( toggled(bool) ), this, SLOT( setBold(bool) ) );
205 ba->setToggleAction(TRUE);
206 ba->addTo( font );
207
208 QAction *ia = new QAction( tr("Italic"), QString::null, 0, this, 0 );
209 connect( ia, SIGNAL( toggled(bool) ), this, SLOT( setItalic(bool) ) );
210 ia->setToggleAction(TRUE);
211 ia->addTo( font );
212
213 ba->setOn(defb);
214 ia->setOn(defi);
215
216 font->insertSeparator();
217#endif
218
219 QAction *wa = new QAction( tr("Wrap lines"), QString::null, 0, this, 0 );
220 connect( wa, SIGNAL( toggled(bool) ), this, SLOT( setWordWrap(bool) ) );
221 wa->setToggleAction(TRUE);
222 wa->addTo( font );
223
224 mb->insertItem( tr( "File" ), file );
225 mb->insertItem( tr( "Edit" ), edit );
226 mb->insertItem( tr( "View" ), font );
227
228 searchBar = new QPEToolBar(this);
229 addToolBar( searchBar, "Search", QMainWindow::Top, TRUE );
230
231 searchBar->setHorizontalStretchable( TRUE );
232
233 searchEdit = new QLineEdit( searchBar, "searchEdit" );
234 searchBar->setStretchableWidget( searchEdit );
235 connect( searchEdit, SIGNAL( textChanged( const QString & ) ),
236 this, SLOT( search() ) );
237
238 a = new QAction( tr( "Find Next" ), Resource::loadPixmap( "next" ), QString::null, 0, this, 0 );
239 connect( a, SIGNAL( activated() ), this, SLOT( findNext() ) );
240 a->addTo( searchBar );
241 a->addTo( edit );
242
243 a = new QAction( tr( "Close Find" ), Resource::loadPixmap( "close" ), QString::null, 0, this, 0 );
244 connect( a, SIGNAL( activated() ), this, SLOT( findClose() ) );
245 a->addTo( searchBar );
246
247 searchBar->hide();
248
249 editorStack = new QWidgetStack( this );
250 setCentralWidget( editorStack );
251
252 searchVisible = FALSE;
253
254 fileSelector = new FileSelector( "text/*", editorStack, "fileselector" ,
255 TRUE, FALSE );
256 fileSelector->setCategoriesVisible(TRUE);
257 connect( fileSelector, SIGNAL( closeMe() ), this, SLOT( showEditTools() ) );
258 connect( fileSelector, SIGNAL( newSelected( const DocLnk &) ), this, SLOT( newFile( const DocLnk & ) ) );
259 connect( fileSelector, SIGNAL( fileSelected( const DocLnk &) ), this, SLOT( openFile( const DocLnk & ) ) );
260 fileOpen();
261
262 editor = new QpeEditor( editorStack );
263 editorStack->addWidget( editor, get_unique_id() );
264
265 resize( 200, 300 );
266
267 setFontSize(defsize,TRUE);
268 wa->setOn(wrap);
269}
270
271TextEdit::~TextEdit()
272{
273 save();
274
275 Config cfg("TextEdit");
276 cfg.setGroup("View");
277 QFont f = editor->font();
278 cfg.writeEntry("FontSize",f.pointSize());
279 cfg.writeEntry("Bold",f.bold());
280 cfg.writeEntry("Italic",f.italic());
281 cfg.writeEntry("Wrap",editor->wordWrap() == QMultiLineEdit::WidgetWidth);
282}
283
284void TextEdit::zoomIn()
285{
286 setFontSize(editor->font().pointSize()+1,FALSE);
287}
288
289void TextEdit::zoomOut()
290{
291 setFontSize(editor->font().pointSize()-1,TRUE);
292}
293
294
295void TextEdit::setFontSize(int sz, bool round_down_not_up)
296{
297 int s=10;
298 for (int i=0; i<nfontsizes; i++) {
299 if ( fontsize[i] == sz ) {
300 s = sz;
301 break;
302 } else if ( round_down_not_up ) {
303 if ( fontsize[i] < sz )
304 s = fontsize[i];
305 } else {
306 if ( fontsize[i] > sz ) {
307 s = fontsize[i];
308 break;
309 }
310 }
311 }
312
313 QFont f = editor->font();
314 f.setPointSize(s);
315 editor->setFont(f);
316
317 zin->setEnabled(s != fontsize[nfontsizes-1]);
318 zout->setEnabled(s != fontsize[0]);
319}
320
321void TextEdit::setBold(bool y)
322{
323 QFont f = editor->font();
324 f.setBold(y);
325 editor->setFont(f);
326}
327
328void TextEdit::setItalic(bool y)
329{
330 QFont f = editor->font();
331 f.setItalic(y);
332 editor->setFont(f);
333}
334
335void TextEdit::setWordWrap(bool y)
336{
337 editor->setWordWrap(y ? QMultiLineEdit::WidgetWidth : QMultiLineEdit::NoWrap );
338}
339
340void TextEdit::fileNew()
341{
342 save();
343 newFile(DocLnk());
344}
345
346void TextEdit::fileOpen()
347{
348 if ( !save() ) {
349 if ( QMessageBox::critical( this, tr( "Out of space" ),
350 tr( "Text Editor was unable to\n"
351 "save your changes.\n"
352 "Free some space and try again.\n"
353 "\nContinue anyway?" ),
354 QMessageBox::Yes|QMessageBox::Escape,
355 QMessageBox::No|QMessageBox::Default )
356 != QMessageBox::Yes )
357 return;
358 else {
359 delete doc;
360 doc = 0;
361 }
362 }
363 menu->hide();
364 editBar->hide();
365 searchBar->hide();
366 clearWState (WState_Reserved1 );
367 editorStack->raiseWidget( fileSelector );
368 fileSelector->reread();
369 updateCaption();
370}
371
372
373#if 0
374void TextEdit::slotFind()
375{
376 FindDialog frmFind( "Text Editor", this );
377 connect( &frmFind, SIGNAL(signalFindClicked(const QString &, bool, bool, int)),
378 editor, SLOT(slotDoFind( const QString&,bool,bool)));
379
380 //case sensitive, backwards, [category]
381
382
383 connect( editor, SIGNAL(notFound()),
384 &frmFind, SLOT(slotNotFound()) );
385 connect( editor, SIGNAL(searchWrapped()),
386 &frmFind, SLOT(slotWrapAround()) );
387
388 frmFind.exec();
389
390
391}
392#endif
393
394void TextEdit::fileRevert()
395{
396 clear();
397 fileOpen();
398}
399
400void TextEdit::editCut()
401{
402#ifndef QT_NO_CLIPBOARD
403 editor->cut();
404#endif
405}
406
407void TextEdit::editCopy()
408{
409#ifndef QT_NO_CLIPBOARD
410 editor->copy();
411#endif
412}
413
414void TextEdit::editPaste()
415{
416#ifndef QT_NO_CLIPBOARD
417 editor->paste();
418#endif
419}
420
421void TextEdit::editFind()
422{
423 searchBar->show();
424 searchVisible = TRUE;
425 searchEdit->setFocus();
426}
427
428void TextEdit::findNext()
429{
430 editor->find( searchEdit->text(), FALSE, FALSE );
431
432}
433
434void TextEdit::findClose()
435{
436 searchVisible = FALSE;
437 searchBar->hide();
438}
439
440void TextEdit::search()
441{
442 editor->find( searchEdit->text(), FALSE, FALSE );
443}
444
445void TextEdit::newFile( const DocLnk &f )
446{
447 DocLnk nf = f;
448 nf.setType("text/plain");
449 clear();
450 editorStack->raiseWidget( editor );
451 setWState (WState_Reserved1 );
452 editor->setFocus();
453 doc = new DocLnk(nf);
454 updateCaption();
455}
456
457void TextEdit::openFile( const QString &f )
458{
459 bFromDocView = TRUE;
460 DocLnk nf;
461 nf.setType("text/plain");
462 nf.setFile(f);
463 openFile(nf);
464 showEditTools();
465 // Show filename in caption
466 QString name = f;
467 int sep = name.findRev( '/' );
468 if ( sep > 0 )
469 name = name.mid( sep+1 );
470 updateCaption( name );
471}
472
473void TextEdit::openFile( const DocLnk &f )
474{
475 clear();
476 FileManager fm;
477 QString txt;
478 if ( !fm.loadFile( f, txt ) ) {
479 // ####### could be a new file
480 //qDebug( "Cannot open file" );
481 //return;
482 }
483 fileNew();
484 if ( doc )
485 delete doc;
486 doc = new DocLnk(f);
487 editor->setText(txt);
488 editor->setEdited(FALSE);
489 updateCaption();
490}
491
492void TextEdit::showEditTools()
493{
494 if ( !doc )
495 close();
496 fileSelector->hide();
497 menu->show();
498 editBar->show();
499 if ( searchVisible )
500 searchBar->show();
501 updateCaption();
502}
503
504bool TextEdit::save()
505{
506 // case of nothing to save...
507 if ( !doc )
508 return true;
509 if ( !editor->edited() ) {
510 delete doc;
511 doc = 0;
512 return true;
513 }
514
515 QString rt = editor->text();
516
517 if ( doc->name().isEmpty() ) {
518 QString pt = rt.simplifyWhiteSpace();
519 int i = pt.find( ' ' );
520 QString docname = pt;
521 if ( i > 0 )
522 docname = pt.left( i );
523 // remove "." at the beginning
524 while( docname.startsWith( "." ) )
525 docname = docname.mid( 1 );
526 docname.replace( QRegExp("/"), "_" );
527 // cut the length. filenames longer than that don't make sense and something goes wrong when they get too long.
528 if ( docname.length() > 40 )
529 docname = docname.left(40);
530 if ( docname.isEmpty() )
531 docname = "Empty Text";
532 doc->setName(docname);
533
534 // append .txt to the file name
535 if ( doc->file().find(".txt") == -1 ) {
536 QString file = doc->file() + ".txt";
537 doc->setFile( file );
538 }
539 }
540
541
542 FileManager fm;
543 if ( !fm.saveFile( *doc, rt ) ) {
544 return false;
545 }
546 delete doc;
547 doc = 0;
548 editor->setEdited( false );
549 return true;
550}
551
552void TextEdit::clear()
553{
554 delete doc;
555 doc = 0;
556 editor->clear();
557}
558
559void TextEdit::updateCaption( const QString &name )
560{
561 if ( !doc )
562 setCaption( tr("Text Editor") );
563 else {
564 QString s = name;
565 if ( s.isNull() )
566 s = doc->name();
567 if ( s.isEmpty() )
568 s = tr( "Unnamed" );
569 setCaption( s + " - " + tr("Text Editor") );
570 }
571}
572
573void TextEdit::setDocument(const QString& fileref)
574{
575 bFromDocView = TRUE;
576 openFile(DocLnk(fileref));
577 showEditTools();
578}
579
580void TextEdit::closeEvent( QCloseEvent *e )
581{
582 if ( editorStack->visibleWidget() == editor && !bFromDocView ) {
583 e->ignore();
584 fileRevert();
585 } else {
586 bFromDocView = FALSE;
587 e->accept();
588 }
589}
590
591void TextEdit::accept()
592{
593 fileOpen();
594 }
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#ifndef TEXTEDIT_H
22#define TEXTEDIT_H
23
24#define QTEXTEDIT_OPEN_API
25
26#include <qpe/filemanager.h>
27
28#include <qmainwindow.h>
29#include <qmultilineedit.h>
30#include <qlist.h>
31#include <qmap.h>
32
33class QWidgetStack;
34class QToolButton;
35class QPopupMenu;
36class QToolBar;
37class QLineEdit;
38class QAction;
39class FileSelector;
40class QpeEditor;
41
42class TextEdit : public QMainWindow
43{
44 Q_OBJECT
45
46public:
47 TextEdit( QWidget *parent = 0, const char *name = 0, WFlags f = 0 );
48 ~TextEdit();
49
50 void openFile( const QString & );
51
52protected:
53 void closeEvent( QCloseEvent *e );
54
55private slots:
56 void setDocument(const QString&);
57
58 void fileNew();
59 void fileRevert();
60 void fileOpen();
61
62 void editCut();
63 void editCopy();
64 void editPaste();
65 void editFind();
66
67 void findNext();
68 void findClose();
69
70 void search();
71 void accept();
72
73 void newFile( const DocLnk & );
74 void openFile( const DocLnk & );
75 void showEditTools();
76
77 void zoomIn();
78 void zoomOut();
79 void setBold(bool y);
80 void setItalic(bool y);
81 void setWordWrap(bool y);
82
83private:
84 void colorChanged( const QColor &c );
85 bool save();
86 void clear();
87 void updateCaption( const QString &name=QString::null );
88 void setFontSize(int sz, bool round_down_not_up);
89
90private:
91 QWidgetStack *editorStack;
92 FileSelector *fileSelector;
93 QpeEditor* editor;
94 QToolBar *menu, *editBar, *searchBar;
95 QLineEdit *searchEdit;
96 DocLnk *doc;
97 bool searchVisible;
98 bool bFromDocView;
99 QAction *zin, *zout;
100};
101
102#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 @@
1# This is a Qt message file in .po format. Each msgid starts with
2# a scope. This scope should *NOT* be translated - eg. translating
3# from French to English, "Foo::Bar" would be translated to "Pub",
4# not "Foo::Pub".
5msgid ""
6msgstr ""
7"Project-Id-Version: PROJECT VERSION\n"
8"POT-Creation-Date: 2001-03-16 14:29:14 EST\n"
9"PO-Revision-Date: YYYY-MM-DD\n"
10"Last-Translator: FULLNAME <EMAIL@ADDRESS>\n"
11"Content-Type: text/plain; charset=iso-8859-1\n"
12
13#: textedit.cpp:110
14msgid "TextEdit::&Edit"
15msgstr ""
16
17#: textedit.cpp:109
18msgid "TextEdit::&File"
19msgstr ""
20
21#: textedit.cpp:102
22msgid "TextEdit::&Insert"
23msgstr ""
24
25#: textedit.cpp:115
26msgid "TextEdit::Bold"
27msgstr ""
28
29#: textedit.cpp:191
30msgid "TextEdit::Bullet List"
31msgstr ""
32
33#: textedit.cpp:140
34msgid "TextEdit::Center"
35msgstr ""
36
37#: textedit.cpp:170
38msgid "TextEdit::Close Find"
39msgstr ""
40
41#: textedit.cpp:69
42msgid "TextEdit::Close"
43msgstr ""
44
45#: textedit.cpp:79
46msgid "TextEdit::Copy"
47msgstr ""
48
49#: textedit.cpp:74
50msgid "TextEdit::Cut"
51msgstr ""
52
53#: textedit.cpp:194
54msgid "TextEdit::Enumerated List"
55msgstr ""
56
57#: textedit.cpp:94
58msgid "TextEdit::Find Next"
59msgstr ""
60
61#: textedit.cpp:89
62msgid "TextEdit::Find..."
63msgstr ""
64
65#: textedit.cpp:120
66msgid "TextEdit::Italic"
67msgstr ""
68
69#: textedit.cpp:134
70msgid "TextEdit::Left"
71msgstr ""
72
73#: textedit.cpp:61
74msgid "TextEdit::New"
75msgstr ""
76
77#: textedit.cpp:65
78msgid "TextEdit::Open"
79msgstr ""
80
81#: textedit.cpp:84
82msgid "TextEdit::Paste"
83msgstr ""
84
85#: textedit.cpp:145
86msgid "TextEdit::Right"
87msgstr ""
88
89#: textedit.cpp:188
90msgid "TextEdit::Standard"
91msgstr ""
92
93#: textedit.cpp:104
94msgid "TextEdit::Table..."
95msgstr ""
96
97#: textedit.cpp:570
98msgid "TextEdit::Text Editor"
99msgstr ""
100
101#: textedit.cpp:125
102msgid "TextEdit::Underline"
103msgstr ""
104
105#: textedit.cpp:569
106msgid "TextEdit::Unnamed"
107msgstr ""
108
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 @@
1 TEMPLATE= app
2 CONFIG += qt warn_on release
3
4 DESTDIR = $(QPEDIR)/bin
5
6 HEADERS= textedit.h
7
8 SOURCES= main.cpp textedit.cpp
9
10INCLUDEPATH += $(QPEDIR)/include
11 DEPENDPATH+= $(QPEDIR)/include
12LIBS += -lqpe
13
14 TARGET = textedit
15
16TRANSLATIONS = ../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 @@
1moc_*
2*.moc
3Makefile
4shutdown.cpp
5shutdown.h
6qimpenprefbase.h
7lnkpropertiesbase.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 @@
1#############################################################################
2
3####### Compiler, tools and options
4
5 CXX =$(SYSCONF_CXX) $(QT_CXX_MT)
6 CXXFLAGS=$(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
7 CC =$(SYSCONF_CC) $(QT_C_MT)
8 CFLAGS =$(SYSCONF_CFLAGS)
9 INCPATH =-I$(QPEDIR)/include -I$(QPEDIR)/calibrate -I$(QPEDIR)/rsync
10 LFLAGS =$(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
11 LIBS =$(SUBLIBS) -lqpe -lcrypt $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
12 MOC =$(SYSCONF_MOC)
13 UIC =$(SYSCONF_UIC)
14
15####### Target
16
17DESTDIR = $(QPEDIR)/bin/
18VER_MAJ = 1
19VER_MIN = 0
20VER_PATCH = 0
21 TARGET= qpe
22TARGET1 = lib$(TARGET).so.$(VER_MAJ)
23
24####### Files
25
26 HEADERS =background.h \
27 desktop.h \
28 info.h \
29 appicons.h \
30 taskbar.h \
31 sidething.h \
32 mrulist.h \
33 stabmon.h \
34 inputmethods.h \
35 systray.h \
36 wait.h \
37 shutdownimpl.h \
38 launcher.h \
39 launcherview.h \
40 ../calibrate/calibrate.h \
41 startmenu.h \
42 transferserver.h \
43 qcopbridge.h \
44 packageslave.h \
45 irserver.h \
46 $(QPEDIR)/rsync/buf.h \
47 $(QPEDIR)/rsync/checksum.h \
48 $(QPEDIR)/rsync/command.h \
49 $(QPEDIR)/rsync/emit.h \
50 $(QPEDIR)/rsync/job.h \
51 $(QPEDIR)/rsync/netint.h \
52 $(QPEDIR)/rsync/protocol.h \
53 $(QPEDIR)/rsync/prototab.h \
54 $(QPEDIR)/rsync/rsync.h \
55 $(QPEDIR)/rsync/search.h \
56 $(QPEDIR)/rsync/stream.h \
57 $(QPEDIR)/rsync/sumset.h \
58 $(QPEDIR)/rsync/trace.h \
59 $(QPEDIR)/rsync/types.h \
60 $(QPEDIR)/rsync/util.h \
61 $(QPEDIR)/rsync/whole.h \
62 $(QPEDIR)/rsync/config_rsync.h \
63 $(QPEDIR)/rsync/qrsync.h
64 SOURCES =background.cpp \
65 desktop.cpp \
66 info.cpp \
67 appicons.cpp \
68 taskbar.cpp \
69 sidething.cpp \
70 mrulist.cpp \
71 stabmon.cpp \
72 inputmethods.cpp \
73 systray.cpp \
74 wait.cpp \
75 shutdownimpl.cpp \
76 launcher.cpp \
77 launcherview.cpp \
78 $(QPEDIR)/calibrate/calibrate.cpp \
79 transferserver.cpp \
80 packageslave.cpp \
81 irserver.cpp \
82 qcopbridge.cpp \
83 startmenu.cpp \
84 main.cpp \
85 $(QPEDIR)/rsync/base64.c \
86 $(QPEDIR)/rsync/buf.c \
87 $(QPEDIR)/rsync/checksum.c \
88 $(QPEDIR)/rsync/command.c \
89 $(QPEDIR)/rsync/delta.c \
90 $(QPEDIR)/rsync/emit.c \
91 $(QPEDIR)/rsync/hex.c \
92 $(QPEDIR)/rsync/job.c \
93 $(QPEDIR)/rsync/mdfour.c \
94 $(QPEDIR)/rsync/mksum.c \
95 $(QPEDIR)/rsync/msg.c \
96 $(QPEDIR)/rsync/netint.c \
97 $(QPEDIR)/rsync/patch.c \
98 $(QPEDIR)/rsync/prototab.c \
99 $(QPEDIR)/rsync/readsums.c \
100 $(QPEDIR)/rsync/scoop.c \
101 $(QPEDIR)/rsync/search.c \
102 $(QPEDIR)/rsync/stats.c \
103 $(QPEDIR)/rsync/stream.c \
104 $(QPEDIR)/rsync/sumset.c \
105 $(QPEDIR)/rsync/trace.c \
106 $(QPEDIR)/rsync/tube.c \
107 $(QPEDIR)/rsync/util.c \
108 $(QPEDIR)/rsync/version.c \
109 $(QPEDIR)/rsync/whole.c \
110 $(QPEDIR)/rsync/qrsync.cpp
111 OBJECTS =background.o \
112 desktop.o \
113 info.o \
114 appicons.o \
115 taskbar.o \
116 sidething.o \
117 mrulist.o \
118 stabmon.o \
119 inputmethods.o \
120 systray.o \
121 wait.o \
122 shutdownimpl.o \
123 launcher.o \
124 launcherview.o \
125 $(QPEDIR)/calibrate/calibrate.o \
126 transferserver.o \
127 packageslave.o \
128 irserver.o \
129 qcopbridge.o \
130 startmenu.o \
131 main.o \
132 $(QPEDIR)/rsync/base64.o \
133 $(QPEDIR)/rsync/buf.o \
134 $(QPEDIR)/rsync/checksum.o \
135 $(QPEDIR)/rsync/command.o \
136 $(QPEDIR)/rsync/delta.o \
137 $(QPEDIR)/rsync/emit.o \
138 $(QPEDIR)/rsync/hex.o \
139 $(QPEDIR)/rsync/job.o \
140 $(QPEDIR)/rsync/mdfour.o \
141 $(QPEDIR)/rsync/mksum.o \
142 $(QPEDIR)/rsync/msg.o \
143 $(QPEDIR)/rsync/netint.o \
144 $(QPEDIR)/rsync/patch.o \
145 $(QPEDIR)/rsync/prototab.o \
146 $(QPEDIR)/rsync/readsums.o \
147 $(QPEDIR)/rsync/scoop.o \
148 $(QPEDIR)/rsync/search.o \
149 $(QPEDIR)/rsync/stats.o \
150 $(QPEDIR)/rsync/stream.o \
151 $(QPEDIR)/rsync/sumset.o \
152 $(QPEDIR)/rsync/trace.o \
153 $(QPEDIR)/rsync/tube.o \
154 $(QPEDIR)/rsync/util.o \
155 $(QPEDIR)/rsync/version.o \
156 $(QPEDIR)/rsync/whole.o \
157 $(QPEDIR)/rsync/qrsync.o \
158 shutdown.o \
159 syncdialog.o
160INTERFACES = shutdown.ui \
161 syncdialog.ui
162UICDECLS = shutdown.h \
163 syncdialog.h
164UICIMPLS = shutdown.cpp \
165 syncdialog.cpp
166 SRCMOC =moc_background.cpp \
167 moc_desktop.cpp \
168 moc_info.cpp \
169 moc_appicons.cpp \
170 moc_taskbar.cpp \
171 moc_sidething.cpp \
172 moc_inputmethods.cpp \
173 moc_systray.cpp \
174 moc_shutdownimpl.cpp \
175 moc_launcher.cpp \
176 moc_launcherview.cpp \
177 ../calibrate/moc_calibrate.cpp \
178 moc_startmenu.cpp \
179 moc_transferserver.cpp \
180 moc_qcopbridge.cpp \
181 moc_packageslave.cpp \
182 moc_irserver.cpp \
183 appicons.moc \
184 moc_shutdown.cpp \
185 moc_syncdialog.cpp
186 OBJMOC =moc_background.o \
187 moc_desktop.o \
188 moc_info.o \
189 moc_appicons.o \
190 moc_taskbar.o \
191 moc_sidething.o \
192 moc_inputmethods.o \
193 moc_systray.o \
194 moc_shutdownimpl.o \
195 moc_launcher.o \
196 moc_launcherview.o \
197 ../calibrate/moc_calibrate.o \
198 moc_startmenu.o \
199 moc_transferserver.o \
200 moc_qcopbridge.o \
201 moc_packageslave.o \
202 moc_irserver.o \
203 moc_shutdown.o \
204 moc_syncdialog.o
205
206
207####### Implicit rules
208
209.SUFFIXES: .cpp .cxx .cc .C .c
210
211.cpp.o:
212 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
213
214.cxx.o:
215 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
216
217.cc.o:
218 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
219
220.C.o:
221 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
222
223.c.o:
224 $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
225
226####### Build rules
227
228
229all: $(DESTDIR)$(TARGET)
230
231$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
232 $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
233
234moc: $(SRCMOC)
235
236tmake:
237 tmake taskbar.pro
238
239clean:
240 -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
241 -rm -f *~ core
242 -rm -f allmoc.cpp
243
244####### Extension Modules
245
246listpromodules:
247 @echo
248
249listallmodules:
250 @echo
251
252listaddonpromodules:
253 @echo
254
255listaddonentmodules:
256 @echo
257
258
259REQUIRES=
260
261####### Sub-libraries
262
263
264###### Combined headers
265
266
267
268####### Compile
269
270background.o: background.cpp \
271 background.h \
272 desktop.h \
273 shutdownimpl.h \
274 shutdown.h \
275 $(QPEDIR)/include/qpe/qpeapplication.h \
276 $(QPEDIR)/include/qpe/resource.h
277
278desktop.o: desktop.cpp \
279 desktop.h \
280 shutdownimpl.h \
281 shutdown.h \
282 $(QPEDIR)/include/qpe/qpeapplication.h \
283 info.h \
284 background.h \
285 launcher.h \
286 launcherview.h \
287 $(QPEDIR)/include/qpe/storage.h \
288 mrulist.h \
289 $(QPEDIR)/include/qpe/applnk.h \
290 qcopbridge.h \
291 startmenu.h \
292 taskbar.h \
293 $(QPEDIR)/include/qpe/custom.h \
294 transferserver.h \
295 irserver.h \
296 packageslave.h \
297 $(QPEDIR)/include/qpe/mimetype.h \
298 $(QPEDIR)/include/qpe/password.h \
299 $(QPEDIR)/include/qpe/config.h \
300 $(QPEDIR)/include/qpe/power.h \
301 $(QPEDIR)/include/qpe/qcopenvelope_qws.h \
302 $(QPEDIR)/include/qpe/global.h
303
304info.o: info.cpp \
305 info.h \
306 background.h \
307 desktop.h \
308 shutdownimpl.h \
309 shutdown.h \
310 $(QPEDIR)/include/qpe/qpeapplication.h \
311 $(QPEDIR)/include/qpe/resource.h \
312 $(QPEDIR)/include/qpe/version.h
313
314appicons.o: appicons.cpp \
315 appicons.moc \
316 appicons.h \
317 $(QPEDIR)/include/qpe/qcopenvelope_qws.h
318
319taskbar.o: taskbar.cpp \
320 startmenu.h \
321 inputmethods.h \
322 $(QPEDIR)/include/qpe/inputmethodinterface.h \
323 $(QPEDIR)/include/qpe/qcom.h \
324 $(QPEDIR)/include/qpe/quuid.h \
325 mrulist.h \
326 $(QPEDIR)/include/qpe/applnk.h \
327 systray.h \
328 $(QPEDIR)/include/qpe/taskbarappletinterface.h \
329 $(QPEDIR)/calibrate/calibrate.h \
330 wait.h \
331 $(QPEDIR)/include/qpe/resource.h \
332 appicons.h \
333 taskbar.h \
334 $(QPEDIR)/include/qpe/custom.h \
335 desktop.h \
336 shutdownimpl.h \
337 shutdown.h \
338 $(QPEDIR)/include/qpe/qpeapplication.h \
339 $(QPEDIR)/include/qpe/qcopenvelope_qws.h \
340 $(QPEDIR)/include/qpe/global.h \
341 ../taskbar/apps.h \
342 ../addressbook/addressbook.h \
343 ../datebook/datebook.h \
344 $(QPEDIR)/include/qpe/datebookdb.h \
345 $(QPEDIR)/include/qpe/event.h \
346 $(QPEDIR)/include/qpe/palmtoprecord.h \
347 ../helpbrowser/helpbrowser.h \
348 ../minesweep/minesweep.h \
349 ../textedit/textedit.h \
350 $(QPEDIR)/include/qpe/filemanager.h \
351 ../todo/mainwindow.h \
352 ../citytime/citytime.h \
353 ../clock/clock.h \
354 ../calculator/calculatorimpl.h \
355 ../sysinfo/sysinfo.h \
356 ../settings/appearance/settings.h \
357 ../settings/systemtime/settime.h \
358 $(QPEDIR)/include/qpe/timestring.h \
359 ../filebrowser/filebrowser.h \
360 ../solitaire/canvascardwindow.h \
361 ../snake/interface.h \
362 ../parashoot/interface.h \
363 $(QPEDIR)/include/qpe/sound.h \
364 ../mpegplayer/mediaplayer.h \
365 $(QPEDIR)/include/qpe/qlibrary.h \
366 ../embeddedkonsole/konsole.h \
367 ../wordgame/wordgame.h \
368 $(QPEDIR)/include/qpe/qdawg.h
369
370sidething.o: sidething.cpp \
371 sidething.h \
372 startmenu.h \
373 $(QPEDIR)/include/qpe/resource.h
374
375mrulist.o: mrulist.cpp \
376 mrulist.h \
377 $(QPEDIR)/include/qpe/applnk.h \
378 $(QPEDIR)/include/qpe/global.h \
379 $(QPEDIR)/include/qpe/resource.h
380
381stabmon.o: stabmon.cpp \
382 stabmon.h \
383 $(QPEDIR)/include/qpe/qcopenvelope_qws.h
384
385inputmethods.o: inputmethods.cpp \
386 inputmethods.h \
387 $(QPEDIR)/include/qpe/inputmethodinterface.h \
388 $(QPEDIR)/include/qpe/qcom.h \
389 $(QPEDIR)/include/qpe/quuid.h \
390 $(QPEDIR)/include/qpe/config.h \
391 $(QPEDIR)/include/qpe/qpeapplication.h \
392 $(QPEDIR)/include/qpe/qlibrary.h
393
394systray.o: systray.cpp \
395 $(QPEDIR)/include/qpe/qpeapplication.h \
396 $(QPEDIR)/include/qpe/qlibrary.h \
397 $(QPEDIR)/include/qpe/qcom.h \
398 $(QPEDIR)/include/qpe/quuid.h \
399 $(QPEDIR)/include/qpe/config.h \
400 quicklauncher.h \
401 systray.h \
402 $(QPEDIR)/include/qpe/taskbarappletinterface.h
403
404wait.o: wait.cpp \
405 wait.h \
406 $(QPEDIR)/include/qpe/resource.h
407
408shutdownimpl.o: shutdownimpl.cpp \
409 shutdownimpl.h \
410 shutdown.h \
411 $(QPEDIR)/include/qpe/global.h
412
413launcher.o: launcher.cpp \
414 $(QPEDIR)/include/qpe/qcopenvelope_qws.h \
415 $(QPEDIR)/include/qpe/resource.h \
416 $(QPEDIR)/include/qpe/applnk.h \
417 $(QPEDIR)/include/qpe/config.h \
418 $(QPEDIR)/include/qpe/global.h \
419 $(QPEDIR)/include/qpe/qpeapplication.h \
420 $(QPEDIR)/include/qpe/mimetype.h \
421 $(QPEDIR)/include/qpe/storage.h \
422 launcherview.h \
423 launcher.h \
424 $(QPEDIR)/include/qpe/lnkproperties.h \
425 mrulist.h \
426 $(QPEDIR)/rsync/qrsync.h
427
428launcherview.o: launcherview.cpp \
429 launcherview.h \
430 $(QPEDIR)/include/qpe/storage.h \
431 $(QPEDIR)/include/qpe/qpeapplication.h \
432 $(QPEDIR)/include/qpe/applnk.h \
433 $(QPEDIR)/include/qpe/qpedebug.h \
434 $(QPEDIR)/include/qpe/categories.h \
435 $(QPEDIR)/include/qpe/categoryselect.h \
436 $(QPEDIR)/include/qpe/menubutton.h \
437 $(QPEDIR)/include/qpe/resource.h \
438 $(QPEDIR)/include/qpe/qpetoolbar.h
439
440$(QPEDIR)/calibrate/calibrate.o: $(QPEDIR)/calibrate/calibrate.cpp \
441 $(QPEDIR)/calibrate/calibrate.h \
442 $(QPEDIR)/include/qpe/resource.h
443
444transferserver.o: transferserver.cpp \
445 $(QPEDIR)/include/qpe/qprocess.h \
446 $(QPEDIR)/include/qpe/process.h \
447 transferserver.h
448
449packageslave.o: packageslave.cpp \
450 packageslave.h \
451 $(QPEDIR)/include/qpe/process.h \
452 $(QPEDIR)/include/qpe/qcopenvelope_qws.h
453
454irserver.o: irserver.cpp \
455 irserver.h \
456 $(QPEDIR)/include/qpe/qlibrary.h \
457 $(QPEDIR)/include/qpe/qcom.h \
458 $(QPEDIR)/include/qpe/quuid.h \
459 $(QPEDIR)/include/qpe/qpeapplication.h \
460 obexinterface.h
461
462qcopbridge.o: qcopbridge.cpp \
463 qcopbridge.h \
464 $(QPEDIR)/include/qpe/qcopenvelope_qws.h \
465 $(QPEDIR)/include/qpe/qpeapplication.h
466
467startmenu.o: startmenu.cpp \
468 startmenu.h \
469 sidething.h \
470 mrulist.h \
471 $(QPEDIR)/include/qpe/applnk.h \
472 info.h \
473 background.h \
474 $(QPEDIR)/include/qpe/qpeapplication.h \
475 $(QPEDIR)/include/qpe/config.h \
476 $(QPEDIR)/include/qpe/global.h \
477 $(QPEDIR)/include/qpe/resource.h
478
479main.o: main.cpp \
480 desktop.h \
481 shutdownimpl.h \
482 shutdown.h \
483 $(QPEDIR)/include/qpe/qpeapplication.h \
484 taskbar.h \
485 $(QPEDIR)/include/qpe/custom.h \
486 stabmon.h \
487 $(QPEDIR)/include/qpe/network.h \
488 $(QPEDIR)/include/qpe/config.h \
489 $(QPEDIR)/include/qpe/qcopenvelope_qws.h \
490 $(QPEDIR)/include/qpe/alarmserver.h \
491 ../calibrate/calibrate.h \
492 ../login/qdmdialogimpl.h \
493 $(QPEDIR)/include/qpe/global.h
494
495$(QPEDIR)/rsync/base64.o: $(QPEDIR)/rsync/base64.c \
496 $(QPEDIR)/rsync/config_rsync.h \
497 $(QPEDIR)/rsync/config_linux.h \
498 $(QPEDIR)/rsync/rsync.h
499
500$(QPEDIR)/rsync/buf.o: $(QPEDIR)/rsync/buf.c \
501 $(QPEDIR)/rsync/config_rsync.h \
502 $(QPEDIR)/rsync/config_linux.h \
503 $(QPEDIR)/rsync/rsync.h \
504 $(QPEDIR)/rsync/trace.h \
505 $(QPEDIR)/rsync/buf.h \
506 $(QPEDIR)/rsync/util.h
507
508$(QPEDIR)/rsync/checksum.o: $(QPEDIR)/rsync/checksum.c \
509 $(QPEDIR)/rsync/config_rsync.h \
510 $(QPEDIR)/rsync/config_linux.h \
511 $(QPEDIR)/rsync/rsync.h \
512 $(QPEDIR)/rsync/checksum.h
513
514$(QPEDIR)/rsync/command.o: $(QPEDIR)/rsync/command.c \
515 $(QPEDIR)/rsync/config_rsync.h \
516 $(QPEDIR)/rsync/config_linux.h \
517 $(QPEDIR)/rsync/rsync.h \
518 $(QPEDIR)/rsync/command.h
519
520$(QPEDIR)/rsync/delta.o: $(QPEDIR)/rsync/delta.c \
521 $(QPEDIR)/rsync/config_rsync.h \
522 $(QPEDIR)/rsync/config_linux.h \
523 $(QPEDIR)/rsync/rsync.h \
524 $(QPEDIR)/rsync/emit.h \
525 $(QPEDIR)/rsync/stream.h \
526 $(QPEDIR)/rsync/util.h \
527 $(QPEDIR)/rsync/sumset.h \
528 $(QPEDIR)/rsync/job.h \
529 $(QPEDIR)/rsync/trace.h \
530 $(QPEDIR)/rsync/checksum.h \
531 $(QPEDIR)/rsync/search.h \
532 $(QPEDIR)/rsync/types.h
533
534$(QPEDIR)/rsync/emit.o: $(QPEDIR)/rsync/emit.c \
535 $(QPEDIR)/rsync/config_rsync.h \
536 $(QPEDIR)/rsync/config_linux.h \
537 $(QPEDIR)/rsync/rsync.h \
538 $(QPEDIR)/rsync/command.h \
539 $(QPEDIR)/rsync/protocol.h \
540 $(QPEDIR)/rsync/trace.h \
541 $(QPEDIR)/rsync/emit.h \
542 $(QPEDIR)/rsync/prototab.h \
543 $(QPEDIR)/rsync/netint.h \
544 $(QPEDIR)/rsync/sumset.h \
545 $(QPEDIR)/rsync/job.h
546
547$(QPEDIR)/rsync/hex.o: $(QPEDIR)/rsync/hex.c \
548 $(QPEDIR)/rsync/config_rsync.h \
549 $(QPEDIR)/rsync/config_linux.h \
550 $(QPEDIR)/rsync/rsync.h
551
552$(QPEDIR)/rsync/job.o: $(QPEDIR)/rsync/job.c \
553 $(QPEDIR)/rsync/config_rsync.h \
554 $(QPEDIR)/rsync/config_linux.h \
555 $(QPEDIR)/rsync/rsync.h \
556 $(QPEDIR)/rsync/stream.h \
557 $(QPEDIR)/rsync/util.h \
558 $(QPEDIR)/rsync/sumset.h \
559 $(QPEDIR)/rsync/job.h \
560 $(QPEDIR)/rsync/trace.h
561
562$(QPEDIR)/rsync/mdfour.o: $(QPEDIR)/rsync/mdfour.c \
563 $(QPEDIR)/rsync/config_rsync.h \
564 $(QPEDIR)/rsync/config_linux.h \
565 $(QPEDIR)/rsync/rsync.h \
566 $(QPEDIR)/rsync/trace.h \
567 $(QPEDIR)/rsync/types.h
568
569$(QPEDIR)/rsync/mksum.o: $(QPEDIR)/rsync/mksum.c \
570 $(QPEDIR)/rsync/config_rsync.h \
571 $(QPEDIR)/rsync/config_linux.h \
572 $(QPEDIR)/rsync/rsync.h \
573 $(QPEDIR)/rsync/stream.h \
574 $(QPEDIR)/rsync/util.h \
575 $(QPEDIR)/rsync/sumset.h \
576 $(QPEDIR)/rsync/job.h \
577 $(QPEDIR)/rsync/protocol.h \
578 $(QPEDIR)/rsync/netint.h \
579 $(QPEDIR)/rsync/trace.h \
580 $(QPEDIR)/rsync/checksum.h
581
582$(QPEDIR)/rsync/msg.o: $(QPEDIR)/rsync/msg.c \
583 $(QPEDIR)/rsync/config_rsync.h \
584 $(QPEDIR)/rsync/config_linux.h \
585 $(QPEDIR)/rsync/rsync.h
586
587$(QPEDIR)/rsync/netint.o: $(QPEDIR)/rsync/netint.c \
588 $(QPEDIR)/rsync/config_rsync.h \
589 $(QPEDIR)/rsync/config_linux.h \
590 $(QPEDIR)/rsync/rsync.h \
591 $(QPEDIR)/rsync/job.h \
592 $(QPEDIR)/rsync/netint.h \
593 $(QPEDIR)/rsync/trace.h \
594 $(QPEDIR)/rsync/stream.h
595
596$(QPEDIR)/rsync/patch.o: $(QPEDIR)/rsync/patch.c \
597 $(QPEDIR)/rsync/config_rsync.h \
598 $(QPEDIR)/rsync/config_linux.h \
599 $(QPEDIR)/rsync/rsync.h \
600 $(QPEDIR)/rsync/util.h \
601 $(QPEDIR)/rsync/trace.h \
602 $(QPEDIR)/rsync/protocol.h \
603 $(QPEDIR)/rsync/netint.h \
604 $(QPEDIR)/rsync/command.h \
605 $(QPEDIR)/rsync/sumset.h \
606 $(QPEDIR)/rsync/prototab.h \
607 $(QPEDIR)/rsync/stream.h \
608 $(QPEDIR)/rsync/job.h
609
610$(QPEDIR)/rsync/prototab.o: $(QPEDIR)/rsync/prototab.c \
611 $(QPEDIR)/rsync/config_rsync.h \
612 $(QPEDIR)/rsync/config_linux.h \
613 $(QPEDIR)/rsync/rsync.h \
614 $(QPEDIR)/rsync/protocol.h \
615 $(QPEDIR)/rsync/command.h \
616 $(QPEDIR)/rsync/prototab.h
617
618$(QPEDIR)/rsync/readsums.o: $(QPEDIR)/rsync/readsums.c \
619 $(QPEDIR)/rsync/config_rsync.h \
620 $(QPEDIR)/rsync/config_linux.h \
621 $(QPEDIR)/rsync/rsync.h \
622 $(QPEDIR)/rsync/sumset.h \
623 $(QPEDIR)/rsync/job.h \
624 $(QPEDIR)/rsync/trace.h \
625 $(QPEDIR)/rsync/netint.h \
626 $(QPEDIR)/rsync/protocol.h \
627 $(QPEDIR)/rsync/util.h \
628 $(QPEDIR)/rsync/stream.h
629
630$(QPEDIR)/rsync/scoop.o: $(QPEDIR)/rsync/scoop.c \
631 $(QPEDIR)/rsync/config_rsync.h \
632 $(QPEDIR)/rsync/config_linux.h \
633 $(QPEDIR)/rsync/rsync.h \
634 $(QPEDIR)/rsync/job.h \
635 $(QPEDIR)/rsync/stream.h \
636 $(QPEDIR)/rsync/trace.h \
637 $(QPEDIR)/rsync/util.h
638
639$(QPEDIR)/rsync/search.o: $(QPEDIR)/rsync/search.c \
640 $(QPEDIR)/rsync/config_rsync.h \
641 $(QPEDIR)/rsync/config_linux.h \
642 $(QPEDIR)/rsync/rsync.h \
643 $(QPEDIR)/rsync/trace.h \
644 $(QPEDIR)/rsync/util.h \
645 $(QPEDIR)/rsync/sumset.h \
646 $(QPEDIR)/rsync/search.h \
647 $(QPEDIR)/rsync/checksum.h
648
649$(QPEDIR)/rsync/stats.o: $(QPEDIR)/rsync/stats.c \
650 $(QPEDIR)/rsync/config_rsync.h \
651 $(QPEDIR)/rsync/config_linux.h \
652 $(QPEDIR)/rsync/rsync.h \
653 $(QPEDIR)/rsync/trace.h
654
655$(QPEDIR)/rsync/stream.o: $(QPEDIR)/rsync/stream.c \
656 $(QPEDIR)/rsync/config_rsync.h \
657 $(QPEDIR)/rsync/config_linux.h \
658 $(QPEDIR)/rsync/rsync.h \
659 $(QPEDIR)/rsync/stream.h \
660 $(QPEDIR)/rsync/util.h \
661 $(QPEDIR)/rsync/trace.h
662
663$(QPEDIR)/rsync/sumset.o: $(QPEDIR)/rsync/sumset.c \
664 $(QPEDIR)/rsync/config_rsync.h \
665 $(QPEDIR)/rsync/config_linux.h \
666 $(QPEDIR)/rsync/rsync.h \
667 $(QPEDIR)/rsync/sumset.h \
668 $(QPEDIR)/rsync/util.h \
669 $(QPEDIR)/rsync/trace.h
670
671$(QPEDIR)/rsync/trace.o: $(QPEDIR)/rsync/trace.c \
672 $(QPEDIR)/rsync/config_rsync.h \
673 $(QPEDIR)/rsync/config_linux.h \
674 $(QPEDIR)/rsync/rsync.h \
675 $(QPEDIR)/rsync/util.h \
676 $(QPEDIR)/rsync/trace.h
677
678$(QPEDIR)/rsync/tube.o: $(QPEDIR)/rsync/tube.c \
679 $(QPEDIR)/rsync/config_rsync.h \
680 $(QPEDIR)/rsync/config_linux.h \
681 $(QPEDIR)/rsync/rsync.h \
682 $(QPEDIR)/rsync/trace.h \
683 $(QPEDIR)/rsync/util.h \
684 $(QPEDIR)/rsync/job.h \
685 $(QPEDIR)/rsync/stream.h
686
687$(QPEDIR)/rsync/util.o: $(QPEDIR)/rsync/util.c \
688 $(QPEDIR)/rsync/config_rsync.h \
689 $(QPEDIR)/rsync/config_linux.h \
690 $(QPEDIR)/rsync/util.h \
691 $(QPEDIR)/rsync/rsync.h \
692 $(QPEDIR)/rsync/trace.h
693
694$(QPEDIR)/rsync/version.o: $(QPEDIR)/rsync/version.c \
695 $(QPEDIR)/rsync/config_rsync.h \
696 $(QPEDIR)/rsync/config_linux.h \
697 $(QPEDIR)/rsync/rsync.h
698
699$(QPEDIR)/rsync/whole.o: $(QPEDIR)/rsync/whole.c \
700 $(QPEDIR)/rsync/config_rsync.h \
701 $(QPEDIR)/rsync/config_linux.h \
702 $(QPEDIR)/rsync/rsync.h \
703 $(QPEDIR)/rsync/trace.h \
704 $(QPEDIR)/rsync/fileutil.h \
705 $(QPEDIR)/rsync/sumset.h \
706 $(QPEDIR)/rsync/job.h \
707 $(QPEDIR)/rsync/buf.h \
708 $(QPEDIR)/rsync/whole.h \
709 $(QPEDIR)/rsync/util.h
710
711$(QPEDIR)/rsync/qrsync.o: $(QPEDIR)/rsync/qrsync.cpp \
712 $(QPEDIR)/rsync/qrsync.h \
713 $(QPEDIR)/rsync/rsync.h
714
715shutdown.h: shutdown.ui
716 $(UIC) shutdown.ui -o $(INTERFACE_DECL_PATH)/shutdown.h
717
718shutdown.cpp: shutdown.ui
719 $(UIC) shutdown.ui -i shutdown.h -o shutdown.cpp
720
721syncdialog.h: syncdialog.ui
722 $(UIC) syncdialog.ui -o $(INTERFACE_DECL_PATH)/syncdialog.h
723
724syncdialog.cpp: syncdialog.ui
725 $(UIC) syncdialog.ui -i syncdialog.h -o syncdialog.cpp
726
727shutdown.o: shutdown.cpp \
728 shutdown.h
729
730syncdialog.o: syncdialog.cpp
731
732moc_background.o: moc_background.cpp \
733 background.h
734
735moc_desktop.o: moc_desktop.cpp \
736 desktop.h \
737 shutdownimpl.h \
738 shutdown.h \
739 $(QPEDIR)/include/qpe/qpeapplication.h
740
741moc_info.o: moc_info.cpp \
742 info.h \
743 background.h
744
745moc_appicons.o: moc_appicons.cpp \
746 appicons.h
747
748moc_taskbar.o: moc_taskbar.cpp \
749 taskbar.h \
750 $(QPEDIR)/include/qpe/custom.h
751
752moc_sidething.o: moc_sidething.cpp \
753 sidething.h \
754 startmenu.h
755
756moc_inputmethods.o: moc_inputmethods.cpp \
757 inputmethods.h \
758 $(QPEDIR)/include/qpe/inputmethodinterface.h \
759 $(QPEDIR)/include/qpe/qcom.h \
760 $(QPEDIR)/include/qpe/quuid.h
761
762moc_systray.o: moc_systray.cpp \
763 systray.h \
764 $(QPEDIR)/include/qpe/taskbarappletinterface.h \
765 $(QPEDIR)/include/qpe/qcom.h \
766 $(QPEDIR)/include/qpe/quuid.h
767
768moc_shutdownimpl.o: moc_shutdownimpl.cpp \
769 shutdownimpl.h \
770 shutdown.h
771
772moc_launcher.o: moc_launcher.cpp \
773 launcher.h \
774 launcherview.h \
775 $(QPEDIR)/include/qpe/storage.h
776
777moc_launcherview.o: moc_launcherview.cpp \
778 launcherview.h \
779 $(QPEDIR)/include/qpe/storage.h
780
781../calibrate/moc_calibrate.o: ../calibrate/moc_calibrate.cpp \
782 ../calibrate/calibrate.h
783
784moc_startmenu.o: moc_startmenu.cpp \
785 startmenu.h
786
787moc_transferserver.o: moc_transferserver.cpp \
788 transferserver.h
789
790moc_qcopbridge.o: moc_qcopbridge.cpp \
791 qcopbridge.h
792
793moc_packageslave.o: moc_packageslave.cpp \
794 packageslave.h
795
796moc_irserver.o: moc_irserver.cpp \
797 irserver.h
798
799moc_shutdown.o: appicons.moc \
800 appicons.cpp \
801 appicons.h \
802 $(QPEDIR)/include/qpe/qcopenvelope_qws.h
803
804moc_syncdialog.o: moc_shutdown.cpp \
805 shutdown.h
806
807moc_background.cpp: background.h
808 $(MOC) background.h -o moc_background.cpp
809
810moc_desktop.cpp: desktop.h
811 $(MOC) desktop.h -o moc_desktop.cpp
812
813moc_info.cpp: info.h
814 $(MOC) info.h -o moc_info.cpp
815
816moc_appicons.cpp: appicons.h
817 $(MOC) appicons.h -o moc_appicons.cpp
818
819moc_taskbar.cpp: taskbar.h
820 $(MOC) taskbar.h -o moc_taskbar.cpp
821
822moc_sidething.cpp: sidething.h
823 $(MOC) sidething.h -o moc_sidething.cpp
824
825moc_inputmethods.cpp: inputmethods.h
826 $(MOC) inputmethods.h -o moc_inputmethods.cpp
827
828moc_systray.cpp: systray.h
829 $(MOC) systray.h -o moc_systray.cpp
830
831moc_shutdownimpl.cpp: shutdownimpl.h
832 $(MOC) shutdownimpl.h -o moc_shutdownimpl.cpp
833
834moc_launcher.cpp: launcher.h
835 $(MOC) launcher.h -o moc_launcher.cpp
836
837moc_launcherview.cpp: launcherview.h
838 $(MOC) launcherview.h -o moc_launcherview.cpp
839
840../calibrate/moc_calibrate.cpp: ../calibrate/calibrate.h
841 $(MOC) ../calibrate/calibrate.h -o ../calibrate/moc_calibrate.cpp
842
843moc_startmenu.cpp: startmenu.h
844 $(MOC) startmenu.h -o moc_startmenu.cpp
845
846moc_transferserver.cpp: transferserver.h
847 $(MOC) transferserver.h -o moc_transferserver.cpp
848
849moc_qcopbridge.cpp: qcopbridge.h
850 $(MOC) qcopbridge.h -o moc_qcopbridge.cpp
851
852moc_packageslave.cpp: packageslave.h
853 $(MOC) packageslave.h -o moc_packageslave.cpp
854
855moc_irserver.cpp: irserver.h
856 $(MOC) irserver.h -o moc_irserver.cpp
857
858appicons.moc: appicons.cpp
859 $(MOC) appicons.cpp -o appicons.moc
860
861moc_shutdown.cpp: shutdown.h
862 $(MOC) shutdown.h -o moc_shutdown.cpp
863
864moc_syncdialog.cpp: syncdialog.h
865 $(MOC) syncdialog.h -o moc_syncdialog.cpp
866
867
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21
22#include "appicons.h"
23
24#include <qpe/qcopenvelope_qws.h>
25
26#include <qtooltip.h>
27#include <qpixmap.h>
28
29
30AppIcons::AppIcons( QWidget *parent ) :
31 QHBox(parent)
32{
33 buttons.setAutoDelete(TRUE);
34
35#ifndef QT_NO_COP
36 QCopChannel* channel = new QCopChannel("Qt/Tray", this);
37 connect(channel, SIGNAL(received(const QCString&, const QByteArray&)),
38 this, SLOT(receive(const QCString&, const QByteArray&)));
39#endif
40}
41
42void AppIcons::setIcon(int id, const QPixmap& pm)
43{
44 button(id)->setPixmap(pm);
45}
46
47class FlatButton : public QLabel {
48 Q_OBJECT
49public:
50 FlatButton(QWidget* parent) : QLabel(parent) { }
51
52 void mouseDoubleClickEvent(QMouseEvent* e)
53 {
54 emit clicked(e->pos(),e->button(),TRUE);
55 }
56 void mouseReleaseEvent(QMouseEvent* e)
57 {
58 if ( rect().contains(e->pos()) )
59 emit clicked(e->pos(),e->button(),FALSE);
60 }
61
62signals:
63 void clicked(const QPoint&, int, bool);
64};
65
66QLabel* AppIcons::button(int id)
67{
68 QLabel* f = buttons.find(id);
69 if ( !f ) {
70 buttons.insert(id,f=new FlatButton(this));
71 connect(f,SIGNAL(clicked(const QPoint&, int, bool)),this,SLOT(clicked(const QPoint&, int, bool)));
72 f->show();
73 }
74 return f;
75}
76
77int AppIcons::findId(QLabel* b)
78{
79 QIntDictIterator<QLabel> it(buttons);
80 for ( ; ; ++it )
81 if ( it.current() == b ) return it.currentKey();
82}
83
84void AppIcons::clicked(const QPoint& relpos, int button, bool dbl)
85{
86#ifndef QT_NO_COP
87 QLabel* s = (QLabel*)sender();
88 if ( button == RightButton ) {
89 QCopEnvelope("Qt/Tray","popup(int,QPoint)")
90 << findId(s) << s->mapToGlobal(QPoint(0,0));
91 } else {
92 QCopEnvelope("Qt/Tray",
93 dbl ? "doubleClicked(int,QPoint)" : "clicked(int,QPoint)")
94 << findId(s) << relpos;
95 }
96#endif
97}
98
99void AppIcons::setToolTip(int id, const QString& tip)
100{
101 QToolTip::add(button(id),tip);
102}
103
104void AppIcons::remove(int id)
105{
106 buttons.remove(id);
107}
108
109void AppIcons::receive( const QCString &msg, const QByteArray &data )
110{
111 QDataStream stream( data, IO_ReadOnly );
112 if ( msg == "remove(int)" ) {
113 int id;
114 stream >> id;
115 remove(id);
116 } else if ( msg == "setIcon(int,QPixmap)" ) {
117 int id;
118 QPixmap pm;
119 stream >> id >> pm;
120 setIcon(id,pm);
121 } else if ( msg == "setToolTip(int,QString)" ) {
122 int id;
123 QString s;
124 stream >> id >> s;
125 setToolTip(id,s);
126 }
127}
128
129#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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#ifndef APPICONS_H
22#define APPICONS_H
23
24
25#include <qhbox.h>
26#include <qintdict.h>
27#include <qlabel.h>
28
29
30class AppIcons : public QHBox
31{
32 Q_OBJECT
33
34public:
35 AppIcons( QWidget *parent );
36 void setIcon(int id, const QPixmap&);
37 void setToolTip(int id, const QString&);
38 void remove(int id);
39
40private slots:
41 void receive( const QCString &msg, const QByteArray &data );
42 void clicked(const QPoint& relpos, int button, bool dbl);
43
44private:
45 QIntDict<QLabel> buttons;
46 QLabel* button(int id);
47 int findId(QLabel*);
48};
49
50
51#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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21
22// To add a new app, include appropriate files and add another APP().
23
24#ifndef APP_INCLUDES
25#define APP_INCLUDES
26
27#include "../addressbook/addressbook.h"
28#include "../datebook/datebook.h"
29#include "../helpbrowser/helpbrowser.h"
30#include "../minesweep/minesweep.h"
31#include "../textedit/textedit.h"
32#include "../todo/mainwindow.h"
33#include "../citytime/citytime.h"
34#include "../clock/clock.h"
35#include "../calculator/calculatorimpl.h"
36#include "../sysinfo/sysinfo.h"
37#include "../settings/appearance/settings.h"
38//#include "../settings/language/settings.h"
39//#include "../settings/light-and-power/settings.h"
40//#include "../settings/rotation/settings.h"
41#include "../settings/systemtime/settime.h"
42#if !defined(QT_QPE_SMALL_BUILD)
43#include "../filebrowser/filebrowser.h"
44#include "../solitaire/canvascardwindow.h"
45#include "../snake/interface.h"
46#include "../parashoot/interface.h"
47#include "../mpegplayer/mediaplayer.h"
48#endif
49#if !defined(QT_DEMO_SINGLE_FLOPPY) && !defined(QT_QPE_SMALL_BUILD)
50#include "../embeddedkonsole/konsole.h"
51#include "../wordgame/wordgame.h"
52#endif
53
54#endif
55
56// app-id class maximize? documentary?
57
58 APP( "addressbook", AddressbookWindow, 1, 0 )
59 APP( "datebook", DateBook, 1, 0 )
60 APP( "helpbrowser", HelpBrowser, 1, 1 )
61 APP( "textedit", TextEdit, 1, 1 )
62 APP( "todo", TodoWindow, 1, 0 )
63 APP( "calculator", CalculatorImpl, 1, 0 )
64 APP( "citytime", CityTime, 1, 0 )
65 APP( "clock", Clock, 1, 0 )
66 APP( "minesweep", MineSweep, 1, 0 )
67 APP( "sysinfo", SystemInfo, 1, 0 )
68 APP( "appearance", AppearanceSettings, 1, 0 )
69 APP( "systemtime", SetDateTime, 1, 0 )
70#if !defined(QT_QPE_SMALL_BUILD)
71 //APP( "light-and-power", LightSettings, 1, 0 )
72 //APP( "sound", SoundSettings, 1, 0 )
73 APP( "filebrowser", FileBrowser, 1, 0 )
74 APP( "solitaire", CanvasCardWindow, 1, 0 )
75 APP( "snake", SnakeGame, 1, 0 )
76 APP( "parashoot", ParaShoot, 1, 0 )
77 APP( "mpegplayer", MediaPlayer, 1, 0 )
78#endif
79#if !defined(QT_DEMO_SINGLE_FLOPPY) && !defined(QT_QPE_SMALL_BUILD)
80 APP( "embeddedkonsole", Konsole, 1, 0 )
81 APP( "wordgame", WordGame, 1, 0 )
82#endif
83
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "background.h"
22#include "desktop.h"
23
24#include <qpe/resource.h>
25
26#include <qpainter.h>
27
28
29Background::Background( Desktop *d ) :
30 QWidget( d, 0, WStyle_Tool | WStyle_Customize )
31{
32/*
33 if ( QPixmap::defaultDepth() < 12 ) {
34 setBackgroundColor(QColor(0x20, 0xb0, 0x50));
35 } else {
36 setBackgroundPixmap( Resource::loadPixmap( "bg" ) );
37 }
38*/
39 setBackgroundMode( PaletteButton );
40}
41
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#ifndef __BACKGROUND_H__
22#define __BACKGROUND_H__
23
24
25#include <qwidget.h>
26
27
28class Desktop;
29
30
31class Background : public QWidget {
32 Q_OBJECT
33public:
34 Background( Desktop *d );
35};
36
37
38#endif // __BACKGROUND_H__
39
40
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "desktop.h"
22#include "info.h"
23#include "launcher.h"
24#include "mrulist.h"
25#include "qcopbridge.h"
26#include "shutdownimpl.h"
27#include "startmenu.h"
28#include "taskbar.h"
29#include "transferserver.h"
30#include "irserver.h"
31#include "packageslave.h"
32
33#include <qpe/applnk.h>
34#include <qpe/mimetype.h>
35#include <qpe/password.h>
36#include <qpe/config.h>
37#include <qpe/power.h>
38#include <qpe/qcopenvelope_qws.h>
39#include <qpe/global.h>
40#ifdef QT_QWS_CUSTOM
41#include "qpe/custom.h"
42#endif
43
44#include <qgfx_qws.h>
45#include <qmainwindow.h>
46#include <qmessagebox.h>
47#include <qtimer.h>
48#include <qwindowsystem_qws.h>
49
50#include <stdlib.h>
51#include <unistd.h>
52
53static Desktop* qpedesktop = 0;
54static int loggedin=0;
55static void login(bool at_poweron)
56{
57 if ( !loggedin ) {
58 Global::terminateBuiltin("calibrate");
59 Password::authenticate(at_poweron);
60 loggedin=1;
61 QCopEnvelope e( "QPE/Desktop", "unlocked()" );
62 }
63}
64
65bool Desktop::screenLocked()
66{
67 return loggedin == 0;
68}
69
70/*
71 Priority is number of alerts that are needed to pop up
72 alert.
73 */
74class DesktopPowerAlerter : public QMessageBox
75{
76public:
77 DesktopPowerAlerter( QWidget *parent, const char *name = 0 )
78 : QMessageBox( tr("Battery Status"), "Low Battery",
79 QMessageBox::Critical,
80 QMessageBox::Ok | QMessageBox::Default,
81 QMessageBox::NoButton, QMessageBox::NoButton,
82 parent, name, FALSE )
83 {
84 currentPriority = INT_MAX;
85 alertCount = 0;
86 }
87
88 void alert( const QString &text, int priority );
89 void hideEvent( QHideEvent * );
90private:
91 int currentPriority;
92 int alertCount;
93};
94
95void DesktopPowerAlerter::alert( const QString &text, int priority )
96{
97 alertCount++;
98 if ( alertCount < priority )
99 return;
100 if ( priority > currentPriority )
101 return;
102 currentPriority = priority;
103 setText( text );
104 show();
105}
106
107
108void DesktopPowerAlerter::hideEvent( QHideEvent *e )
109{
110 QMessageBox::hideEvent( e );
111 alertCount = 0;
112 currentPriority = INT_MAX;
113}
114
115
116
117DesktopApplication::DesktopApplication( int& argc, char **argv, Type t )
118 : QPEApplication( argc, argv, t )
119{
120
121 QTimer *t = new QTimer( this );
122 connect( t, SIGNAL(timeout()), this, SLOT(psTimeout()) );
123 t->start( 10000 );
124 ps = new PowerStatus;
125 pa = new DesktopPowerAlerter( 0 );
126}
127
128
129DesktopApplication::~DesktopApplication()
130{
131 delete ps;
132 delete pa;
133}
134
135
136enum MemState { Unknown, VeryLow, Low, Normal } memstate=Unknown;
137
138#ifdef Q_WS_QWS
139bool DesktopApplication::qwsEventFilter( QWSEvent *e )
140{
141 qpedesktop->checkMemory();
142
143 if ( e->type == QWSEvent::Key ) {
144 QWSKeyEvent *ke = (QWSKeyEvent *)e;
145 if ( !loggedin && ke->simpleData.keycode != Key_F34 )
146 return TRUE;
147 bool press = ke->simpleData.is_press;
148 if ( !keyboardGrabbed() ) {
149 if ( ke->simpleData.keycode == Key_F9 ) {
150 if ( press ) emit datebook();
151 return TRUE;
152 }
153 if ( ke->simpleData.keycode == Key_F10 ) {
154 if ( !press && cardSendTimer ) {
155 emit contacts();
156 delete cardSendTimer;
157 } else if ( press ) {
158 cardSendTimer = new QTimer();
159 cardSendTimer->start( 2000, TRUE );
160 connect( cardSendTimer, SIGNAL( timeout() ), this, SLOT( sendCard() ) );
161 }
162 return TRUE;
163 }
164 /* menu key now opens application menu/toolbar
165 if ( ke->simpleData.keycode == Key_F11 ) {
166 if ( press ) emit menu();
167 return TRUE;
168 }
169 */
170 if ( ke->simpleData.keycode == Key_F12 ) {
171 while( activePopupWidget() )
172 activePopupWidget()->close();
173 if ( press ) emit launch();
174 return TRUE;
175 }
176 if ( ke->simpleData.keycode == Key_F13 ) {
177 if ( press ) emit email();
178 return TRUE;
179 }
180 }
181 if ( ke->simpleData.keycode == Key_F34 ) {
182 if ( press ) emit power();
183 return TRUE;
184 }
185 if ( ke->simpleData.keycode == Key_F35 ) {
186 if ( press ) emit backlight();
187 return TRUE;
188 }
189 if ( ke->simpleData.keycode == Key_F32 ) {
190 if ( press ) QCopEnvelope e( "QPE/Desktop", "startSync()" );
191 return TRUE;
192 }
193 if ( ke->simpleData.keycode == Key_F31 && !ke->simpleData.modifiers ) {
194 if ( press ) emit symbol();
195 return TRUE;
196 }
197 if ( ke->simpleData.keycode == Key_NumLock ) {
198 if ( press ) emit numLockStateToggle();
199 }
200 if ( ke->simpleData.keycode == Key_CapsLock ) {
201 if ( press ) emit capsLockStateToggle();
202 }
203 if ( press )
204 qpedesktop->keyClick();
205 } else {
206 if ( e->type == QWSEvent::Mouse ) {
207 QWSMouseEvent *me = (QWSMouseEvent *)e;
208 static bool up = TRUE;
209 if ( me->simpleData.state&LeftButton ) {
210 if ( up ) {
211 up = FALSE;
212 qpedesktop->screenClick();
213 }
214 } else {
215 up = TRUE;
216 }
217 }
218 }
219
220 return QPEApplication::qwsEventFilter( e );
221}
222#endif
223
224void DesktopApplication::psTimeout()
225{
226 qpedesktop->checkMemory(); // in case no events are being generated
227
228 *ps = PowerStatusManager::readStatus();
229
230 if ( (ps->batteryStatus() == PowerStatus::VeryLow ) ) {
231 pa->alert( tr( "Battery is running very low." ), 6 );
232 }
233
234 if ( ps->batteryStatus() == PowerStatus::Critical ) {
235 pa->alert( tr( "Battery level is critical!\n"
236 "Keep power off until power restored!" ), 1 );
237 }
238
239 if ( ps->backupBatteryStatus() == PowerStatus::VeryLow ) {
240 pa->alert( tr( "The Back-up battery is very low.\nPlease charge the back-up battery." ), 3 );
241 }
242}
243
244
245void DesktopApplication::sendCard()
246{
247 delete cardSendTimer;
248 cardSendTimer = 0;
249 QString card = getenv("HOME");
250 card += "/Applications/addressbook/businesscard.vcf";
251
252 if ( QFile::exists( card ) ) {
253 QCopEnvelope e("QPE/Obex", "send(QString,QString,QString)");
254 QString mimetype = "text/x-vCard";
255 e << tr("business card") << card << mimetype;
256 }
257}
258
259#if defined(QPE_HAVE_MEMALERTER)
260QPE_MEMALERTER_IMPL
261#endif
262
263#if defined(CUSTOM_SOUND_IMPL)
264CUSTOM_SOUND_IMPL
265#endif
266
267//===========================================================================
268
269Desktop::Desktop() :
270 QWidget( 0, 0, WStyle_Tool | WStyle_Customize ),
271 qcopBridge( 0 ),
272 transferServer( 0 ),
273 packageSlave( 0 )
274{
275#ifdef CUSTOM_SOUND_INIT
276 CUSTOM_SOUND_INIT;
277#endif
278
279 qpedesktop = this;
280
281// bg = new Info( this );
282 tb = new TaskBar;
283
284 launcher = new Launcher( 0, 0, WStyle_Customize | QWidget::WGroupLeader );
285
286 connect(launcher, SIGNAL(busy()), tb, SLOT(startWait()));
287 connect(launcher, SIGNAL(notBusy(const QString&)), tb, SLOT(stopWait(const QString&)));
288
289 int displayw = qApp->desktop()->width();
290 int displayh = qApp->desktop()->height();
291
292
293 QSize sz = tb->sizeHint();
294
295 setGeometry( 0, displayh-sz.height(), displayw, sz.height() );
296 tb->setGeometry( 0, displayh-sz.height(), displayw, sz.height() );
297
298 tb->show();
299 launcher->showMaximized();
300 launcher->show();
301 launcher->raise();
302#if defined(QPE_HAVE_MEMALERTER)
303 initMemalerter();
304#endif
305 // start services
306 startTransferServer();
307 (void) new IrServer( this );
308 rereadVolumes();
309
310 packageSlave = new PackageSlave( this );
311 connect(qApp, SIGNAL(volumeChanged(bool)), this, SLOT(rereadVolumes()));
312
313 qApp->installEventFilter( this );
314}
315
316void Desktop::show()
317{
318 login(TRUE);
319 QWidget::show();
320}
321
322Desktop::~Desktop()
323{
324 delete launcher;
325 delete tb;
326 delete qcopBridge;
327 delete transferServer;
328}
329
330bool Desktop::recoverMemory()
331{
332 return tb->recoverMemory();
333}
334
335void Desktop::checkMemory()
336{
337#if defined(QPE_HAVE_MEMALERTER)
338 static bool ignoreNormal=FALSE;
339 static bool existingMessage=FALSE;
340
341 if(existingMessage)
342 return; // don't show a second message while still on first
343
344 existingMessage = TRUE;
345 switch ( memstate ) {
346 case Unknown:
347 break;
348 case Low:
349 memstate = Unknown;
350 if ( recoverMemory() )
351 ignoreNormal = TRUE;
352 else
353 QMessageBox::warning( 0 , "Memory Status",
354 "The memory smacks of shortage. \n"
355 "Please save data. " );
356 break;
357 case Normal:
358 memstate = Unknown;
359 if ( ignoreNormal )
360 ignoreNormal = FALSE;
361 else
362 QMessageBox::information ( 0 , "Memory Status",
363 "There is enough memory again." );
364 break;
365 case VeryLow:
366 memstate = Unknown;
367 QMessageBox::critical( 0 , "Memory Status",
368 "The memory is very low. \n"
369 "Please end this application \n"
370 "immediately." );
371 recoverMemory();
372 }
373 existingMessage = FALSE;
374#endif
375}
376
377static bool isVisibleWindow(int wid)
378{
379 const QList<QWSWindow> &list = qwsServer->clientWindows();
380 QWSWindow* w;
381 for (QListIterator<QWSWindow> it(list); (w=it.current()); ++it) {
382 if ( w->winId() == wid )
383 return !w->isFullyObscured();
384 }
385 return FALSE;
386}
387
388static bool hasVisibleWindow(const QString& clientname)
389{
390 const QList<QWSWindow> &list = qwsServer->clientWindows();
391 QWSWindow* w;
392 for (QListIterator<QWSWindow> it(list); (w=it.current()); ++it) {
393 if ( w->client()->identity() == clientname && !w->isFullyObscured() )
394 return TRUE;
395 }
396 return FALSE;
397}
398
399void Desktop::raiseLauncher()
400{
401 if ( isVisibleWindow(launcher->winId()) )
402 launcher->nextView();
403 else
404 launcher->raise();
405}
406
407void Desktop::executeOrModify(const QString& appLnkFile)
408{
409 AppLnk lnk(MimeType::appsFolderName() + "/" + appLnkFile);
410 if ( lnk.isValid() ) {
411 QCString app = lnk.exec().utf8();
412 Global::terminateBuiltin("calibrate");
413 if ( QCopChannel::isRegistered("QPE/Application/" + app) ) {
414 MRUList::addTask(&lnk);
415 if ( hasVisibleWindow(app) )
416 QCopChannel::send("QPE/Application/" + app, "nextView()");
417 else
418 QCopChannel::send("QPE/Application/" + app, "raise()");
419 } else {
420 lnk.execute();
421 }
422 }
423}
424
425void Desktop::raiseDatebook()
426{
427 executeOrModify("Applications/datebook.desktop");
428}
429
430void Desktop::raiseContacts()
431{
432 executeOrModify("Applications/addressbook.desktop");
433}
434
435void Desktop::raiseMenu()
436{
437 Global::terminateBuiltin("calibrate");
438 tb->startMenu()->launch();
439}
440
441void Desktop::raiseEmail()
442{
443 executeOrModify("Applications/qtmail.desktop");
444}
445
446#if defined(QPE_HAVE_TOGGLELIGHT)
447#include <qpe/config.h>
448
449#include <sys/ioctl.h>
450#include <sys/types.h>
451#include <fcntl.h>
452#include <unistd.h>
453#include <errno.h>
454#include <linux/ioctl.h>
455#include <time.h>
456#endif
457
458static bool blanked=FALSE;
459
460static void blankScreen()
461{
462 if ( !qt_screen ) return;
463 /* Should use a big black window instead.
464 QGfx* g = qt_screen->screenGfx();
465 g->fillRect(0,0,qt_screen->width(),qt_screen->height());
466 delete g;
467 */
468 blanked = TRUE;
469}
470
471static void darkScreen()
472{
473 extern void qpe_setBacklight(int);
474 qpe_setBacklight(0); // force off
475}
476
477
478void Desktop::togglePower()
479{
480 bool wasloggedin = loggedin;
481 loggedin=0;
482 darkScreen();
483 if ( wasloggedin )
484 blankScreen();
485 system("apm --suspend");
486 QWSServer::screenSaverActivate( FALSE );
487 {
488 QCopEnvelope("QPE/Card", "mtabChanged()" ); // might have changed while asleep
489 QCopEnvelope e("QPE/System", "setBacklight(int)");
490 e << -3; // Force on
491 }
492 if ( wasloggedin )
493 login(TRUE);
494 //qcopBridge->closeOpenConnections();
495 //qDebug("called togglePower()!!!!!!");
496}
497
498void Desktop::toggleLight()
499{
500 QCopEnvelope e("QPE/System", "setBacklight(int)");
501 e << -2; // toggle
502}
503
504void Desktop::toggleSymbolInput()
505{
506 tb->toggleSymbolInput();
507}
508
509void Desktop::toggleNumLockState()
510{
511 tb->toggleNumLockState();
512}
513
514void Desktop::toggleCapsLockState()
515{
516 tb->toggleCapsLockState();
517}
518
519void Desktop::styleChange( QStyle &s )
520{
521 QWidget::styleChange( s );
522 int displayw = qApp->desktop()->width();
523 int displayh = qApp->desktop()->height();
524
525 QSize sz = tb->sizeHint();
526
527 tb->setGeometry( 0, displayh-sz.height(), displayw, sz.height() );
528}
529
530void DesktopApplication::shutdown()
531{
532 if ( type() != GuiServer )
533 return;
534 ShutdownImpl *sd = new ShutdownImpl( 0, 0, WDestructiveClose );
535 connect( sd, SIGNAL(shutdown(ShutdownImpl::Type)),
536 this, SLOT(shutdown(ShutdownImpl::Type)) );
537 sd->showMaximized();
538}
539
540void DesktopApplication::shutdown( ShutdownImpl::Type t )
541{
542 switch ( t ) {
543 case ShutdownImpl::ShutdownSystem:
544 execlp("shutdown", "shutdown", "-h", "now", (void*)0);
545 break;
546 case ShutdownImpl::RebootSystem:
547 execlp("shutdown", "shutdown", "-r", "now", (void*)0);
548 break;
549 case ShutdownImpl::RestartDesktop:
550 restart();
551 break;
552 case ShutdownImpl::TerminateDesktop:
553 prepareForTermination(FALSE);
554 quit();
555 break;
556 }
557}
558
559void DesktopApplication::restart()
560{
561 prepareForTermination(TRUE);
562
563#ifdef Q_WS_QWS
564 for ( int fd = 3; fd < 100; fd++ )
565 close( fd );
566#if defined(QT_DEMO_SINGLE_FLOPPY)
567 execl( "/sbin/init", "qpe", 0 );
568#elif defined(QT_QWS_CASSIOPEIA)
569 execl( "/bin/sh", "sh", 0 );
570#else
571 execl( (qpeDir()+"/bin/qpe").latin1(), "qpe", 0 );
572#endif
573 exit(1);
574#endif
575}
576
577void Desktop::startTransferServer()
578{
579 // start qcop bridge server
580 qcopBridge = new QCopBridge( 4243 );
581 if ( !qcopBridge->ok() ) {
582 delete qcopBridge;
583 qcopBridge = 0;
584 }
585 // start transfer server
586 transferServer = new TransferServer( 4242 );
587 if ( !transferServer->ok() ) {
588 delete transferServer;
589 transferServer = 0;
590 }
591 if ( !transferServer || !qcopBridge )
592 startTimer( 2000 );
593}
594
595void Desktop::timerEvent( QTimerEvent *e )
596{
597 killTimer( e->timerId() );
598 startTransferServer();
599}
600
601void Desktop::terminateServers()
602{
603 delete transferServer;
604 delete qcopBridge;
605 transferServer = 0;
606 qcopBridge = 0;
607}
608
609void Desktop::rereadVolumes()
610{
611 Config cfg("Sound");
612 cfg.setGroup("System");
613 touchclick = cfg.readBoolEntry("Touch");
614 keyclick = cfg.readBoolEntry("Key");
615}
616
617void Desktop::keyClick()
618{
619#ifdef CUSTOM_SOUND_KEYCLICK
620 if ( keyclick )
621 CUSTOM_SOUND_KEYCLICK;
622#endif
623}
624
625void Desktop::screenClick()
626{
627#ifdef CUSTOM_SOUND_TOUCH
628 if ( touchclick )
629 CUSTOM_SOUND_TOUCH;
630#endif
631}
632
633void Desktop::soundAlarm()
634{
635#ifdef CUSTOM_SOUND_ALARM
636 CUSTOM_SOUND_ALARM;
637#endif
638}
639
640bool Desktop::eventFilter( QObject *w, QEvent *ev )
641{
642 if ( ev->type() == QEvent::KeyPress ) {
643 QKeyEvent *ke = (QKeyEvent *)ev;
644 if ( ke->key() == Qt::Key_F11 ) { // menu key
645 QWidget *active = qApp->activeWindow();
646 if ( active && active->isPopup() ) {
647 active->close();
648 }
649 raiseMenu();
650 return TRUE;
651 }
652 }
653 return FALSE;
654}
655
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#ifndef __DESKTOP_H__
22#define __DESKTOP_H__
23
24
25#include "shutdownimpl.h"
26
27#include <qpe/qpeapplication.h>
28
29#include <qwidget.h>
30
31class Background;
32class Launcher;
33class TaskBar;
34class PowerStatus;
35class QCopBridge;
36class TransferServer;
37class DesktopPowerAlerter;
38class PackageSlave;
39
40class DesktopApplication : public QPEApplication
41{
42 Q_OBJECT
43public:
44 DesktopApplication( int& argc, char **argv, Type t );
45 ~DesktopApplication();
46signals:
47 void home();
48 void datebook();
49 void contacts();
50 void launch();
51 void email();
52 void backlight();
53 void power();
54 void symbol();
55 void numLockStateToggle();
56 void capsLockStateToggle();
57 void prepareForRestart();
58
59protected:
60#ifdef Q_WS_QWS
61 bool qwsEventFilter( QWSEvent * );
62#endif
63 void shutdown();
64 void restart();
65
66protected slots:
67 void shutdown(ShutdownImpl::Type);
68 void psTimeout();
69 void sendCard();
70private:
71 DesktopPowerAlerter *pa;
72 PowerStatus *ps;
73 QTimer *cardSendTimer;
74};
75
76
77class Desktop : public QWidget {
78 Q_OBJECT
79public:
80 Desktop();
81 ~Desktop();
82
83 static bool screenLocked();
84
85 void show();
86 void checkMemory();
87
88 void keyClick();
89 void screenClick();
90 static void soundAlarm();
91
92public slots:
93 void raiseDatebook();
94 void raiseContacts();
95 void raiseMenu();
96 void raiseLauncher();
97 void raiseEmail();
98 void togglePower();
99 void toggleLight();
100 void toggleNumLockState();
101 void toggleCapsLockState();
102 void toggleSymbolInput();
103 void terminateServers();
104 void rereadVolumes();
105
106protected:
107 void executeOrModify(const QString& appLnkFile);
108 void styleChange( QStyle & );
109 void timerEvent( QTimerEvent *e );
110 bool eventFilter( QObject *, QEvent * );
111
112 QWidget *bg;
113 Launcher *launcher;
114 TaskBar *tb;
115
116private:
117 void startTransferServer();
118 bool recoverMemory();
119
120 QCopBridge *qcopBridge;
121 TransferServer *transferServer;
122 PackageSlave *packageSlave;
123
124 bool keyclick,touchclick;
125};
126
127
128#endif // __DESKTOP_H__
129
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "info.h"
22#include "desktop.h"
23
24#include <qpe/resource.h>
25#include <qpe/version.h>
26
27#include <qlayout.h>
28#include <qimage.h>
29#include <qpainter.h>
30#include <qsimplerichtext.h>
31
32
33Info *desktopInfo = NULL;
34
35
36Info::Info( Desktop *d ) : Background( d ), needsClear(FALSE), menuHasBeenClicked(FALSE)
37{
38 QString motd;
39 /* eg.
40 =
41 "<table width=100% cellspacing=0 cellpadding=2>"
42 "<tr><td bgcolor=#9090ff><h2>Today&nbsp;&nbsp;&nbsp;&nbsp;<small>June 15, 2001</small></h2></td>"
43 "<tr><td bgcolor=#c0c0ff><big><a href=datebook>Appointments</a></big>"
44 "<tr><td bgcolor=#e0e0ff>"
45 "<b>8:30am</b> Meeting with John<br>"
46 "<b>1:10pm</b> Lunch with Sharon"
47 "<tr><td bgcolor=#c0c0ff><big><a href=todo>Reminders</a></big>"
48 "<tr><td bgcolor=#e0e0ff>"
49 "<b>#1</b> Port XMAME to QPE<br>"
50 "<b>#2</b> Flowers for wife"
51 "<tr><td bgcolor=#c0c0ff><big><a href=channels>Net channels</a></big>"
52 "<tr><td bgcolor=#e0e0ff>"
53 "<b>LinuxDevices:</b><a href=http://www.linuxdevices.com> QPE announcement</a><br>"
54 "<b>Slashdot:</b><a href=http://www.slashdot.org> GPL Examined</a>"
55 "</table>";
56 */
57 info = new QSimpleRichText(motd, QFont("lucidux_sans",10));
58 desktopInfo = this;
59}
60
61
62void Info::mouseReleaseEvent( QMouseEvent * )
63{
64}
65
66
67void Info::menuClicked( )
68{
69 QPainter p(this);
70 if ( needsClear ) {
71 QColor col = colorGroup().color( QColorGroup::Button ).dark( 0 );
72 p.fillRect( 5, height() - 24, width() - 5, 20, col );
73 needsClear = FALSE;
74 menuHasBeenClicked = TRUE;
75 }
76}
77
78
79void Info::paintEvent( QPaintEvent *e )
80{
81 QPainter p(this);
82
83 BrushStyle styles[] = { Dense1Pattern, Dense2Pattern, Dense3Pattern,
84 Dense4Pattern, Dense5Pattern, Dense6Pattern };
85
86 QColor shade = colorGroup().color( QColorGroup::Button ).dark( 110 );
87 int blend = width() * 3 / 4;
88 int step = blend/6;
89 p.fillRect( 0, 0, width()-blend, 30, shade );
90 for ( int i = 0; i < 6; i++ ) {
91 QBrush brush( shade, styles[i] );
92 p.fillRect( width()-blend+i*step, 0, step, 30, brush );
93 }
94 p.setFont( QFont("Helvetica", 24, QFont::Bold) );
95 p.setPen( shade.dark( 140 ) );
96 p.drawText( 5, 24, "QPE" );
97 int pos = 5 + p.fontMetrics().width( "QPE" );
98 QFont f("Helvetica", 10, QFont::Bold);
99 p.setFont( f );
100 p.drawText( pos + 5, 24, QString( "Version " ) + QPE_VERSION );
101
102 if (!menuHasBeenClicked) {
103 p.drawText( 5, height()-10, QString( "Click on the " ) );
104 int pos = 5 + p.fontMetrics().width( "Click on the " );
105 p.drawPixmap( pos, height()-10-14, Resource::loadPixmap( "go" ) );
106 p.drawText( pos + 16, height()-10, QString( " logo to start." ) );
107 needsClear = TRUE;
108 }
109
110 if ( info ) {
111 info->setWidth(&p,width()-10);
112 info->draw(&p, 5, 35, e->region(), colorGroup());
113 }
114}
115
116
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#ifndef __INFO_H__
22#define __INFO_H__
23
24
25#include <qwidget.h>
26#include <qpainter.h>
27#include "background.h"
28
29class QSimpleRichText;
30
31class Info : public Background {
32 Q_OBJECT
33public:
34 Info( Desktop *d );
35 void menuClicked( );
36
37signals:
38 void giveInfo( );
39
40protected:
41 void mouseReleaseEvent( QMouseEvent *e );
42 void paintEvent( QPaintEvent *pe );
43
44private:
45 QSimpleRichText* info;
46 bool needsClear;
47 bool menuHasBeenClicked;
48};
49
50
51extern Info *desktopInfo;
52
53
54#endif // __INFO_H__
55
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "inputmethods.h"
22
23#include <qpe/config.h>
24#include <qpe/qpeapplication.h>
25#include <qpe/inputmethodinterface.h>
26#include <qpe/qlibrary.h>
27
28#include <qpopupmenu.h>
29#include <qpushbutton.h>
30#include <qtoolbutton.h>
31#include <qwidget.h>
32#include <qlayout.h>
33#include <qtimer.h>
34#include <qdir.h>
35#include <stdlib.h>
36#include <qtranslator.h>
37
38#ifdef Q_WS_QWS
39#include <qwindowsystem_qws.h>
40#include <qwsevent_qws.h>
41#endif
42
43#ifdef SINGLE_APP
44#include "handwritingimpl.h"
45#include "keyboardimpl.h"
46#include "pickboardimpl.h"
47#endif
48
49
50/* XPM */
51static const char * tri_xpm[]={
52"9 9 2 1",
53"a c #000000",
54". c None",
55".........",
56".........",
57".........",
58"....a....",
59"...aaa...",
60"..aaaaa..",
61".aaaaaaa.",
62".........",
63"........."};
64
65static const int inputWidgetStyle = QWidget::WStyle_Customize |
66 QWidget::WStyle_Tool |
67 QWidget::WStyle_StaysOnTop |
68 QWidget::WGroupLeader;
69
70InputMethods::InputMethods( QWidget *parent ) :
71 QWidget( parent, "InputMethods", WStyle_Tool | WStyle_Customize )
72{
73 method = NULL;
74
75 QHBoxLayout *hbox = new QHBoxLayout( this );
76
77 kbdButton = new QToolButton( this );
78 kbdButton->setFocusPolicy(NoFocus);
79 kbdButton->setToggleButton( TRUE );
80 kbdButton->setFixedHeight( 17 );
81 kbdButton->setFixedWidth( 32 );
82 kbdButton->setAutoRaise( TRUE );
83 kbdButton->setUsesBigPixmap( TRUE );
84 hbox->addWidget( kbdButton );
85 connect( kbdButton, SIGNAL(toggled(bool)), this, SLOT(showKbd(bool)) );
86
87 kbdChoice = new QToolButton( this );
88 kbdChoice->setFocusPolicy(NoFocus);
89 kbdChoice->setPixmap( QPixmap( (const char **)tri_xpm ) );
90 kbdChoice->setFixedHeight( 17 );
91 kbdChoice->setFixedWidth( 12 );
92 kbdChoice->setAutoRaise( TRUE );
93 hbox->addWidget( kbdChoice );
94 connect( kbdChoice, SIGNAL(clicked()), this, SLOT(chooseKbd()) );
95
96 connect( (QPEApplication*)qApp, SIGNAL(clientMoused()),
97 this, SLOT(resetStates()) );
98
99 loadInputMethods();
100}
101
102InputMethods::~InputMethods()
103{
104#ifndef SINGLE_APP
105 QValueList<InputMethod>::Iterator mit;
106 for ( mit = inputMethodList.begin(); mit != inputMethodList.end(); ++mit ) {
107 int i = (*mit).interface->release();
108 (*mit).library->unload();
109 delete (*mit).library;
110 }
111#endif
112}
113
114void InputMethods::hideInputMethod()
115{
116 kbdButton->setOn( FALSE );
117}
118
119void InputMethods::showInputMethod()
120{
121 kbdButton->setOn( TRUE );
122}
123
124void InputMethods::showInputMethod(const QString& name)
125{
126 int i = 0;
127 QValueList<InputMethod>::Iterator it;
128 InputMethod *im = 0;
129 for ( it = inputMethodList.begin(); it != inputMethodList.end(); ++it, i++ ) {
130 if ( (*it).interface->name() == name ) {
131 im = &(*it);
132 break;
133 }
134 }
135 if ( im )
136 chooseMethod(im);
137}
138
139void InputMethods::resetStates()
140{
141 if ( method )
142 method->interface->resetState();
143}
144
145QRect InputMethods::inputRect() const
146{
147 if ( !method || !method->widget->isVisible() )
148 return QRect();
149 else
150 return method->widget->geometry();
151}
152
153void InputMethods::loadInputMethods()
154{
155#ifndef SINGLE_APP
156 hideInputMethod();
157 method = 0;
158
159 QValueList<InputMethod>::Iterator mit;
160 for ( mit = inputMethodList.begin(); mit != inputMethodList.end(); ++mit ) {
161 (*mit).interface->release();
162 (*mit).library->unload();
163 delete (*mit).library;
164 }
165 inputMethodList.clear();
166
167 QString path = QPEApplication::qpeDir() + "/plugins/inputmethods";
168 QDir dir( path, "lib*.so" );
169 QStringList list = dir.entryList();
170 QStringList::Iterator it;
171 for ( it = list.begin(); it != list.end(); ++it ) {
172 InputMethodInterface *iface = 0;
173 QLibrary *lib = new QLibrary( path + "/" + *it );
174 if ( lib->queryInterface( IID_InputMethod, (QUnknownInterface**)&iface ) == QS_OK ) {
175 InputMethod input;
176 input.library = lib;
177 input.interface = iface;
178 input.widget = input.interface->inputMethod( 0, inputWidgetStyle );
179 input.interface->onKeyPress( this, SLOT(sendKey(ushort,ushort,ushort,bool,bool)) );
180 inputMethodList.append( input );
181 QString lang = getenv( "LANG" );
182 QTranslator * trans = new QTranslator(qApp);
183 QString type = (*it).left( (*it).find(".") );
184 QString tfn = QPEApplication::qpeDir()+"/i18n/"+lang+"/"+type+".qm";
185 qDebug("tr for inputmethod: %s", tfn.latin1() );
186 if ( trans->load( tfn ))
187 qApp->installTranslator( trans );
188 else
189 delete trans;
190 } else {
191 delete lib;
192 }
193 }
194#else
195 InputMethod input;
196 input.interface = new HandwritingImpl();
197 input.widget = input.interface->inputMethod( 0, inputWidgetStyle );
198 input.interface->onKeyPress( this, SLOT(sendKey(ushort,ushort,ushort,bool,bool)) );
199 inputMethodList.append( input );
200 input.interface = new KeyboardImpl();
201 input.widget = input.interface->inputMethod( 0, inputWidgetStyle );
202 input.interface->onKeyPress( this, SLOT(sendKey(ushort,ushort,ushort,bool,bool)) );
203 inputMethodList.append( input );
204 input.interface = new PickboardImpl();
205 input.widget = input.interface->inputMethod( 0, inputWidgetStyle );
206 input.interface->onKeyPress( this, SLOT(sendKey(ushort,ushort,ushort,bool,bool)) );
207 inputMethodList.append( input );
208#endif
209 if ( !inputMethodList.isEmpty() ) {
210 method = &inputMethodList[0];
211 kbdButton->setPixmap( *method->interface->icon() );
212 }
213 if ( !inputMethodList.isEmpty() )
214 kbdButton->show();
215 else
216 kbdButton->hide();
217 if ( inputMethodList.count() > 1 )
218 kbdChoice->show();
219 else
220 kbdChoice->hide();
221}
222
223void InputMethods::chooseKbd()
224{
225 QPopupMenu pop( this );
226
227 int i = 0;
228 QValueList<InputMethod>::Iterator it;
229 for ( it = inputMethodList.begin(); it != inputMethodList.end(); ++it, i++ ) {
230 pop.insertItem( (*it).interface->name(), i );
231 if ( method == &(*it) )
232 pop.setItemChecked( i, TRUE );
233 }
234
235 QPoint pt = mapToGlobal(kbdChoice->geometry().topRight());
236 QSize s = pop.sizeHint();
237 pt.ry() -= s.height();
238 pt.rx() -= s.width();
239 i = pop.exec( pt );
240 if ( i == -1 )
241 return;
242 InputMethod *im = &inputMethodList[i];
243 chooseMethod(im);
244}
245
246void InputMethods::chooseMethod(InputMethod* im)
247{
248 if ( im != method ) {
249 if ( method && method->widget->isVisible() )
250 method->widget->hide();
251 method = im;
252 kbdButton->setPixmap( *method->interface->icon() );
253 }
254 if ( !kbdButton->isOn() )
255 kbdButton->setOn( TRUE );
256 else
257 showKbd( TRUE );
258}
259
260
261void InputMethods::showKbd( bool on )
262{
263 if ( !method )
264 return;
265
266 if ( on ) {
267 method->interface->resetState();
268 // HACK... Make the texteditor fit with all input methods
269 // Input methods should also never use more than about 40% of the screen
270 int height = QMIN( method->widget->sizeHint().height(), 134 );
271 method->widget->resize( qApp->desktop()->width(), height );
272 method->widget->move( 0, mapToGlobal( QPoint() ).y() - height );
273 method->widget->show();
274 } else {
275 method->widget->hide();
276 }
277
278 emit inputToggled( on );
279}
280
281bool InputMethods::shown() const
282{
283 return method && method->widget->isVisible();
284}
285
286QString InputMethods::currentShown() const
287{
288 return method && method->widget->isVisible()
289 ? method->interface->name() : QString::null;
290}
291
292void InputMethods::sendKey( ushort unicode, ushort scancode, ushort mod, bool press, bool repeat )
293{
294#if defined(Q_WS_QWS)
295 QWSServer::sendKeyEvent( unicode, scancode, mod, press, repeat );
296#endif
297}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#ifndef __INPUT_METHODS_H__
22#define __INPUT_METHODS_H__
23
24
25#include <qpe/inputmethodinterface.h>
26
27#include <qwidget.h>
28#include <qvaluelist.h>
29
30class QToolButton;
31class QLibrary;
32
33struct InputMethod
34{
35#ifndef QT_NO_COMPONENT
36 QLibrary *library;
37#endif
38 QWidget *widget;
39 InputMethodInterface *interface;
40};
41
42class InputMethods : public QWidget
43{
44 Q_OBJECT
45public:
46 InputMethods( QWidget * );
47 ~InputMethods();
48
49 QRect inputRect() const;
50 bool shown() const;
51 QString currentShown() const; // name of interface
52 void showInputMethod(const QString& id);
53 void showInputMethod();
54 void hideInputMethod();
55 void loadInputMethods();
56
57signals:
58 void inputToggled( bool on );
59
60private slots:
61 void chooseKbd();
62 void showKbd( bool );
63 void resetStates();
64 void sendKey( ushort unicode, ushort scancode, ushort modifiers, bool, bool );
65
66private:
67 void chooseMethod(InputMethod* im);
68 QToolButton *kbdButton;
69 QToolButton *kbdChoice;
70 InputMethod *method;
71 QValueList<InputMethod> inputMethodList;
72};
73
74
75#endif // __INPUT_METHODS_H__
76
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 @@
1#include "irserver.h"
2
3#include <qpe/qlibrary.h>
4#include <qpe/qpeapplication.h>
5
6#include <qtranslator.h>
7#include <stdlib.h>
8
9#include "obexinterface.h"
10
11#include <qdir.h>
12
13IrServer::IrServer( QObject *parent, const char *name )
14 : QObject( parent, name )
15{
16 lib = 0;
17 QString path = QPEApplication::qpeDir() + "/plugins/obex/";
18 QDir dir( path, "lib*.so" );
19 QStringList list = dir.entryList();
20 QStringList::Iterator it;
21 for ( it = list.begin(); it != list.end(); ++it ) {
22 ObexInterface *iface = 0;
23 QLibrary *trylib = new QLibrary( path + *it );
24 qDebug("trying lib %s", (path + (*it)).latin1() );
25 if ( trylib->queryInterface( IID_ObexInterface, (QUnknownInterface**)&iface ) == QS_OK ) {
26 lib = trylib;
27 qDebug("found obex lib" );
28 QString lang = getenv( "LANG" );
29 QTranslator * trans = new QTranslator(qApp);
30 QString type = (*it).left( (*it).find(".") );
31 QString tfn = QPEApplication::qpeDir()+"/i18n/"+lang+"/"+type+".qm";
32 qDebug("tr fpr obex: %s", tfn.latin1() );
33 if ( trans->load( tfn ))
34 qApp->installTranslator( trans );
35 else
36 delete trans;
37
38 break;
39 } else {
40 delete lib;
41 }
42 }
43 if ( !lib )
44 qDebug("could not load IR plugin" );
45}
46
47IrServer::~IrServer()
48{
49 delete lib;
50}
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 @@
1#ifndef IRSERVER_H
2#define IRSERVER_H
3
4#include <qobject.h>
5
6class QCopChannel;
7class QLibrary;
8
9class IrServer : public QObject
10{
11 Q_OBJECT
12public:
13 IrServer( QObject *parent = 0, const char *name = 0 );
14 ~IrServer();
15
16private:
17 QLibrary *lib;
18};
19
20#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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include <qpe/qcopenvelope_qws.h>
22#include <qpe/resource.h>
23#include <qpe/applnk.h>
24#include <qpe/config.h>
25#include <qpe/global.h>
26#include <qpe/qpeapplication.h>
27#include <qpe/mimetype.h>
28#include <qpe/storage.h>
29#include <qpe/palmtoprecord.h>
30
31#include <qdir.h>
32#include <qwindowsystem_qws.h>
33#include <qtimer.h>
34#include <qcombobox.h>
35#include <qvbox.h>
36#include <qlayout.h>
37#include <qstyle.h>
38#include <qpushbutton.h>
39#include <qtabbar.h>
40#include <qwidgetstack.h>
41#include <qlayout.h>
42#include <qregexp.h>
43#include <qmessagebox.h>
44#include <qframe.h>
45#include <qpainter.h>
46#include <qlabel.h>
47#include <qtextstream.h>
48
49#include "launcherview.h"
50#include "launcher.h"
51#include "syncdialog.h"
52#include "desktop.h"
53#include <qpe/lnkproperties.h>
54#include "mrulist.h"
55#include "qrsync.h"
56#include <stdlib.h>
57#include <unistd.h>
58
59#if defined(_OS_LINUX_) || defined(Q_OS_LINUX)
60#include <stdio.h>
61#include <sys/vfs.h>
62#include <mntent.h>
63#endif
64
65//#define SHOW_ALL
66
67CategoryTabWidget::CategoryTabWidget( QWidget* parent ) :
68 QVBox( parent )
69{
70 categoryBar = 0;
71 stack = 0;
72}
73
74void CategoryTabWidget::prevTab()
75{
76 if ( categoryBar ) {
77 int n = categoryBar->count();
78 int tab = categoryBar->currentTab();
79 if ( tab >= 0 )
80 categoryBar->setCurrentTab( (tab - 1 + n)%n );
81 }
82}
83
84void CategoryTabWidget::nextTab()
85{
86 if ( categoryBar ) {
87 int n = categoryBar->count();
88 int tab = categoryBar->currentTab();
89 categoryBar->setCurrentTab( (tab + 1)%n );
90 }
91}
92
93void CategoryTabWidget::addItem( const QString& linkfile )
94{
95 int i=0;
96 AppLnk *app = new AppLnk(linkfile);
97 if ( !app->isValid() ) {
98 delete app;
99 return;
100 }
101 if ( !app->file().isEmpty() ) {
102 // A document
103 delete app;
104 app = new DocLnk(linkfile);
105 ((LauncherView*)(stack->widget(ids.count()-1)))->addItem(app);
106 return;
107 }
108 for ( QStringList::Iterator it=ids.begin(); it!=ids.end(); ++it) {
109 if ( !(*it).isEmpty() ) {
110 QRegExp tf(*it,FALSE,TRUE);
111 if ( tf.match(app->type()) >= 0 ) {
112 ((LauncherView*)stack->widget(i))->addItem(app);
113 return;
114 }
115 i++;
116 }
117 }
118}
119
120void CategoryTabWidget::initializeCategories(AppLnkSet* rootFolder,
121 AppLnkSet* docFolder, const QList<FileSystem> &fs)
122{
123 delete categoryBar;
124 categoryBar = new CategoryTabBar( this );
125 QPalette pal = categoryBar->palette();
126 pal.setColor( QColorGroup::Light, pal.color(QPalette::Active,QColorGroup::Shadow) );
127 pal.setColor( QColorGroup::Background, pal.active().background().light(110) );
128 categoryBar->setPalette( pal );
129
130 delete stack;
131 stack = new QWidgetStack(this);
132 tabs=0;
133
134 ids.clear();
135
136 QStringList types = rootFolder->types();
137 for ( QStringList::Iterator it=types.begin(); it!=types.end(); ++it) {
138 if ( !(*it).isEmpty() ) {
139 newView(*it,rootFolder->typePixmap(*it),rootFolder->typeName(*it));
140 }
141 }
142 QListIterator<AppLnk> it( rootFolder->children() );
143 AppLnk* l;
144 while ( (l=it.current()) ) {
145 if ( l->type() == "Separator" ) {
146 rootFolder->remove(l);
147 delete l;
148 } else {
149 int i=0;
150 for ( QStringList::Iterator it=types.begin(); it!=types.end(); ++it) {
151 if ( *it == l->type() )
152 ((LauncherView*)stack->widget(i))->addItem(l,FALSE);
153 i++;
154 }
155 }
156 ++it;
157 }
158 rootFolder->detachChildren();
159 for (int i=0; i<tabs; i++)
160 ((LauncherView*)stack->widget(i))->sort();
161
162 // all documents
163 docview = newView( QString::null, Resource::loadPixmap("DocsIcon"), tr("Documents"));
164 docview->populate( docFolder, QString::null );
165 docFolder->detachChildren();
166 docview->setFileSystems(fs);
167 docview->setToolsEnabled(TRUE);
168
169 connect( categoryBar, SIGNAL(selected(int)), stack, SLOT(raiseWidget(int)) );
170
171 ((LauncherView*)stack->widget(0))->setFocus();
172
173 categoryBar->show();
174 stack->show();
175}
176
177void CategoryTabWidget::updateDocs(AppLnkSet* docFolder, const QList<FileSystem> &fs)
178{
179 docview->populate( docFolder, QString::null );
180 docFolder->detachChildren();
181 docview->setFileSystems(fs);
182 docview->updateTools();
183}
184
185LauncherView* CategoryTabWidget::newView( const QString& id, const QPixmap& pm, const QString& label )
186{
187 LauncherView* view = new LauncherView( stack );
188 connect( view, SIGNAL(clicked(const AppLnk*)),
189 this, SIGNAL(clicked(const AppLnk*)));
190 connect( view, SIGNAL(rightPressed(AppLnk*)),
191 this, SIGNAL(rightPressed(AppLnk*)));
192 ids.append(id);
193 categoryBar->addTab( new QTab( pm, label ) );
194 stack->addWidget( view, tabs++ );
195 return view;
196}
197
198void CategoryTabWidget::updateLink(const QString& linkfile)
199{
200 int i=0;
201 LauncherView* view;
202 while ((view = (LauncherView*)stack->widget(i++))) {
203 if ( view->removeLink(linkfile) )
204 break;
205 }
206 addItem(linkfile);
207 docview->updateTools();
208}
209
210void CategoryTabWidget::paletteChange( const QPalette &p )
211{
212 QVBox::paletteChange( p );
213 QPalette pal = palette();
214 pal.setColor( QColorGroup::Light, pal.color(QPalette::Active,QColorGroup::Shadow) );
215 pal.setColor( QColorGroup::Background, pal.active().background().light(110) );
216 categoryBar->setPalette( pal );
217 categoryBar->update();
218}
219
220void CategoryTabWidget::setBusy(bool on)
221{
222 if ( on )
223 ((LauncherView*)stack->visibleWidget())->setBusy(TRUE);
224 else
225 for (int i=0; i<tabs; i++)
226 ((LauncherView*)stack->widget(i))->setBusy(FALSE);
227}
228
229
230CategoryTabBar::CategoryTabBar( QWidget *parent, const char *name )
231 : QTabBar( parent, name )
232{
233 setFocusPolicy( NoFocus );
234 connect( this, SIGNAL( selected(int) ), this, SLOT( layoutTabs() ) );
235}
236
237CategoryTabBar::~CategoryTabBar()
238{
239}
240
241void CategoryTabBar::layoutTabs()
242{
243 if ( !count() )
244 return;
245
246// int percentFalloffTable[] = { 100, 70, 40, 12, 6, 3, 1, 0 };
247 int hiddenTabWidth = -12;
248 int middleTab = currentTab();
249 int hframe, vframe, overlap;
250 style().tabbarMetrics( this, hframe, vframe, overlap );
251 QFontMetrics fm = fontMetrics();
252 int x = 0;
253 QRect r;
254 QTab *t;
255 int available = width()-1;
256 int required = 0;
257 for ( int i = 0; i < count(); i++ ) {
258 t = tab(i);
259 // if (( i < (middleTab - 1) ) || ( i > (middleTab + 1) )) {
260 if ( i != middleTab ) {
261 // required += hiddenTabWidth + hframe - overlap;
262 available -= hiddenTabWidth + hframe - overlap;
263 if ( t->iconSet() != 0 )
264 available -= t->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).width();
265 } else {
266 required += fm.width( t->text() ) + hframe - overlap;
267 if ( t->iconSet() != 0 )
268 required += t->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).width();
269 }
270 }
271 for ( int i = 0; i < count(); i++ ) {
272 t = tab(i);
273 // if (( i < (middleTab - 1) ) || ( i > (middleTab + 1) )) {
274 if ( i != middleTab ) {
275 int w = hiddenTabWidth;
276 int ih = 0;
277 if ( t->iconSet() != 0 ) {
278 w += t->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).width();
279 ih = t->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).height();
280 }
281 int h = QMAX( fm.height(), ih );
282 h = QMAX( h, QApplication::globalStrut().height() );
283
284 h += vframe;
285 w += hframe;
286
287 t->setRect( QRect(x, 0, w, h) );
288 x += t->rect().width() - overlap;
289 r = r.unite( t->rect() );
290 } else {
291 int w = fm.width( t->text() );
292 int ih = 0;
293 if ( t->iconSet() != 0 ) {
294 w += t->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).width();
295 ih = t->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).height();
296 }
297 int h = QMAX( fm.height(), ih );
298 h = QMAX( h, QApplication::globalStrut().height() );
299
300 h += vframe;
301 w += hframe;
302
303 // t->setRect( QRect(x, 0, w * available/required, h) );
304 t->setRect( QRect(x, 0, available, h) );
305 x += t->rect().width() - overlap;
306 r = r.unite( t->rect() );
307 }
308 }
309
310 QRect rr = tab(count()-1)->rect();
311 rr.setRight(width()-1);
312 tab(count()-1)->setRect( rr );
313
314 for ( t = tabList()->first(); t; t = tabList()->next() ) {
315 QRect tr = t->rect();
316 tr.setHeight( r.height() );
317 t->setRect( tr );
318 }
319
320 update();
321}
322
323
324void CategoryTabBar::paint( QPainter * p, QTab * t, bool selected ) const
325{
326#if QT_VERSION >= 300
327 QStyle::SFlags flags = QStyle::Style_Default;
328 if ( selected )
329 flags |= QStyle::Style_Selected;
330 style().drawControl( QStyle::CE_TabBarTab, p, this, t->rect(),
331 colorGroup(), flags, QStyleOption(t) );
332#else
333 style().drawTab( p, this, t, selected );
334#endif
335
336 QRect r( t->rect() );
337 QFont f( font() );
338 if ( selected )
339 f.setBold( TRUE );
340 p->setFont( f );
341
342 int iw = 0;
343 int ih = 0;
344 if ( t->iconSet() != 0 ) {
345 iw = t->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).width() + 2;
346 ih = t->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).height();
347 }
348 int w = iw + p->fontMetrics().width( t->text() ) + 4;
349 int h = QMAX(p->fontMetrics().height() + 4, ih );
350 paintLabel( p, QRect( r.left() + (r.width()-w)/2 - 3,
351 r.top() + (r.height()-h)/2, w, h ), t,
352#if QT_VERSION >= 300
353 t->identifier() == keyboardFocusTab()
354#else
355 t->identitifer() == keyboardFocusTab()
356#endif
357 );
358}
359
360
361void CategoryTabBar::paintLabel( QPainter* p, const QRect&,
362 QTab* t, bool has_focus ) const
363{
364 QRect r = t->rect();
365 // if ( t->id != currentTab() )
366 //r.moveBy( 1, 1 );
367 //
368 if ( t->iconSet() ) {
369 // the tab has an iconset, draw it in the right mode
370 QIconSet::Mode mode = (t->isEnabled() && isEnabled()) ? QIconSet::Normal : QIconSet::Disabled;
371 if ( mode == QIconSet::Normal && has_focus )
372 mode = QIconSet::Active;
373 QPixmap pixmap = t->iconSet()->pixmap( QIconSet::Small, mode );
374 int pixw = pixmap.width();
375 int pixh = pixmap.height();
376 p->drawPixmap( r.left() + 6, r.center().y() - pixh / 2 + 1, pixmap );
377 r.setLeft( r.left() + pixw + 5 );
378 }
379
380 QRect tr = r;
381
382 if ( r.width() < 20 )
383 return;
384
385 if ( t->isEnabled() && isEnabled() ) {
386#if defined(_WS_WIN32_)
387 if ( colorGroup().brush( QColorGroup::Button ) == colorGroup().brush( QColorGroup::Background ) )
388 p->setPen( colorGroup().buttonText() );
389 else
390 p->setPen( colorGroup().foreground() );
391#else
392 p->setPen( colorGroup().foreground() );
393#endif
394 p->drawText( tr, AlignCenter | AlignVCenter | ShowPrefix, t->text() );
395 } else {
396 p->setPen( palette().disabled().foreground() );
397 p->drawText( tr, AlignCenter | AlignVCenter | ShowPrefix, t->text() );
398 }
399}
400
401//---------------------------------------------------------------------------
402
403Launcher::Launcher( QWidget* parent, const char* name, WFlags fl )
404 : QMainWindow( parent, name, fl )
405{
406 setCaption( tr("Launcher") );
407
408 syncDialog = 0;
409
410 // we have a pretty good idea how big we'll be
411 setGeometry( 0, 0, qApp->desktop()->width(), qApp->desktop()->height() );
412
413 tabs = 0;
414 rootFolder = 0;
415 docsFolder = 0;
416
417 tabs = new CategoryTabWidget( this );
418 tabs->setMaximumWidth( qApp->desktop()->width() );
419 setCentralWidget( tabs );
420
421 connect( tabs, SIGNAL(selected(const QString&)),
422 this, SLOT(viewSelected(const QString&)) );
423 connect( tabs, SIGNAL(clicked(const AppLnk*)),
424 this, SLOT(select(const AppLnk*)));
425 connect( tabs, SIGNAL(rightPressed(AppLnk*)),
426 this, SLOT(properties(AppLnk*)));
427
428#if defined(Q_WS_QWS) && !defined(QT_NO_COP)
429 QCopChannel* sysChannel = new QCopChannel( "QPE/System", this );
430 connect( sysChannel, SIGNAL(received(const QCString &, const QByteArray &)),
431 this, SLOT(systemMessage( const QCString &, const QByteArray &)) );
432#endif
433
434 storage = new StorageInfo( this );
435 connect( storage, SIGNAL( disksChanged() ), SLOT( storageChanged() ) );
436
437 updateTabs();
438
439 preloadApps();
440
441 in_lnk_props = FALSE;
442 got_lnk_change = FALSE;
443}
444
445Launcher::~Launcher()
446{
447}
448
449static bool isVisibleWindow(int wid)
450{
451 const QList<QWSWindow> &list = qwsServer->clientWindows();
452 QWSWindow* w;
453 for (QListIterator<QWSWindow> it(list); (w=it.current()); ++it) {
454 if ( w->winId() == wid )
455 return !w->isFullyObscured();
456 }
457 return FALSE;
458}
459
460void Launcher::showMaximized()
461{
462 if ( isVisibleWindow( winId() ) )
463 doMaximize();
464 else
465 QTimer::singleShot( 20, this, SLOT(doMaximize()) );
466}
467
468void Launcher::doMaximize()
469{
470 QMainWindow::showMaximized();
471}
472
473void Launcher::updateMimeTypes()
474{
475 MimeType::clear();
476 updateMimeTypes(rootFolder);
477}
478
479void Launcher::updateMimeTypes(AppLnkSet* folder)
480{
481 for ( QListIterator<AppLnk> it( folder->children() ); it.current(); ++it ) {
482 AppLnk *app = it.current();
483 if ( app->type() == "Folder" )
484 updateMimeTypes((AppLnkSet *)app);
485 else {
486 MimeType::registerApp(*app);
487 }
488 }
489}
490
491void Launcher::loadDocs()
492{
493 delete docsFolder;
494 docsFolder = new DocLnkSet;
495 Global::findDocuments(docsFolder);
496}
497
498void Launcher::updateTabs()
499{
500 MimeType::updateApplications(); // ### reads all applnks twice
501
502 delete rootFolder;
503 rootFolder = new AppLnkSet( MimeType::appsFolderName() );
504
505 loadDocs();
506
507 tabs->initializeCategories(rootFolder, docsFolder, storage->fileSystems());
508}
509
510void Launcher::updateDocs()
511{
512 loadDocs();
513 tabs->updateDocs(docsFolder,storage->fileSystems());
514}
515
516void Launcher::viewSelected(const QString& s)
517{
518 setCaption( s + tr(" - Launcher") );
519}
520
521void Launcher::nextView()
522{
523 tabs->nextTab();
524}
525
526
527void Launcher::select( const AppLnk *appLnk )
528{
529 if ( appLnk->type() == "Folder" ) {
530 // Not supported: flat is simpler for the user
531 } else {
532 if ( appLnk->exec().isNull() ) {
533 QMessageBox::information(this,tr("No application"),
534 tr("<p>No application is defined for this document."
535 "<p>Type is %1.").arg(appLnk->type()));
536 return;
537 }
538 tabs->setBusy(TRUE);
539 emit executing( appLnk );
540 appLnk->execute();
541 }
542}
543
544void Launcher::externalSelected(const AppLnk *appLnk)
545{
546 tabs->setBusy(TRUE);
547 emit executing( appLnk );
548}
549
550void Launcher::properties( AppLnk *appLnk )
551{
552 if ( appLnk->type() == "Folder" ) {
553 // Not supported: flat is simpler for the user
554 } else {
555 in_lnk_props = TRUE;
556 got_lnk_change = FALSE;
557 LnkProperties prop(appLnk);
558 connect(&prop, SIGNAL(select(const AppLnk *)), this, SLOT(externalSelected(const AppLnk *)));
559 prop.showMaximized();
560 prop.exec();
561 in_lnk_props = FALSE;
562 if ( got_lnk_change ) {
563 updateLink(lnk_change);
564 }
565 }
566}
567
568void Launcher::updateLink(const QString& link)
569{
570 if (link.isNull())
571 updateTabs();
572 else if (link.isEmpty())
573 updateDocs();
574 else
575 tabs->updateLink(link);
576}
577
578void Launcher::systemMessage( const QCString &msg, const QByteArray &data)
579{
580 QDataStream stream( data, IO_ReadOnly );
581 if ( msg == "linkChanged(QString)" ) {
582 QString link;
583 stream >> link;
584 if ( in_lnk_props ) {
585 got_lnk_change = TRUE;
586 lnk_change = link;
587 } else {
588 updateLink(link);
589 }
590 } else if ( msg == "busy()" ) {
591 emit busy();
592 } else if ( msg == "notBusy(QString)" ) {
593 QString app;
594 stream >> app;
595 tabs->setBusy(FALSE);
596 emit notBusy(app);
597 } else if ( msg == "mkdir(QString)" ) {
598 QString dir;
599 stream >> dir;
600 if ( !dir.isEmpty() )
601 mkdir( dir );
602 } else if ( msg == "rdiffGenSig(QString,QString)" ) {
603 QString baseFile, sigFile;
604 stream >> baseFile >> sigFile;
605 QRsync::generateSignature( baseFile, sigFile );
606 } else if ( msg == "rdiffGenDiff(QString,QString,QString)" ) {
607 QString baseFile, sigFile, deltaFile;
608 stream >> baseFile >> sigFile >> deltaFile;
609 QRsync::generateDiff( baseFile, sigFile, deltaFile );
610 } else if ( msg == "rdiffApplyPatch(QString,QString)" ) {
611 QString baseFile, deltaFile;
612 stream >> baseFile >> deltaFile;
613 if ( !QFile::exists( baseFile ) ) {
614 QFile f( baseFile );
615 f.open( IO_WriteOnly );
616 f.close();
617 }
618 QRsync::applyDiff( baseFile, deltaFile );
619 QCopEnvelope e( "QPE/Desktop", "patchApplied(QString)" );
620 e << baseFile;
621 } else if ( msg == "rdiffCleanup()" ) {
622 mkdir( "/tmp/rdiff" );
623 QDir dir;
624 dir.setPath( "/tmp/rdiff" );
625 QStringList entries = dir.entryList();
626 for ( QStringList::Iterator it = entries.begin(); it != entries.end(); ++it )
627 dir.remove( *it );
628 } else if ( msg == "sendHandshakeInfo()" ) {
629 QString home = getenv( "HOME" );
630 QCopEnvelope e( "QPE/Desktop", "handshakeInfo(QString,bool)" );
631 e << home;
632 int locked = (int) Desktop::screenLocked();
633 e << locked;
634 } else if ( msg == "sendCardInfo()" ) {
635 QCopEnvelope e( "QPE/Desktop", "cardInfo(QString)" );
636 const QList<FileSystem> &fs = storage->fileSystems();
637 QListIterator<FileSystem> it ( fs );
638 QString s;
639 QString homeDir = getenv("HOME");
640 QString hardDiskHome;
641 for ( ; it.current(); ++it ) {
642 if ( (*it)->isRemovable() )
643 s += (*it)->name() + "=" + (*it)->path() + "/Documents "
644 + QString::number( (*it)->availBlocks() * (*it)->blockSize() )
645 + " " + (*it)->options() + ";";
646 else if ( (*it)->disk() == "/dev/mtdblock1" ||
647 (*it)->disk() == "/dev/mtdblock/1" )
648 s += (*it)->name() + "=" + homeDir + "/Documents "
649 + QString::number( (*it)->availBlocks() * (*it)->blockSize() )
650 + " " + (*it)->options() + ";";
651 else if ( (*it)->name().contains( "Hard Disk") &&
652 homeDir.contains( (*it)->path() ) &&
653 (*it)->path().length() > hardDiskHome.length() )
654 hardDiskHome =
655 (*it)->name() + "=" + homeDir + "/Documents "
656 + QString::number( (*it)->availBlocks() * (*it)->blockSize() )
657 + " " + (*it)->options() + ";";
658 }
659 if ( !hardDiskHome.isEmpty() )
660 s += hardDiskHome;
661
662 e << s;
663 } else if ( msg == "sendSyncDate(QString)" ) {
664 QString app;
665 stream >> app;
666 Config cfg( "qpe" );
667 cfg.setGroup("SyncDate");
668 QCopEnvelope e( "QPE/Desktop", "syncDate(QString,QString)" );
669 e << app << cfg.readEntry( app );
670 //qDebug("QPE/System sendSyncDate for %s: response %s", app.latin1(),
671 //cfg.readEntry( app ).latin1() );
672 } else if ( msg == "setSyncDate(QString,QString)" ) {
673 QString app, date;
674 stream >> app >> date;
675 Config cfg( "qpe" );
676 cfg.setGroup("SyncDate");
677 cfg.writeEntry( app, date );
678 //qDebug("setSyncDate(QString,QString) %s %s", app.latin1(), date.latin1());
679 } else if ( msg == "startSync(QString)" ) {
680 QString what;
681 stream >> what;
682 delete syncDialog; syncDialog = 0;
683 syncDialog = new SyncDialog( this, "syncProgress", FALSE,
684 WStyle_Tool | WStyle_Customize |
685 Qt::WStyle_StaysOnTop );
686 syncDialog->showMaximized();
687 syncDialog->whatLabel->setText( "<b>" + what + "</b>" );
688 connect( syncDialog->buttonCancel, SIGNAL( clicked() ),
689 SLOT( cancelSync() ) );
690 }
691 else if ( msg == "stopSync()") {
692 delete syncDialog; syncDialog = 0;
693 } else if ( msg == "getAllDocLinks()" ) {
694 loadDocs();
695
696 QString contents;
697
698 for ( QListIterator<DocLnk> it( docsFolder->children() ); it.current(); ++it ) {
699 DocLnk *doc = it.current();
700 QString lfn = doc->linkFile();
701 QFileInfo fi( doc->file() );
702 if ( !fi.exists() )
703 continue;
704
705
706
707 QFile f( lfn );
708 if ( f.open( IO_ReadOnly ) ) {
709 QTextStream ts( &f );
710 ts.setEncoding( QTextStream::UnicodeUTF8 );
711 contents += ts.read();
712 f.close();
713 } else {
714 contents += "[Desktop Entry]\n";
715 contents += "Categories = " + Qtopia::Record::idsToString( doc->categories() ) + "\n";
716 contents += "File = "+doc->file()+"\n";
717 contents += "Name = "+doc->name()+"\n";
718 contents += "Type = "+doc->type()+"\n";
719 }
720 contents += QString("Size = %1\n").arg( fi.size() );
721 }
722
723 //qDebug( "sending length %d", contents.length() );
724 QCopEnvelope e( "QPE/Desktop", "docLinks(QString)" );
725 e << contents;
726
727 //qDebug( "================ \n\n%s\n\n===============",
728 //contents.latin1() );
729
730 delete docsFolder;
731 docsFolder = 0;
732 }
733}
734
735void Launcher::cancelSync()
736{
737 QCopEnvelope e( "QPE/Desktop", "cancelSync()" );
738}
739
740void Launcher::storageChanged()
741{
742 if ( in_lnk_props ) {
743 got_lnk_change = TRUE;
744 lnk_change = "";
745 } else {
746 updateDocs();
747 }
748}
749
750
751bool Launcher::mkdir(const QString &localPath)
752{
753 QDir fullDir(localPath);
754 if (fullDir.exists())
755 return true;
756
757 // at this point the directory doesn't exist
758 // go through the directory tree and start creating the direcotories
759 // that don't exist; if we can't create the directories, return false
760
761 QString dirSeps = "/";
762 int dirIndex = localPath.find(dirSeps);
763 QString checkedPath;
764
765 // didn't find any seps; weird, use the cur dir instead
766 if (dirIndex == -1) {
767 //qDebug("No seperators found in path %s", localPath.latin1());
768 checkedPath = QDir::currentDirPath();
769 }
770
771 while (checkedPath != localPath) {
772 // no more seperators found, use the local path
773 if (dirIndex == -1)
774 checkedPath = localPath;
775 else {
776 // the next directory to check
777 checkedPath = localPath.left(dirIndex) + "/";
778 // advance the iterator; the next dir seperator
779 dirIndex = localPath.find(dirSeps, dirIndex+1);
780 }
781
782 QDir checkDir(checkedPath);
783 if (!checkDir.exists()) {
784 //qDebug("mkdir making dir %s", checkedPath.latin1());
785
786 if (!checkDir.mkdir(checkedPath)) {
787 qDebug("Unable to make directory %s", checkedPath.latin1());
788 return FALSE;
789 }
790 }
791
792 }
793 return TRUE;
794}
795
796void Launcher::preloadApps()
797{
798 Config cfg("Launcher");
799 cfg.setGroup("Preload");
800 QStringList apps = cfg.readListEntry("Apps",',');
801 for (QStringList::ConstIterator it=apps.begin(); it!=apps.end(); ++it) {
802 QCopEnvelope e("QPE/Application/"+(*it).local8Bit(), "enablePreload()");
803 }
804}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef LAUNCHER_H
21#define LAUNCHER_H
22
23#include <qmainwindow.h>
24#include <qtabbar.h>
25#include <qstringlist.h>
26#include <qvbox.h>
27#include <qlist.h>
28#include "launcherview.h"
29
30class AppLnk;
31class AppLnkSet;
32class DocLnkSet;
33class QWidgetStack;
34class StorageInfo;
35class SyncDialog;
36
37class CategoryTabBar : public QTabBar
38{
39 Q_OBJECT
40public:
41 CategoryTabBar( QWidget *parent=0, const char *name=0 );
42 ~CategoryTabBar();
43
44protected slots:
45 virtual void layoutTabs();
46
47protected:
48 void paint ( QPainter *p, QTab *t, bool f ) const;
49 void paintLabel( QPainter* p, const QRect& br, QTab* t, bool has_focus ) const;
50};
51
52class CategoryTabWidget : public QVBox {
53 // can't use a QTabWidget, since it won't let us set the frame style.
54 Q_OBJECT
55public:
56 CategoryTabWidget( QWidget* parent );
57 void initializeCategories(AppLnkSet* rootFolder, AppLnkSet* docFolder,
58 const QList<FileSystem> &);
59 void updateDocs(AppLnkSet* docFolder, const QList<FileSystem> &fs);
60 void updateLink(const QString& linkfile);
61 void setBusy(bool on);
62
63signals:
64 void selected(const QString&);
65 void clicked(const AppLnk*);
66 void rightPressed(AppLnk*);
67
68public slots:
69 void nextTab();
70 void prevTab();
71
72protected:
73 void paletteChange( const QPalette &p );
74
75private:
76 CategoryTabBar* categoryBar;
77 QWidgetStack* stack;
78 LauncherView* docview;
79 QStringList ids;
80 int tabs;
81 LauncherView* newView( const QString&, const QPixmap& pm, const QString& label );
82 void addItem( const QString& );
83};
84
85class Launcher : public QMainWindow
86{
87 Q_OBJECT
88 friend class LauncherPrivate;
89public:
90 Launcher( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
91 ~Launcher();
92
93 static QString appsFolderName();
94
95 virtual void showMaximized();
96 static bool mkdir(const QString &path);
97
98public slots:
99 void viewSelected(const QString&);
100 void select( const AppLnk * );
101 void externalSelected( const AppLnk *);
102 void properties( AppLnk * );
103 void nextView();
104
105signals:
106 void executing( const AppLnk * );
107 void busy();
108 void notBusy(const QString&);
109
110private slots:
111 void doMaximize();
112 void systemMessage( const QCString &, const QByteArray &);
113 void storageChanged();
114 void cancelSync();
115
116private:
117 void updateApps();
118 void loadDocs();
119 void updateDocs();
120 void updateTabs();
121 void updateMimeTypes();
122 void updateMimeTypes(AppLnkSet*);
123 void preloadApps();
124 AppLnkSet *rootFolder;
125 DocLnkSet *docsFolder;
126 CategoryTabWidget *tabs;
127 StorageInfo *storage;
128 SyncDialog *syncDialog;
129
130 void updateLink(const QString& link);
131 bool in_lnk_props;
132 bool got_lnk_change;
133 QString lnk_change;
134};
135
136#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 @@
1 TEMPLATE= app
2
3 CONFIG = qt warn_on release
4
5 DESTDIR = $(QPEDIR)/bin
6
7 HEADERS = background.h \
8 desktop.h \
9 info.h \
10 appicons.h \
11 taskbar.h \
12 sidething.h \
13 mrulist.h \
14 stabmon.h \
15 inputmethods.h \
16 systray.h \
17 wait.h \
18 shutdownimpl.h \
19 launcher.h \
20 launcherview.h \
21 ../calibrate/calibrate.h \
22 startmenu.h \
23 transferserver.h \
24 qcopbridge.h \
25 packageslave.h \
26 irserver.h \
27 $(QPEDIR)/rsync/buf.h \
28 $(QPEDIR)/rsync/checksum.h \
29 $(QPEDIR)/rsync/command.h \
30 $(QPEDIR)/rsync/emit.h \
31 $(QPEDIR)/rsync/job.h \
32 $(QPEDIR)/rsync/netint.h \
33 $(QPEDIR)/rsync/protocol.h \
34 $(QPEDIR)/rsync/prototab.h \
35 $(QPEDIR)/rsync/rsync.h \
36 $(QPEDIR)/rsync/search.h \
37 $(QPEDIR)/rsync/stream.h \
38 $(QPEDIR)/rsync/sumset.h \
39 $(QPEDIR)/rsync/trace.h \
40 $(QPEDIR)/rsync/types.h \
41 $(QPEDIR)/rsync/util.h \
42 $(QPEDIR)/rsync/whole.h \
43 $(QPEDIR)/rsync/config_rsync.h \
44 $(QPEDIR)/rsync/qrsync.h
45 # quicklauncher.h \
46
47 SOURCES = background.cpp \
48 desktop.cpp \
49 info.cpp \
50 appicons.cpp \
51 taskbar.cpp \
52 sidething.cpp \
53 mrulist.cpp \
54 stabmon.cpp \
55 inputmethods.cpp \
56 systray.cpp \
57 wait.cpp \
58 shutdownimpl.cpp \
59 launcher.cpp \
60 launcherview.cpp \
61 $(QPEDIR)/calibrate/calibrate.cpp \
62 transferserver.cpp \
63 packageslave.cpp \
64 irserver.cpp \
65 qcopbridge.cpp \
66 startmenu.cpp \
67 main.cpp \
68 $(QPEDIR)/rsync/base64.c \
69 $(QPEDIR)/rsync/buf.c \
70 $(QPEDIR)/rsync/checksum.c \
71 $(QPEDIR)/rsync/command.c \
72 $(QPEDIR)/rsync/delta.c \
73 $(QPEDIR)/rsync/emit.c \
74 $(QPEDIR)/rsync/hex.c \
75 $(QPEDIR)/rsync/job.c \
76 $(QPEDIR)/rsync/mdfour.c \
77 $(QPEDIR)/rsync/mksum.c \
78 $(QPEDIR)/rsync/msg.c \
79 $(QPEDIR)/rsync/netint.c \
80 $(QPEDIR)/rsync/patch.c \
81 $(QPEDIR)/rsync/prototab.c \
82 $(QPEDIR)/rsync/readsums.c \
83 $(QPEDIR)/rsync/scoop.c \
84 $(QPEDIR)/rsync/search.c \
85 $(QPEDIR)/rsync/stats.c \
86 $(QPEDIR)/rsync/stream.c \
87 $(QPEDIR)/rsync/sumset.c \
88 $(QPEDIR)/rsync/trace.c \
89 $(QPEDIR)/rsync/tube.c \
90 $(QPEDIR)/rsync/util.c \
91 $(QPEDIR)/rsync/version.c \
92 $(QPEDIR)/rsync/whole.c \
93 $(QPEDIR)/rsync/qrsync.cpp
94
95 INTERFACES= shutdown.ui syncdialog.ui
96
97INCLUDEPATH += $(QPEDIR)/include
98 DEPENDPATH+= $(QPEDIR)/include .
99
100INCLUDEPATH += $(QPEDIR)/calibrate
101 DEPENDPATH+= $(QPEDIR)/calibrate
102
103INCLUDEPATH += $(QPEDIR)/rsync
104 DEPENDPATH+= $(QPEDIR)/rsync
105
106 TARGET = qpe
107
108 LIBS += -lqpe -lcrypt
109
110TRANSLATIONS = ../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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "launcherview.h"
22
23#include <qpe/qpeapplication.h>
24#include <qpe/applnk.h>
25#include <qpe/qpedebug.h>
26#include <qpe/categories.h>
27#include <qpe/categoryselect.h>
28#include <qpe/menubutton.h>
29#include <qpe/resource.h>
30#include <qpe/qpetoolbar.h>
31
32#include <qtimer.h>
33#include <qdict.h>
34#include <qfile.h>
35#include <qfileinfo.h>
36#include <qhbox.h>
37#include <qiconview.h>
38#include <qpainter.h>
39#include <qregexp.h>
40#include <qtoolbutton.h>
41
42class LauncherIconView : public QIconView {
43public:
44 LauncherIconView( QWidget* parent, const char* name=0 ) :
45 QIconView(parent,name),
46 tf(""),
47 cf(0),
48 bsy(0)
49 {
50 sortmeth = Name;
51 hidden.setAutoDelete(TRUE);
52 ike = FALSE;
53 }
54
55 ~LauncherIconView()
56 {
57#if 0 // debuggery
58 QListIterator<AppLnk> it(hidden);
59 AppLnk* l;
60 while ((l=it.current())) {
61 ++it;
62 //qDebug("%p: hidden (should remove)",l);
63 }
64#endif
65 }
66
67 QIconViewItem* busyItem() const { return bsy; }
68
69 void updateCategoriesAndMimeTypes();
70
71 void doAutoScroll()
72 {
73 // We don't want rubberbanding (yet)
74 }
75
76 void setBusy(bool on)
77 {
78 QIconViewItem *c = on ? currentItem() : 0;
79 if ( bsy != c ) {
80 QIconViewItem* o = bsy;
81 bsy = c;
82 if ( o ) o->repaint();
83 if ( c ) c->repaint();
84 }
85 }
86
87 bool inKeyEvent() const { return ike; }
88 void keyPressEvent(QKeyEvent* e)
89 {
90 ike = TRUE;
91 if ( e->key() == Key_F33 ) {
92 // "OK" button
93 returnPressed(currentItem());
94 }
95 QIconView::keyPressEvent(e);
96 ike = FALSE;
97 }
98
99 void addItem(AppLnk* app, bool resort=TRUE);
100 bool removeLink(const QString& linkfile);
101
102 QStringList mimeTypes() const;
103 QStringList categories() const;
104
105 void clear()
106 {
107 mimes.clear();
108 cats.clear();
109 QIconView::clear();
110 hidden.clear();
111 }
112
113 void addCatsAndMimes(AppLnk* app)
114 {
115 // QStringList c = app->categories();
116 // for (QStringList::ConstIterator cit=c.begin(); cit!=c.end(); ++cit) {
117 // cats.replace(*cit,(void*)1);
118 // }
119 QString maj=app->type();
120 int sl=maj.find('/');
121 if (sl>=0) {
122 QString k = maj.left(sl);
123 mimes.replace(k,(void*)1);
124 }
125 }
126
127 void drawBackground( QPainter *p, const QRect &r )
128 {
129 //int backgroundMode = QPixmap::defaultDepth() >= 12 ? 1 : 0;
130 int backgroundMode = 2;
131
132 if ( backgroundMode == 1 ) {
133
134 // Double buffer the background
135 static QPixmap *bg = NULL;
136 static QColor bgColor;
137
138 if ( (bg == NULL) || (bgColor != colorGroup().button()) ) {
139 // Create a new background double buffer
140 if (bg == NULL)
141 bg = new QPixmap( width(), height() );
142 bgColor = colorGroup().button();
143 QPainter painter( bg );
144
145 painter.fillRect( QRect( 0, 0, width(), height() ), QBrush( white ) );
146
147 // Overlay the Qtopia logo in the center
148 QImage logo = Resource::loadImage( "qpe-logo" );
149 if ( !logo.isNull() )
150 painter.drawImage( (width() - logo.width()) / 2,
151 (height() - logo.height()) / 2, logo );
152 }
153
154 // Draw the double buffer to the widget (it is tiled for when the icon view is large)
155 p->drawTiledPixmap( r, *bg, QPoint( (r.x() + contentsX()) % bg->width(),
156 (r.y() + contentsY()) % bg->height() ) );
157 } else if ( backgroundMode == 2 ) {
158 static QPixmap *bg = 0;
159 static QColor bgColor;
160 if ( !bg || (bgColor != colorGroup().background()) ) {
161 bgColor = colorGroup().background();
162 bg = new QPixmap( width(), 9 );
163 QPainter painter( bg );
164 for ( int i = 0; i < 3; i++ ) {
165 painter.setPen( white );
166 painter.drawLine( 0, i*3, width()-1, i*3 );
167 painter.drawLine( 0, i*3+1, width()-1, i*3+1 );
168 painter.setPen( colorGroup().background().light(105) );
169 painter.drawLine( 0, i*3+2, width()-1, i*3+2 );
170 }
171 }
172 p->drawTiledPixmap( r, *bg, QPoint( (r.x() + contentsX()) % bg->width(),
173 (r.y() + contentsY()) % bg->height() ) );
174 } else {
175 p->fillRect( r, QBrush( white ) );
176 }
177 }
178
179 void hideOrShowItems(bool resort);
180
181 void setTypeFilter(const QString& typefilter, bool resort)
182 {
183 tf = QRegExp(typefilter,FALSE,TRUE);
184 hideOrShowItems(resort);
185 }
186
187 void setCategoryFilter( int catfilter, bool resort )
188 {
189 Categories cat;
190 cat.load( categoryFileName() );
191 QString str;
192 if ( catfilter == -2 )
193 cf = 0;
194 else
195 cf = catfilter;
196 hideOrShowItems(resort);
197 }
198
199 enum SortMethod { Name, Date, Type };
200
201 void setSortMethod( SortMethod m )
202 {
203 if ( sortmeth != m ) {
204 sortmeth = m;
205 sort();
206 }
207 }
208
209 int compare(const AppLnk* a, const AppLnk* b)
210 {
211 switch (sortmeth) {
212 case Name:
213 return a->name().compare(b->name());
214 case Date: {
215 QFileInfo fa(a->linkFile());
216 if ( !fa.exists() ) fa.setFile(a->file());
217 QFileInfo fb(b->linkFile());
218 if ( !fb.exists() ) fb.setFile(b->file());
219 return fa.lastModified().secsTo(fb.lastModified());
220 }
221 case Type:
222 return a->type().compare(b->type());
223 }
224 return 0;
225 }
226
227protected:
228
229 void styleChange( QStyle &old )
230 {
231 QIconView::styleChange( old );
232 //### duplicated code from LauncherView constructor
233 int dw = QApplication::desktop()->width();
234 setGridX( (dw-13-style().scrollBarExtent().width())/3 ); // tweaked for 8pt+dw=176 and 10pt+dw=240
235 }
236
237private:
238 QList<AppLnk> hidden;
239 QDict<void> mimes;
240 QDict<void> cats;
241 SortMethod sortmeth;
242 QRegExp tf;
243 int cf;
244 QIconViewItem* bsy;
245 bool ike;
246
247};
248
249
250bool LauncherView::bsy=FALSE;
251
252void LauncherView::setBusy(bool on)
253{
254 icons->setBusy(on);
255}
256
257class LauncherItem : public QIconViewItem
258{
259public:
260 LauncherItem( QIconView *parent, AppLnk* applnk );
261 ~LauncherItem()
262 {
263 LauncherIconView* liv = (LauncherIconView*)iconView();
264 if ( liv->busyItem() == this )
265 liv->setBusy(FALSE);
266 delete app;
267 }
268
269 AppLnk* appLnk() const { return app; }
270 AppLnk* takeAppLnk() { AppLnk* r=app; app=0; return r; }
271
272 virtual int compare ( QIconViewItem * i ) const;
273
274 void paintItem( QPainter *p, const QColorGroup &cg )
275 {
276 LauncherIconView* liv = (LauncherIconView*)iconView();
277 QBrush oldBrush( liv->itemTextBackground() );
278 QColorGroup mycg( cg );
279 if ( liv->currentItem() == this ) {
280 liv->setItemTextBackground( cg.brush( QColorGroup::Highlight ) );
281 mycg.setColor( QColorGroup::Text, cg.color( QColorGroup::HighlightedText ) );
282 }
283 QIconViewItem::paintItem(p,mycg);
284 if ( liv->currentItem() == this )
285 liv->setItemTextBackground( oldBrush );
286 if ( liv->busyItem() == this ) {
287 static QPixmap* busypm=0;
288 if ( !busypm )
289 busypm = new QPixmap(Resource::loadPixmap("launching"));
290 p->drawPixmap(x()+(width()-busypm->width())/2, y(),*busypm);
291 }
292 }
293
294protected:
295 AppLnk* app;
296};
297
298
299LauncherItem::LauncherItem( QIconView *parent, AppLnk *applnk )
300 : QIconViewItem( parent, applnk->name(), applnk->bigPixmap() ),
301 app(applnk) // Takes ownership
302{
303}
304
305int LauncherItem::compare ( QIconViewItem * i ) const
306{
307 LauncherIconView* view = (LauncherIconView*)iconView();
308 return view->compare(app,((LauncherItem *)i)->appLnk());
309}
310
311QStringList LauncherIconView::mimeTypes() const
312{
313 QStringList r;
314 QDictIterator<void> it(mimes);
315 while (it.current()) {
316 r.append(it.currentKey());
317 ++it;
318 }
319 r.sort();
320 return r;
321}
322
323void LauncherIconView::addItem(AppLnk* app, bool resort)
324{
325 addCatsAndMimes(app);
326
327 if ( (tf.isEmpty() || tf.match(app->type()) >= 0)
328 && (cf == 0 || app->categories().contains(cf)
329 || cf == -1 && app->categories().count() == 0 ) )
330 (void) new LauncherItem( this, app );
331 else
332 hidden.append(app);
333 if ( resort )
334 sort();
335}
336
337void LauncherIconView::updateCategoriesAndMimeTypes()
338{
339 mimes.clear();
340 cats.clear();
341 LauncherItem* item = (LauncherItem*)firstItem();
342 while (item) {
343 addCatsAndMimes(item->appLnk());
344 item = (LauncherItem*)item->nextItem();
345 }
346 QListIterator<AppLnk> it(hidden);
347 AppLnk* l;
348 while ((l=it.current())) {
349 addCatsAndMimes(l);
350 ++it;
351 }
352}
353
354void LauncherIconView::hideOrShowItems(bool resort)
355{
356 hidden.setAutoDelete(FALSE);
357 QList<AppLnk> links=hidden;
358 hidden.clear();
359 hidden.setAutoDelete(TRUE);
360 LauncherItem* item = (LauncherItem*)firstItem();
361 while (item) {
362 links.append(item->takeAppLnk());
363 item = (LauncherItem*)item->nextItem();
364 }
365 clear();
366 QListIterator<AppLnk> it(links);
367 AppLnk* l;
368 while ((l=it.current())) {
369 addItem(l,FALSE);
370 ++it;
371 }
372 if ( resort )
373 sort();
374}
375
376bool LauncherIconView::removeLink(const QString& linkfile)
377{
378 LauncherItem* item = (LauncherItem*)firstItem();
379 while (item) {
380 if ( item->appLnk()->linkFile() == linkfile ) {
381 delete item;
382 return TRUE;
383 }
384 item = (LauncherItem*)item->nextItem();
385 }
386 QListIterator<AppLnk> it(hidden);
387 AppLnk* l;
388 while ((l=it.current())) {
389 ++it;
390 if ( l->linkFile() == linkfile ) {
391 hidden.removeRef(l);
392 return TRUE;
393 }
394 }
395 return FALSE;
396}
397
398LauncherView::LauncherView( QWidget* parent, const char* name, WFlags fl )
399 : QVBox( parent, name, fl )
400{
401 icons = new LauncherIconView( this );
402 setFocusProxy(icons);
403 QPEApplication::setStylusOperation( icons->viewport(), QPEApplication::RightOnHold );
404
405 int dw = QApplication::desktop()->width();
406 icons->setItemsMovable( FALSE );
407 icons->setAutoArrange( TRUE );
408 icons->setSorting( TRUE );
409 icons->setGridX( (dw-13-style().scrollBarExtent().width())/3 ); // tweaked for 8pt+dw=176 and 10pt+dw=240
410 icons->setGridY( fontMetrics().height()*2+24 );
411 icons->setFrameStyle( QFrame::NoFrame );
412 icons->setSpacing( 4 );
413 icons->setMargin( 0 );
414 icons->setSelectionMode( QIconView::Multi );
415 icons->setBackgroundMode( PaletteBase );
416
417 connect( icons, SIGNAL(mouseButtonClicked(int, QIconViewItem *, const QPoint&)),
418 SLOT(itemClicked(int, QIconViewItem *)) );
419 connect( icons, SIGNAL(selectionChanged()),
420 SLOT(selectionChanged()) );
421 connect( icons, SIGNAL(returnPressed(QIconViewItem *)),
422 SLOT(returnPressed(QIconViewItem *)) );
423 connect( icons, SIGNAL(mouseButtonPressed(int, QIconViewItem *, const QPoint&)),
424 SLOT(itemPressed(int, QIconViewItem *)) );
425
426 tools = 0;
427}
428
429LauncherView::~LauncherView()
430{
431}
432
433void LauncherView::setToolsEnabled(bool y)
434{
435 if ( !y != !tools ) {
436 if ( y ) {
437 tools = new QHBox(this);
438
439 // Type filter
440 typemb = new MenuButton(tools);
441 typemb->setLabel(tr("Type: %1"));
442
443 // Category filter
444 catmb = new CategorySelect(tools);
445
446 updateTools();
447 tools->show();
448 } else {
449 delete tools;
450 tools = 0;
451 }
452 }
453}
454
455void LauncherView::updateTools()
456{
457 disconnect( typemb, SIGNAL(selected(const QString&)),
458 this, SLOT(showType(const QString&)) );
459 disconnect( catmb, SIGNAL(signalSelected(int)),
460 this, SLOT(showCategory(int)) );
461
462 icons->updateCategoriesAndMimeTypes();
463
464 QString prev;
465
466 // Type filter
467 QStringList types;
468 types << tr("All");
469 types << "--";
470 types += icons->mimeTypes();
471 prev = typemb->currentText();
472 typemb->clear();
473 typemb->insertItems(types);
474 typemb->select(prev);
475
476 Categories cats( 0 );
477 cats.load( categoryFileName() );
478 QArray<int> vl( 0 );
479 catmb->setCategories( vl, "Document View", tr("Document View") );
480 catmb->setRemoveCategoryEdit( TRUE );
481 catmb->setAllCategories( TRUE );
482
483 connect(typemb, SIGNAL(selected(const QString&)), this, SLOT(showType(const QString&)));
484 connect(catmb, SIGNAL(signalSelected(int)), this, SLOT(showCategory(int)));
485}
486
487void LauncherView::sortBy(int s)
488{
489 icons->setSortMethod((LauncherIconView::SortMethod)s);
490}
491
492void LauncherView::showType(const QString& t)
493{
494 if ( t == tr("All") ) {
495 icons->setTypeFilter("",TRUE);
496 } else {
497 icons->setTypeFilter(t+"/*",TRUE);
498 }
499}
500
501void LauncherView::showCategory( int c )
502{
503 icons->setCategoryFilter( c, TRUE );
504}
505
506void LauncherView::resizeEvent(QResizeEvent *e)
507{
508 QVBox::resizeEvent( e );
509 if ( e->size().width() != e->oldSize().width() )
510 sort();
511}
512
513void LauncherView::populate( AppLnkSet *folder, const QString& typefilter )
514{
515 icons->clear();
516 internalPopulate( folder, typefilter );
517}
518
519void LauncherView::selectionChanged()
520{
521 QIconViewItem* item = icons->currentItem();
522 if ( item && item->isSelected() ) {
523 AppLnk *appLnk = ((LauncherItem *)item)->appLnk();
524 if ( icons->inKeyEvent() ) // not for mouse press
525 emit clicked( appLnk );
526 item->setSelected(FALSE);
527 }
528}
529
530void LauncherView::returnPressed( QIconViewItem *item )
531{
532 if ( item ) {
533 AppLnk *appLnk = ((LauncherItem *)item)->appLnk();
534 emit clicked( appLnk );
535 }
536}
537
538void LauncherView::itemClicked( int btn, QIconViewItem *item )
539{
540 if ( item ) {
541 AppLnk *appLnk = ((LauncherItem *)item)->appLnk();
542 if ( btn == LeftButton ) {
543 // Make sure it's the item we execute that gets highlighted
544 icons->setCurrentItem( item );
545 emit clicked( appLnk );
546 }
547 item->setSelected(FALSE);
548 }
549}
550
551void LauncherView::itemPressed( int btn, QIconViewItem *item )
552{
553 if ( item ) {
554 AppLnk *appLnk = ((LauncherItem *)item)->appLnk();
555 if ( btn == RightButton )
556 emit rightPressed( appLnk );
557/*
558 else if ( btn == LeftButton )
559 emit clicked( appLnk );
560*/
561 item->setSelected(FALSE);
562 }
563}
564
565void LauncherView::internalPopulate( AppLnkSet *folder, const QString& typefilter )
566{
567 QListIterator<AppLnk> it( folder->children() );
568 icons->setTypeFilter(typefilter,FALSE);
569
570 while ( it.current() ) {
571 icons->addItem(*it,FALSE);
572 ++it;
573 }
574
575 icons->sort();
576}
577
578bool LauncherView::removeLink(const QString& linkfile)
579{
580 return icons->removeLink(linkfile);
581}
582
583void LauncherView::sort()
584{
585 icons->sort();
586}
587
588void LauncherView::addItem(AppLnk* app, bool resort)
589{
590 icons->addItem(app,resort);
591}
592
593void LauncherView::setFileSystems(const QList<FileSystem> &)
594{
595 // ### does nothing now...
596}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef LAUNCHERVIEW_H
21#define LAUNCHERVIEW_H
22
23#include <qpe/storage.h>
24
25#include <qvbox.h>
26
27class AppLnk;
28class AppLnkSet;
29class CategorySelect;
30class LauncherIconView;
31class QIconView;
32class QIconViewItem;
33class MenuButton;
34
35class LauncherView : public QVBox
36{
37 Q_OBJECT
38
39public:
40 LauncherView( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
41 ~LauncherView();
42
43 bool removeLink(const QString& linkfile);
44 void addItem(AppLnk* app, bool resort=TRUE);
45 void sort();
46
47 void setFileSystems(const QList<FileSystem> &);
48 void setToolsEnabled(bool);
49 void updateTools();
50
51 void setBusy(bool);
52
53public slots:
54 void populate( AppLnkSet *folder, const QString& categoryfilter );
55
56signals:
57 void clicked( const AppLnk * );
58 void rightPressed( AppLnk * );
59
60protected slots:
61 void selectionChanged();
62 void returnPressed( QIconViewItem *item );
63 void itemClicked( int, QIconViewItem * );
64 void itemPressed( int, QIconViewItem * );
65 void sortBy(int);
66 void showType(const QString&);
67 void showCategory( int );
68 void resizeEvent(QResizeEvent *);
69
70protected:
71 void internalPopulate( AppLnkSet *, const QString& categoryfilter );
72
73private:
74 static bool bsy;
75 QWidget* tools;
76 LauncherIconView* icons;
77 MenuButton *typemb;
78 CategorySelect *catmb;
79};
80
81#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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "desktop.h"
22#include "taskbar.h"
23#include "stabmon.h"
24
25#include <qpe/qpeapplication.h>
26#include <qpe/network.h>
27#include <qpe/config.h>
28#ifdef QT_QWS_CUSTOM
29#include <qpe/custom.h>
30#endif
31
32#include <qfile.h>
33#include <qwindowsystem_qws.h>
34#include <qpe/qcopenvelope_qws.h>
35#include <qpe/alarmserver.h>
36
37#include <stdlib.h>
38#include <stdio.h>
39#include <signal.h>
40#include <unistd.h>
41
42#if defined(QT_QWS_CASSIOPEIA) || defined(QT_QWS_IPAQ) || defined(QT_QWS_EBX)
43#include "../calibrate/calibrate.h"
44#endif
45
46#ifdef QT_QWS_LOGIN
47#include "../login/qdmdialogimpl.h"
48#endif
49
50#ifdef QT_QWS_CASSIOPEIA
51static void ignoreMessage( QtMsgType, const char * )
52{
53}
54#include <sys/mount.h>
55#include <sys/types.h>
56#include <sys/stat.h>
57#include <sys/time.h>
58#include <fcntl.h>
59#include <qdatetime.h>
60
61void initCassiopeia()
62{
63 // MIPSEL-specific init - make sure /proc exists for shm
64/*
65 if ( mount("/dev/ram0", "/", "ext2", MS_REMOUNT | MS_MGC_VAL, 0 ) ) {
66 perror("Remounting - / read/write");
67 }
68*/
69 if ( mount("none", "/tmp", "ramfs", 0, 0 ) ) {
70 perror("mounting ramfs /tmp");
71 } else {
72 fprintf( stderr, "mounted /tmp\n" );
73 }
74 if ( mount("none", "/home", "ramfs", 0, 0 ) ) {
75 perror("mounting ramfs /home");
76 } else {
77 fprintf( stderr, "mounted /home\n" );
78 }
79 if ( mount("none","/proc","proc",0,0) ) {
80 perror("Mounting - /proc");
81 } else {
82 fprintf( stderr, "mounted /proc\n" );
83 }
84 if ( mount("none","/mnt","shm",0,0) ) {
85 perror("Mounting - shm");
86 }
87 setenv( "QTDIR", "/", 1 );
88 setenv( "QPEDIR", "/", 1 );
89 setenv( "HOME", "/home", 1 );
90 mkdir( "/home/Documents", 0755 );
91
92 // set a reasonable starting date
93 QDateTime dt( QDate( 2001, 3, 15 ) );
94 QDateTime now = QDateTime::currentDateTime();
95 int change = now.secsTo( dt );
96
97 time_t t = ::time(0);
98 t += change;
99 stime(&t);
100
101 qInstallMsgHandler(ignoreMessage);
102}
103#endif
104
105#ifdef QPE_OWNAPM
106#include <sys/ioctl.h>
107#include <sys/types.h>
108#include <fcntl.h>
109#include <unistd.h>
110#include <errno.h>
111#include <linux/ioctl.h>
112#include <qpe/global.h>
113
114static void disableAPM()
115{
116
117 int fd, cur_val, ret;
118 char *device = "/dev/apm_bios";
119
120 fd = open (device, O_WRONLY);
121
122 if (fd == -1) {
123 perror(device);
124 return;
125 }
126
127 cur_val = ioctl(fd, APM_IOCGEVTSRC, 0);
128 if (cur_val == -1) {
129 perror("ioctl");
130 exit(errno);
131 }
132
133 ret = ioctl(fd, APM_IOCSEVTSRC, cur_val & ~APM_EVT_POWER_BUTTON);
134 if (ret == -1) {
135 perror("ioctl");
136 return;
137 }
138 close(fd);
139}
140
141static void initAPM()
142{
143 // So that we have to do it ourself, but better.
144 disableAPM();
145}
146#endif
147
148#ifdef QT_DEMO_SINGLE_FLOPPY
149#include <sys/mount.h>
150
151void initFloppy()
152{
153 mount("none","/proc","proc",0,0);
154 setenv( "QTDIR", "/", 0 );
155 setenv( "HOME", "/root", 0 );
156 setenv( "QWS_SIZE", "240x320", 0 );
157}
158#endif
159
160
161void initEnvironment()
162{
163 Config config("locale");
164 config.setGroup( "Location" );
165 QString tz = config.readEntry( "Timezone", getenv("TZ") );
166
167 // if not timezone set, pick New York
168 if (tz.isNull())
169 tz = "America/New_York";
170
171 setenv( "TZ", tz, 1 );
172 config.writeEntry( "Timezone", tz);
173
174 config.setGroup( "Language" );
175 QString lang = config.readEntry( "Language", getenv("LANG") );
176 if ( !lang.isNull() )
177 setenv( "LANG", lang, 1 );
178}
179
180static void initBacklight()
181{
182 QCopEnvelope e("QPE/System", "setBacklight(int)" );
183 e << -3; // Forced on
184}
185
186
187
188int initApplication( int argc, char ** argv )
189{
190#ifdef QT_QWS_CASSIOPEIA
191 initCassiopeia();
192#endif
193
194#ifdef QPE_OWNAPM
195 initAPM();
196#endif
197
198#ifdef QT_DEMO_SINGLE_FLOPPY
199 initFloppy();
200#endif
201
202 initEnvironment();
203
204#if !defined(QT_QWS_CASSIOPEIA) && !defined(QT_QWS_IPAQ) && !defined(QT_QWS_EBX)
205 setenv( "QWS_SIZE", "240x320", 0 );
206#endif
207
208 //Don't flicker at startup:
209 QWSServer::setDesktopBackground( QImage() );
210 DesktopApplication a( argc, argv, QApplication::GuiServer );
211
212 initBacklight();
213
214 AlarmServer::initialize();
215
216#if defined(QT_QWS_LOGIN)
217 for( int i=0; i<a.argc(); i++ )
218 if( strcmp( a.argv()[i], "-login" ) == 0 ) {
219 QDMDialogImpl::login( );
220 return 0;
221 }
222#endif
223
224 Desktop *d = new Desktop();
225
226 QObject::connect( &a, SIGNAL(datebook()), d, SLOT(raiseDatebook()) );
227 QObject::connect( &a, SIGNAL(contacts()), d, SLOT(raiseContacts()) );
228 QObject::connect( &a, SIGNAL(launch()), d, SLOT(raiseLauncher()) );
229 QObject::connect( &a, SIGNAL(email()), d, SLOT(raiseEmail()) );
230 QObject::connect( &a, SIGNAL(power()), d, SLOT(togglePower()) );
231 QObject::connect( &a, SIGNAL(backlight()), d, SLOT(toggleLight()) );
232 QObject::connect( &a, SIGNAL(symbol()), d, SLOT(toggleSymbolInput()) );
233 QObject::connect( &a, SIGNAL(numLockStateToggle()), d, SLOT(toggleNumLockState()) );
234 QObject::connect( &a, SIGNAL(capsLockStateToggle()), d, SLOT(toggleCapsLockState()) );
235 QObject::connect( &a, SIGNAL(prepareForRestart()), d, SLOT(terminateServers()) );
236
237 (void)new SysFileMonitor(d);
238 Network::createServer(d);
239
240#if defined(QT_QWS_CASSIOPEIA) || defined(QT_QWS_IPAQ) || defined(QT_QWS_EBX)
241 if ( !QFile::exists( "/etc/pointercal" ) ) {
242 // Make sure calibration widget starts on top.
243 Calibrate *cal = new Calibrate;
244 cal->exec();
245 delete cal;
246 }
247#endif
248
249 d->show();
250
251 int rv = a.exec();
252
253 delete d;
254
255 return rv;
256}
257
258int main( int argc, char ** argv )
259{
260#ifndef SINGLE_APP
261 signal( SIGCHLD, SIG_IGN );
262#endif
263
264 int retVal = initApplication( argc, argv );
265
266#ifndef SINGLE_APP
267 // Kill them. Kill them all.
268 setpgid( getpid(), getppid() );
269 killpg( getpid(), SIGTERM );
270 sleep( 1 );
271 killpg( getpid(), SIGKILL );
272#endif
273
274 return retVal;
275}
276
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "mrulist.h"
22
23#include <qpe/global.h>
24#include <qpe/applnk.h>
25#include <qpe/resource.h>
26
27#include <qframe.h>
28#include <qpushbutton.h>
29#include <qtoolbutton.h>
30#include <qpopupmenu.h>
31#include <qpainter.h>
32#include <qwindowsystem_qws.h>
33
34
35 QList<MRUList>*MRUList::MRUListWidgets = NULL;
36 QList<AppLnk>*MRUList::task = NULL;
37
38
39MRUList::MRUList( QWidget *parent )
40 : QFrame( parent ), selected(-1), oldsel(-1)
41{
42 setBackgroundMode( PaletteButton );
43 if (!MRUListWidgets)
44 MRUListWidgets = new QList<MRUList>;
45 if (!task)
46 task = new QList<AppLnk>;
47 MRUListWidgets->append( this );
48}
49
50
51MRUList::~MRUList()
52{
53 if (MRUListWidgets)
54 MRUListWidgets->remove( this );
55 if (task)
56 task->setAutoDelete( TRUE );
57}
58
59
60QSize MRUList::sizeHint() const
61{
62 return QSize( frameWidth(), 16 );
63}
64
65
66void MRUList::addTask( const AppLnk *appLnk )
67{
68 if ( !appLnk )
69 return;
70 unsigned int i = 0;
71
72 if ( !task )
73 return;
74
75 for ( ; i < task->count(); i++ ) {
76 AppLnk *t = task->at(i);
77 if ( t->exec() == appLnk->exec() ) {
78 if (i != 0) {
79 task->remove();
80 task->prepend( t );
81 }
82 for (unsigned i = 0; i < MRUListWidgets->count(); i++ )
83 MRUListWidgets->at(i)->update();
84 return;
85 }
86 }
87
88 AppLnk *t = new AppLnk( *appLnk );
89 // DocLnks have an overloaded virtual function exec()
90 t->setExec( appLnk->exec() );
91 task->prepend( t );
92
93 if ( task->count() > 6 ) {
94 t = task->last();
95 task->remove();
96 Global::terminate(t);
97 delete t;
98 }
99
100 for (unsigned i = 0; i < MRUListWidgets->count(); i++ )
101 MRUListWidgets->at(i)->update();
102}
103
104bool MRUList::quitOldApps()
105{
106 QStringList appsstarted;
107 QStringList appsrunning;
108 for ( int i=task->count()-1; i>=0; --i ) {
109 AppLnk *t = task->at(i);
110 appsstarted.append(t->exec());
111 }
112
113 const QList<QWSWindow> &list = qwsServer->clientWindows();
114 QWSWindow* w;
115 for (QListIterator<QWSWindow> it(list); (w=it.current()); ++it) {
116 QString app = w->client()->identity();
117 if ( appsstarted.contains(app) && !appsrunning.contains(app) )
118 appsrunning.append(app);
119 }
120
121 if ( appsrunning.count() > 1 ) {
122 QStringList::ConstIterator it = appsrunning.begin();
123 ++it; // top stays running!
124 for (; it != appsrunning.end(); it++) {
125 for ( int i=task->count()-1; i>=0; --i ) {
126 AppLnk *t = task->at(i);
127 if ( t->exec() == *it )
128 Global::terminate(t);
129 }
130 }
131 return TRUE;
132 } else {
133 return FALSE;
134 }
135}
136
137
138void MRUList::mousePressEvent(QMouseEvent *e)
139{
140 selected = 0;
141 int x=0;
142 QListIterator<AppLnk> it( *task );
143 for ( ; it.current(); ++it,++selected,x+=15 ) {
144 if ( x + 15 <= width() ) {
145 if ( e->x() >= x && e->x() < x+15 ) {
146 if ( selected < (int)task->count() ) {
147 repaint(FALSE);
148 return;
149 }
150 }
151 } else {
152 break;
153 }
154 }
155 selected = -1;
156 repaint( FALSE );
157}
158
159
160void MRUList::mouseReleaseEvent(QMouseEvent *)
161{
162 if ( selected >= 0 ) {
163 if ( parentWidget() )
164 if ( parentWidget()->isA( "QPopupMenu" ) )
165 parentWidget()->hide();
166 Global::execute( task->at(selected)->exec() );
167 selected = -1;
168 oldsel = -1;
169 update();
170 }
171}
172
173
174void MRUList::paintEvent( QPaintEvent * )
175{
176 QPainter p( this );
177 AppLnk *t;
178 int x = 0;
179 int y = (height() - 14) / 2;
180 int i = 0;
181
182 p.fillRect( 0, 0, width(), height(), colorGroup().background() );
183
184 if ( task ) {
185 QListIterator<AppLnk> it( *task );
186 for ( ; it.current(); i++, ++it ) {
187 if ( x + 15 <= width() ) {
188 t = it.current();
189 if ( (int)i == selected )
190 p.fillRect( x, y, 15, t->pixmap().height()+1, colorGroup().highlight() );
191 else if ( (int)i == oldsel )
192 p.eraseRect( x, y, 15, t->pixmap().height()+1 );
193 p.drawPixmap( x, y, t->pixmap() );
194 x += 15;
195 }
196 }
197 }
198}
199
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#ifndef __MRU_LIST_H__
22#define __MRU_LIST_H__
23
24
25#include <qpe/applnk.h>
26
27#include <qframe.h>
28#include <qlist.h>
29#include <qpixmap.h>
30
31
32class MRUList : public QFrame
33{
34public:
35 MRUList( QWidget *parent );
36 ~MRUList();
37 virtual QSize sizeHint() const;
38 static void addTask( const AppLnk *appLnk );
39 bool quitOldApps();
40
41protected:
42 void mousePressEvent(QMouseEvent *e);
43 void mouseReleaseEvent(QMouseEvent *e);
44 void paintEvent( QPaintEvent *event );
45
46private:
47 static QList<MRUList> *MRUListWidgets;
48 static QList<AppLnk> *task;
49 int selected;
50 int oldsel;
51};
52
53
54#endif // __MRU_LIST_H__
55
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#ifndef OBEXINTERFACE_H
22#define OBEXINTERFACE_H
23
24#include <qpe/qcom.h>
25
26#ifndef QT_NO_COMPONENT
27// ### regenerate!!!!!!
28// {6CA35D0B-C637-4865-A667-7D4CD8A70407}
29# ifndef IID_ObexInterface
30# define IID_ObexInterface QUuid( 0x6ca35d0b, 0xc637, 0x4865, 0xa6, 0x67, 0x7d, 0x4c, 0xd8, 0xa7, 0x04, 0x07)
31# endif
32#endif
33
34class QObject;
35
36struct ObexInterface : public QUnknownInterface
37{
38};
39
40#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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "packageslave.h"
22
23#include <qpe/process.h>
24#include <qpe/qcopenvelope_qws.h>
25
26#include <qdatastream.h>
27#include <qcopchannel_qws.h>
28
29#include <unistd.h>
30
31PackageSlave::PackageSlave( QObject *parent, char* name )
32 : QObject( parent, name ), packageChannel( 0 )
33{
34 // setup qcop channel
35 packageChannel = new QCopChannel( "QPE/Package", this );
36 connect( packageChannel, SIGNAL( received(const QCString &, const QByteArray &) ),
37 this, SLOT( qcopMessage( const QCString &, const QByteArray &) ) );
38}
39
40void PackageSlave::qcopMessage( const QCString &msg, const QByteArray &data )
41{
42 QDataStream stream( data, IO_ReadOnly );
43
44 if ( msg == "installPackage(QString)" ) {
45 QString file;
46 stream >> file;
47 installPackage( file );
48 }
49 else if ( msg == "removePackage(QString)" ) {
50 QString file;
51 stream >> file;
52 removePackage( file );
53 }
54}
55
56void PackageSlave::installPackage( const QString &package )
57{
58 Process proc( QStringList() << "ipkg" << "install" << package );
59
60 sendReply( "installStarted(QString)", package );
61
62 QString output;
63 if ( proc.exec( "", output ) ) {
64 sendReply( "installDone(QString)", package );
65 }
66 else {
67 sendReply( "installFailed(QString)", package );
68 }
69 QCopEnvelope e("QPE/System", "linkChanged(QString)");
70 QString lf = QString::null;
71 e << lf;
72 unlink( package );
73}
74
75void PackageSlave::removePackage( const QString &package )
76{
77 Process proc( QStringList() << "ipkg" << "remove" << package );
78
79 sendReply( "removeStarted(QString)", package );
80
81 QString output;
82 if ( proc.exec( "", output ) ) {
83 sendReply( "removeDone(QString)", package );
84 }
85 else {
86 sendReply( "removeFailed(QString)", package );
87 }
88 QCopEnvelope e("QPE/System", "linkChanged(QString)");
89 QString lf = QString::null;
90 e << lf;
91}
92
93void PackageSlave::sendReply( const QCString& msg, const QString& arg )
94{
95 QCopEnvelope e( "QPE/Desktop", msg );
96 e << arg;
97}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#ifndef __packageslave_h__
22#define __packageslave_h__
23
24#include <qobject.h>
25
26class QCopChannel;
27
28class PackageSlave : public QObject
29{
30 Q_OBJECT
31
32public:
33 PackageSlave( QObject *parent, char* name = 0 );
34
35protected:
36 void installPackage( const QString &package );
37 void removePackage( const QString &package );
38
39protected slots:
40 void qcopMessage( const QCString &msg, const QByteArray &data );
41
42private:
43 void sendReply( const QCString& msg, const QString& arg );
44
45private:
46 QCopChannel *packageChannel;
47};
48
49
50#endif // __QUICK_LAUNCHER_H__
51
52
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "qcopbridge.h"
22#include "transferserver.h"
23
24#include <qpe/qcopenvelope_qws.h>
25#include <qpe/qpeapplication.h>
26
27#include <qdir.h>
28#include <qfile.h>
29#include <qtextstream.h>
30#include <qdatastream.h>
31#include <qstringlist.h>
32#include <qfileinfo.h>
33#include <qregexp.h>
34#include <qcopchannel_qws.h>
35
36#define _XOPEN_SOURCE
37#include <pwd.h>
38#include <sys/types.h>
39#include <unistd.h>
40
41#if defined(_OS_LINUX_)
42#include <shadow.h>
43#endif
44
45//#define INSECURE
46
47const int block_size = 51200;
48
49QCopBridge::QCopBridge( Q_UINT16 port, QObject *parent = 0,
50 const char* name = 0)
51 : QServerSocket( port, 1, parent, name ),
52 desktopChannel( 0 ),
53 cardChannel( 0 )
54{
55 if ( !ok() )
56 qWarning( "Failed to bind to port %d", port );
57 else {
58 desktopChannel = new QCopChannel( "QPE/Desktop", this );
59 connect( desktopChannel, SIGNAL(received(const QCString &, const QByteArray &)),
60 this, SLOT(desktopMessage( const QCString &, const QByteArray &)) );
61 cardChannel = new QCopChannel( "QPE/Card", this );
62 connect( cardChannel, SIGNAL(received(const QCString &, const QByteArray &)),
63 this, SLOT(desktopMessage( const QCString &, const QByteArray &)) );
64 }
65 sendSync = FALSE;
66}
67
68QCopBridge::~QCopBridge()
69{
70 delete desktopChannel;
71}
72
73void QCopBridge::newConnection( int socket )
74{
75 QCopBridgePI *pi = new QCopBridgePI( socket, this );
76 openConnections.append( pi );
77 connect ( pi, SIGNAL( connectionClosed( QCopBridgePI *) ), this, SLOT( connectionClosed( QCopBridgePI *) ) );
78 QCopEnvelope( "QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::DisableSuspend;
79
80 if ( sendSync ) {
81 pi ->startSync();
82 sendSync = FALSE;
83 }
84}
85
86void QCopBridge::connectionClosed( QCopBridgePI *pi )
87{
88 openConnections.remove( pi );
89 if ( openConnections.count() == 0 ) {
90 QCopEnvelope( "QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::Enable;
91 }
92}
93
94void QCopBridge::closeOpenConnections()
95{
96 QCopBridgePI *pi;
97 for ( pi = openConnections.first(); pi != 0; pi = openConnections.next() )
98 pi->close();
99}
100
101
102void QCopBridge::desktopMessage( const QCString &command, const QByteArray &args )
103{
104 command.stripWhiteSpace();
105
106 int paren = command.find( "(" );
107 if ( paren <= 0 ) {
108 qDebug("DesktopMessage: bad qcop syntax");
109 return;
110 }
111
112 QString params = command.mid( paren + 1 );
113 if ( params[params.length()-1] != ')' ) {
114 qDebug("DesktopMessage: bad qcop syntax");
115 return;
116 }
117
118 params.truncate( params.length()-1 );
119
120 QStringList paramList = QStringList::split( ",", params );
121 QString data;
122 if ( paramList.count() ) {
123 QDataStream stream( args, IO_ReadOnly );
124 for ( QStringList::Iterator it = paramList.begin(); it != paramList.end(); ++it ) {
125 QString str;
126 if ( *it == "QString" ) {
127 stream >> str;
128 } else if ( *it == "QCString" ) {
129 QCString cstr;
130 stream >> cstr;
131 str = QString::fromLocal8Bit( cstr );
132 } else if ( *it == "int" ) {
133 int i;
134 stream >> i;
135 str = QString::number( i );
136 } else if ( *it == "bool" ) {
137 int i;
138 stream >> i;
139 str = QString::number( i );
140 } else {
141 qDebug(" cannot route the argument type %s throught the qcop bridge", (*it).latin1() );
142 return;
143 }
144 str.replace( QRegExp("&"), "&amp;" );
145 str.replace( QRegExp(" "), "&0x20;" );
146 str.replace( QRegExp("\n"), "&0x0d;" );
147 str.replace( QRegExp("\r"), "&0x0a;" );
148 data += " " + str;
149 }
150 }
151 QString sendCommand = QString(command.data()) + data;
152 // send the command to all open connections
153 if ( command == "startSync()" ) {
154 // we need to buffer it a bit
155 sendSync = TRUE;
156 startTimer( 20000 );
157 }
158
159 QCopBridgePI *pi;
160 for ( pi = openConnections.first(); pi != 0; pi = openConnections.next() ) {
161 pi->sendDesktopMessage( sendCommand );
162 }
163}
164
165void QCopBridge::timerEvent( QTimerEvent * )
166{
167 sendSync = FALSE;
168 killTimers();
169}
170
171
172QCopBridgePI::QCopBridgePI( int socket, QObject *parent = 0, const char* name = 0 )
173 : QSocket( parent, name )
174{
175 setSocket( socket );
176
177 peerport = peerPort();
178 peeraddress = peerAddress();
179
180#ifndef INSECURE
181 if ( !accessAuthorized(peeraddress) ) {
182 state = Forbidden;
183 startTimer( 0 );
184 } else
185 #endif
186 {
187 state = Connected;
188 sendSync = FALSE;
189 connect( this, SIGNAL( readyRead() ), SLOT( read() ) );
190 connect( this, SIGNAL( connectionClosed() ), SLOT( connectionClosed() ) );
191
192 send( "220 Qtopia QCop bridge ready!" );
193 state = Wait_USER;
194
195 // idle timer to close connections when not used anymore
196 startTimer( 60000 );
197 connected = TRUE;
198 }
199}
200
201
202QCopBridgePI::~QCopBridgePI()
203{
204
205}
206
207void QCopBridgePI::connectionClosed()
208{
209 emit connectionClosed( this );
210 // qDebug( "Debug: Connection closed" );
211 delete this;
212}
213
214void QCopBridgePI::sendDesktopMessage( const QString &msg )
215{
216 QString str = "CALL QPE/Desktop " + msg;
217 send ( str );
218}
219
220
221void QCopBridgePI::send( const QString& msg )
222{
223 QTextStream os( this );
224 os << msg << endl;
225 //qDebug( "sending qcop message: %s", msg.latin1() );
226}
227
228void QCopBridgePI::read()
229{
230 while ( canReadLine() )
231 process( readLine().stripWhiteSpace() );
232}
233
234bool QCopBridgePI::checkUser( const QString& user )
235{
236 if ( user.isEmpty() ) return FALSE;
237
238 struct passwd *pw;
239 pw = getpwuid( geteuid() );
240 QString euser = QString::fromLocal8Bit( pw->pw_name );
241 return user == euser;
242}
243
244bool QCopBridgePI::checkPassword( const QString& password )
245{
246 // ### HACK for testing on local host
247 return true;
248
249 /*
250 struct passwd *pw = 0;
251 struct spwd *spw = 0;
252
253 pw = getpwuid( geteuid() );
254 spw = getspnam( pw->pw_name );
255
256 QString cpwd = QString::fromLocal8Bit( pw->pw_passwd );
257 if ( cpwd == "x" && spw )
258 cpwd = QString::fromLocal8Bit( spw->sp_pwdp );
259
260 QString cpassword = QString::fromLocal8Bit( crypt( password.local8Bit(), cpwd.local8Bit() ) );
261 return cpwd == cpassword;
262*/
263}
264
265void QCopBridgePI::process( const QString& message )
266{
267 //qDebug( "Command: %s", message.latin1() );
268
269 // split message using "," as separator
270 QStringList msg = QStringList::split( " ", message );
271 if ( msg.isEmpty() ) return;
272
273 // command token
274 QString cmd = msg[0].upper();
275
276 // argument token
277 QString arg;
278 if ( msg.count() >= 2 )
279 arg = msg[1];
280
281 // we always respond to QUIT, regardless of state
282 if ( cmd == "QUIT" ) {
283 send( "211 Have a nice day!" );
284 delete this;
285 return;
286 }
287
288 // connected to client
289 if ( Connected == state )
290 return;
291
292 // waiting for user name
293 if ( Wait_USER == state ) {
294
295 if ( cmd != "USER" || msg.count() < 2 || !checkUser( arg ) ) {
296 send( "530 Please login with USER and PASS" );
297 return;
298 }
299 send( "331 User name ok, need password" );
300 state = Wait_PASS;
301 return;
302 }
303
304 // waiting for password
305 if ( Wait_PASS == state ) {
306
307 if ( cmd != "PASS" || !checkPassword( arg ) ) {
308 //if ( cmd != "PASS" || msg.count() < 2 || !checkPassword( arg ) ) {
309 send( "530 Please login with USER and PASS" );
310 return;
311 }
312 send( "230 User logged in, proceed" );
313 state = Ready;
314 if ( sendSync ) {
315 sendDesktopMessage( "startSync()" );
316 sendSync = FALSE;
317 }
318 return;
319 }
320
321 // noop (NOOP)
322 else if ( cmd == "NOOP" ) {
323 connected = TRUE;
324 send( "200 Command okay" );
325 }
326
327 // call (CALL)
328 else if ( cmd == "CALL" ) {
329
330 // example: call QPE/System execute(QString) addressbook
331
332 if ( msg.count() < 3 ) {
333 send( "500 Syntax error, command unrecognized" );
334 }
335 else {
336
337 QString channel = msg[1];
338 QString command = msg[2];
339
340 command.stripWhiteSpace();
341
342 int paren = command.find( "(" );
343 if ( paren <= 0 ) {
344 send( "500 Syntax error, command unrecognized" );
345 return;
346 }
347
348 QString params = command.mid( paren + 1 );
349 if ( params[params.length()-1] != ')' ) {
350 send( "500 Syntax error, command unrecognized" );
351 return;
352 }
353
354 params.truncate( params.length()-1 );
355 QByteArray buffer;
356 QDataStream ds( buffer, IO_WriteOnly );
357
358 int msgId = 3;
359
360 QStringList paramList = QStringList::split( ",", params );
361 if ( paramList.count() > msg.count() - 3 ) {
362 send( "500 Syntax error, command unrecognized" );
363 return;
364 }
365
366 for ( QStringList::Iterator it = paramList.begin(); it != paramList.end(); ++it ) {
367
368 QString arg = msg[msgId];
369 arg.replace( QRegExp("&0x20;"), " " );
370 arg.replace( QRegExp("&amp;"), "&" );
371 arg.replace( QRegExp("&0x0d;"), "\n" );
372 arg.replace( QRegExp("&0x0a;"), "\r" );
373 if ( *it == "QString" )
374 ds << arg;
375 else if ( *it == "QCString" )
376 ds << arg.local8Bit();
377 else if ( *it == "int" )
378 ds << arg.toInt();
379 else if ( *it == "bool" )
380 ds << arg.toInt();
381 else {
382 send( "500 Syntax error, command unrecognized" );
383 return;
384 }
385 msgId++;
386 }
387
388 if ( !QCopChannel::isRegistered( channel.latin1() ) ) {
389 // send message back about it
390 QString answer = "599 ChannelNotRegistered " + channel;
391 send( answer );
392 return;
393 }
394
395 if ( paramList.count() )
396 QCopChannel::send( channel.latin1(), command.latin1(), buffer );
397 else
398 QCopChannel::send( channel.latin1(), command.latin1() );
399
400 send( "200 Command okay" );
401 }
402 }
403 // not implemented
404 else
405 send( "502 Command not implemented" );
406}
407
408
409
410void QCopBridgePI::timerEvent( QTimerEvent * )
411{
412 if ( connected )
413 connected = FALSE;
414 else
415 connectionClosed();
416}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef __qcopbridge_h__
21#define __qcopbridge_h__
22
23#include <qserversocket.h>
24#include <qsocket.h>
25#include <qdir.h>
26#include <qfile.h>
27#include <qbuffer.h>
28
29class QFileInfo;
30class QCopBridgePI;
31class QCopChannel;
32
33class QCopBridge : public QServerSocket
34{
35 Q_OBJECT
36
37public:
38 QCopBridge( Q_UINT16 port, QObject *parent = 0, const char* name = 0 );
39 virtual ~QCopBridge();
40
41 void newConnection( int socket );
42 void closeOpenConnections();
43
44public slots:
45 void connectionClosed( QCopBridgePI *pi );
46 void desktopMessage( const QCString &call, const QByteArray & );
47
48protected:
49 void timerEvent( QTimerEvent * );
50
51private:
52 QCopChannel *desktopChannel;
53 QCopChannel *cardChannel;
54 QList<QCopBridgePI> openConnections;
55 bool sendSync;
56};
57
58
59class QCopBridgePI : public QSocket
60{
61 Q_OBJECT
62
63 enum State { Connected, Wait_USER, Wait_PASS, Ready, Forbidden };
64
65public:
66 QCopBridgePI( int socket, QObject *parent = 0, const char* name = 0 );
67 virtual ~QCopBridgePI();
68
69 void sendDesktopMessage( const QString &msg );
70 void startSync() { sendSync = TRUE; }
71
72signals:
73 void connectionClosed( QCopBridgePI *);
74
75protected slots:
76 void read();
77 void send( const QString& msg );
78 void process( const QString& command );
79 void connectionClosed();
80
81protected:
82 bool checkUser( const QString& user );
83 bool checkPassword( const QString& pw );
84
85 void timerEvent( QTimerEvent *e );
86
87private:
88 State state;
89 Q_UINT16 peerport;
90 QHostAddress peeraddress;
91 bool connected;
92 bool sendSync;
93};
94
95#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 @@
1Files: bin/qpe apps/Settings/Calibrate.desktop
2Priority: required
3Section: qpe/system
4Maintainer: Warwick Allison <warwick@trolltech.com>
5Architecture: arm
6Version: $QPE_VERSION-3
7Depends: qt-embedded (>=$QTE_VERSION)
8Description: Launcher for QPE
9 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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include <qapplication.h>
22#include <qlayout.h>
23#include <qpushbutton.h>
24#include <applnk.h>
25#include <resource.h>
26#include "quicklauncher.h"
27
28
29void QuickLauncher::addLauncherButton( AppLnk *appLnk )
30{
31 QPushButton *pb = new QPushButton( this );
32 // It's no a QObject anymore
33 //pb->connect( pb, SIGNAL( clicked( ) ), appLnk, SLOT( execute() ) );
34 pb->setPixmap( appLnk->pixmap() );
35 pb->setFocusPolicy( QWidget::NoFocus );
36 pb->setFlat( TRUE );
37 pb->setFixedSize( 18, 18 );
38}
39
40
41QuickLauncher::QuickLauncher( QWidget *parent ) : QHBox( parent )
42{
43// Example usage to add icons to the quick launcher area
44// addLauncherButton( "filebrowser_icon", "filebrowser" );
45// addLauncherButton( "textedit_icon", "textedit" );
46// addLauncherButton( "help_icon", "helpbrowser" );
47}
48
49
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#ifndef __QUICK_LAUNCHER_H__
22#define __QUICK_LAUNCHER_H__
23
24
25#include <qhbox.h>
26
27class AppLnk;
28
29
30class QuickLauncher : public QHBox {
31 Q_OBJECT
32public:
33 QuickLauncher( QWidget *parent );
34 void addLauncherButton( AppLnk * );
35};
36
37
38#endif // __QUICK_LAUNCHER_H__
39
40
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 @@
1<!DOCTYPE UI><UI>
2<class>Shutdown</class>
3<widget>
4 <class>QWidget</class>
5 <property stdset="1">
6 <name>name</name>
7 <cstring>Form1</cstring>
8 </property>
9 <property stdset="1">
10 <name>geometry</name>
11 <rect>
12 <x>0</x>
13 <y>0</y>
14 <width>437</width>
15 <height>465</height>
16 </rect>
17 </property>
18 <property stdset="1">
19 <name>caption</name>
20 <string>Shut down...</string>
21 </property>
22 <property>
23 <name>layoutMargin</name>
24 </property>
25 <property>
26 <name>layoutSpacing</name>
27 </property>
28 <vbox>
29 <property stdset="1">
30 <name>margin</name>
31 <number>6</number>
32 </property>
33 <property stdset="1">
34 <name>spacing</name>
35 <number>3</number>
36 </property>
37 <widget>
38 <class>QButtonGroup</class>
39 <property stdset="1">
40 <name>name</name>
41 <cstring>ButtonGroup1</cstring>
42 </property>
43 <property stdset="1">
44 <name>title</name>
45 <string>Terminate</string>
46 </property>
47 <property>
48 <name>layoutMargin</name>
49 </property>
50 <property>
51 <name>layoutSpacing</name>
52 </property>
53 <grid>
54 <property stdset="1">
55 <name>margin</name>
56 <number>7</number>
57 </property>
58 <property stdset="1">
59 <name>spacing</name>
60 <number>3</number>
61 </property>
62 <widget row="1" column="1" >
63 <class>QPushButton</class>
64 <property stdset="1">
65 <name>name</name>
66 <cstring>quit</cstring>
67 </property>
68 <property stdset="1">
69 <name>sizePolicy</name>
70 <sizepolicy>
71 <hsizetype>3</hsizetype>
72 <vsizetype>0</vsizetype>
73 </sizepolicy>
74 </property>
75 <property stdset="1">
76 <name>palette</name>
77 <palette>
78 <active>
79 <color>
80 <red>0</red>
81 <green>0</green>
82 <blue>0</blue>
83 </color>
84 <color>
85 <red>236</red>
86 <green>236</green>
87 <blue>179</blue>
88 </color>
89 <color>
90 <red>255</red>
91 <green>255</green>
92 <blue>255</blue>
93 </color>
94 <color>
95 <red>245</red>
96 <green>245</green>
97 <blue>217</blue>
98 </color>
99 <color>
100 <red>118</red>
101 <green>118</green>
102 <blue>89</blue>
103 </color>
104 <color>
105 <red>157</red>
106 <green>157</green>
107 <blue>119</blue>
108 </color>
109 <color>
110 <red>0</red>
111 <green>0</green>
112 <blue>0</blue>
113 </color>
114 <color>
115 <red>255</red>
116 <green>255</green>
117 <blue>255</blue>
118 </color>
119 <color>
120 <red>0</red>
121 <green>0</green>
122 <blue>0</blue>
123 </color>
124 <color>
125 <red>255</red>
126 <green>255</green>
127 <blue>255</blue>
128 </color>
129 <color>
130 <red>222</red>
131 <green>222</green>
132 <blue>222</blue>
133 </color>
134 <color>
135 <red>0</red>
136 <green>0</green>
137 <blue>0</blue>
138 </color>
139 <color>
140 <red>0</red>
141 <green>0</green>
142 <blue>128</blue>
143 </color>
144 <color>
145 <red>255</red>
146 <green>255</green>
147 <blue>255</blue>
148 </color>
149 </active>
150 <disabled>
151 <color>
152 <red>128</red>
153 <green>128</green>
154 <blue>128</blue>
155 </color>
156 <color>
157 <red>236</red>
158 <green>236</green>
159 <blue>179</blue>
160 </color>
161 <color>
162 <red>255</red>
163 <green>255</green>
164 <blue>255</blue>
165 </color>
166 <color>
167 <red>255</red>
168 <green>255</green>
169 <blue>209</blue>
170 </color>
171 <color>
172 <red>118</red>
173 <green>118</green>
174 <blue>89</blue>
175 </color>
176 <color>
177 <red>157</red>
178 <green>157</green>
179 <blue>119</blue>
180 </color>
181 <color>
182 <red>128</red>
183 <green>128</green>
184 <blue>128</blue>
185 </color>
186 <color>
187 <red>255</red>
188 <green>255</green>
189 <blue>255</blue>
190 </color>
191 <color>
192 <red>128</red>
193 <green>128</green>
194 <blue>128</blue>
195 </color>
196 <color>
197 <red>255</red>
198 <green>255</green>
199 <blue>255</blue>
200 </color>
201 <color>
202 <red>222</red>
203 <green>222</green>
204 <blue>222</blue>
205 </color>
206 <color>
207 <red>0</red>
208 <green>0</green>
209 <blue>0</blue>
210 </color>
211 <color>
212 <red>0</red>
213 <green>0</green>
214 <blue>128</blue>
215 </color>
216 <color>
217 <red>255</red>
218 <green>255</green>
219 <blue>255</blue>
220 </color>
221 </disabled>
222 <inactive>
223 <color>
224 <red>0</red>
225 <green>0</green>
226 <blue>0</blue>
227 </color>
228 <color>
229 <red>236</red>
230 <green>236</green>
231 <blue>179</blue>
232 </color>
233 <color>
234 <red>255</red>
235 <green>255</green>
236 <blue>255</blue>
237 </color>
238 <color>
239 <red>255</red>
240 <green>255</green>
241 <blue>209</blue>
242 </color>
243 <color>
244 <red>118</red>
245 <green>118</green>
246 <blue>89</blue>
247 </color>
248 <color>
249 <red>157</red>
250 <green>157</green>
251 <blue>119</blue>
252 </color>
253 <color>
254 <red>0</red>
255 <green>0</green>
256 <blue>0</blue>
257 </color>
258 <color>
259 <red>255</red>
260 <green>255</green>
261 <blue>255</blue>
262 </color>
263 <color>
264 <red>0</red>
265 <green>0</green>
266 <blue>0</blue>
267 </color>
268 <color>
269 <red>255</red>
270 <green>255</green>
271 <blue>255</blue>
272 </color>
273 <color>
274 <red>222</red>
275 <green>222</green>
276 <blue>222</blue>
277 </color>
278 <color>
279 <red>0</red>
280 <green>0</green>
281 <blue>0</blue>
282 </color>
283 <color>
284 <red>0</red>
285 <green>0</green>
286 <blue>128</blue>
287 </color>
288 <color>
289 <red>255</red>
290 <green>255</green>
291 <blue>255</blue>
292 </color>
293 </inactive>
294 </palette>
295 </property>
296 <property stdset="1">
297 <name>text</name>
298 <string>Terminate Server</string>
299 </property>
300 <property stdset="1">
301 <name>buttonGroupId</name>
302 <number>4</number>
303 </property>
304 </widget>
305 <widget row="1" column="0" >
306 <class>QPushButton</class>
307 <property stdset="1">
308 <name>name</name>
309 <cstring>reboot</cstring>
310 </property>
311 <property stdset="1">
312 <name>sizePolicy</name>
313 <sizepolicy>
314 <hsizetype>3</hsizetype>
315 <vsizetype>0</vsizetype>
316 </sizepolicy>
317 </property>
318 <property stdset="1">
319 <name>palette</name>
320 <palette>
321 <active>
322 <color>
323 <red>0</red>
324 <green>0</green>
325 <blue>0</blue>
326 </color>
327 <color>
328 <red>236</red>
329 <green>183</green>
330 <blue>181</blue>
331 </color>
332 <color>
333 <red>255</red>
334 <green>255</green>
335 <blue>255</blue>
336 </color>
337 <color>
338 <red>245</red>
339 <green>219</green>
340 <blue>218</blue>
341 </color>
342 <color>
343 <red>118</red>
344 <green>92</green>
345 <blue>91</blue>
346 </color>
347 <color>
348 <red>157</red>
349 <green>122</green>
350 <blue>121</blue>
351 </color>
352 <color>
353 <red>0</red>
354 <green>0</green>
355 <blue>0</blue>
356 </color>
357 <color>
358 <red>255</red>
359 <green>255</green>
360 <blue>255</blue>
361 </color>
362 <color>
363 <red>0</red>
364 <green>0</green>
365 <blue>0</blue>
366 </color>
367 <color>
368 <red>255</red>
369 <green>255</green>
370 <blue>255</blue>
371 </color>
372 <color>
373 <red>222</red>
374 <green>222</green>
375 <blue>222</blue>
376 </color>
377 <color>
378 <red>0</red>
379 <green>0</green>
380 <blue>0</blue>
381 </color>
382 <color>
383 <red>0</red>
384 <green>0</green>
385 <blue>128</blue>
386 </color>
387 <color>
388 <red>255</red>
389 <green>255</green>
390 <blue>255</blue>
391 </color>
392 </active>
393 <disabled>
394 <color>
395 <red>128</red>
396 <green>128</green>
397 <blue>128</blue>
398 </color>
399 <color>
400 <red>236</red>
401 <green>183</green>
402 <blue>181</blue>
403 </color>
404 <color>
405 <red>255</red>
406 <green>255</green>
407 <blue>255</blue>
408 </color>
409 <color>
410 <red>255</red>
411 <green>213</green>
412 <blue>212</blue>
413 </color>
414 <color>
415 <red>118</red>
416 <green>92</green>
417 <blue>91</blue>
418 </color>
419 <color>
420 <red>157</red>
421 <green>122</green>
422 <blue>121</blue>
423 </color>
424 <color>
425 <red>128</red>
426 <green>128</green>
427 <blue>128</blue>
428 </color>
429 <color>
430 <red>255</red>
431 <green>255</green>
432 <blue>255</blue>
433 </color>
434 <color>
435 <red>128</red>
436 <green>128</green>
437 <blue>128</blue>
438 </color>
439 <color>
440 <red>255</red>
441 <green>255</green>
442 <blue>255</blue>
443 </color>
444 <color>
445 <red>222</red>
446 <green>222</green>
447 <blue>222</blue>
448 </color>
449 <color>
450 <red>0</red>
451 <green>0</green>
452 <blue>0</blue>
453 </color>
454 <color>
455 <red>0</red>
456 <green>0</green>
457 <blue>128</blue>
458 </color>
459 <color>
460 <red>255</red>
461 <green>255</green>
462 <blue>255</blue>
463 </color>
464 </disabled>
465 <inactive>
466 <color>
467 <red>0</red>
468 <green>0</green>
469 <blue>0</blue>
470 </color>
471 <color>
472 <red>236</red>
473 <green>183</green>
474 <blue>181</blue>
475 </color>
476 <color>
477 <red>255</red>
478 <green>255</green>
479 <blue>255</blue>
480 </color>
481 <color>
482 <red>255</red>
483 <green>213</green>
484 <blue>212</blue>
485 </color>
486 <color>
487 <red>118</red>
488 <green>92</green>
489 <blue>91</blue>
490 </color>
491 <color>
492 <red>157</red>
493 <green>122</green>
494 <blue>121</blue>
495 </color>
496 <color>
497 <red>0</red>
498 <green>0</green>
499 <blue>0</blue>
500 </color>
501 <color>
502 <red>255</red>
503 <green>255</green>
504 <blue>255</blue>
505 </color>
506 <color>
507 <red>0</red>
508 <green>0</green>
509 <blue>0</blue>
510 </color>
511 <color>
512 <red>255</red>
513 <green>255</green>
514 <blue>255</blue>
515 </color>
516 <color>
517 <red>222</red>
518 <green>222</green>
519 <blue>222</blue>
520 </color>
521 <color>
522 <red>0</red>
523 <green>0</green>
524 <blue>0</blue>
525 </color>
526 <color>
527 <red>0</red>
528 <green>0</green>
529 <blue>128</blue>
530 </color>
531 <color>
532 <red>255</red>
533 <green>255</green>
534 <blue>255</blue>
535 </color>
536 </inactive>
537 </palette>
538 </property>
539 <property stdset="1">
540 <name>text</name>
541 <string>Reboot</string>
542 </property>
543 <property stdset="1">
544 <name>buttonGroupId</name>
545 <number>2</number>
546 </property>
547 </widget>
548 <widget row="0" column="1" >
549 <class>QPushButton</class>
550 <property stdset="1">
551 <name>name</name>
552 <cstring>restart</cstring>
553 </property>
554 <property stdset="1">
555 <name>palette</name>
556 <palette>
557 <active>
558 <color>
559 <red>0</red>
560 <green>0</green>
561 <blue>0</blue>
562 </color>
563 <color>
564 <red>236</red>
565 <green>236</green>
566 <blue>179</blue>
567 </color>
568 <color>
569 <red>255</red>
570 <green>255</green>
571 <blue>255</blue>
572 </color>
573 <color>
574 <red>245</red>
575 <green>245</green>
576 <blue>217</blue>
577 </color>
578 <color>
579 <red>118</red>
580 <green>118</green>
581 <blue>89</blue>
582 </color>
583 <color>
584 <red>157</red>
585 <green>157</green>
586 <blue>119</blue>
587 </color>
588 <color>
589 <red>0</red>
590 <green>0</green>
591 <blue>0</blue>
592 </color>
593 <color>
594 <red>255</red>
595 <green>255</green>
596 <blue>255</blue>
597 </color>
598 <color>
599 <red>0</red>
600 <green>0</green>
601 <blue>0</blue>
602 </color>
603 <color>
604 <red>255</red>
605 <green>255</green>
606 <blue>255</blue>
607 </color>
608 <color>
609 <red>222</red>
610 <green>222</green>
611 <blue>222</blue>
612 </color>
613 <color>
614 <red>0</red>
615 <green>0</green>
616 <blue>0</blue>
617 </color>
618 <color>
619 <red>0</red>
620 <green>0</green>
621 <blue>128</blue>
622 </color>
623 <color>
624 <red>255</red>
625 <green>255</green>
626 <blue>255</blue>
627 </color>
628 </active>
629 <disabled>
630 <color>
631 <red>128</red>
632 <green>128</green>
633 <blue>128</blue>
634 </color>
635 <color>
636 <red>236</red>
637 <green>236</green>
638 <blue>179</blue>
639 </color>
640 <color>
641 <red>255</red>
642 <green>255</green>
643 <blue>255</blue>
644 </color>
645 <color>
646 <red>255</red>
647 <green>255</green>
648 <blue>209</blue>
649 </color>
650 <color>
651 <red>118</red>
652 <green>118</green>
653 <blue>89</blue>
654 </color>
655 <color>
656 <red>157</red>
657 <green>157</green>
658 <blue>119</blue>
659 </color>
660 <color>
661 <red>128</red>
662 <green>128</green>
663 <blue>128</blue>
664 </color>
665 <color>
666 <red>255</red>
667 <green>255</green>
668 <blue>255</blue>
669 </color>
670 <color>
671 <red>128</red>
672 <green>128</green>
673 <blue>128</blue>
674 </color>
675 <color>
676 <red>255</red>
677 <green>255</green>
678 <blue>255</blue>
679 </color>
680 <color>
681 <red>222</red>
682 <green>222</green>
683 <blue>222</blue>
684 </color>
685 <color>
686 <red>0</red>
687 <green>0</green>
688 <blue>0</blue>
689 </color>
690 <color>
691 <red>0</red>
692 <green>0</green>
693 <blue>128</blue>
694 </color>
695 <color>
696 <red>255</red>
697 <green>255</green>
698 <blue>255</blue>
699 </color>
700 </disabled>
701 <inactive>
702 <color>
703 <red>0</red>
704 <green>0</green>
705 <blue>0</blue>
706 </color>
707 <color>
708 <red>236</red>
709 <green>236</green>
710 <blue>179</blue>
711 </color>
712 <color>
713 <red>255</red>
714 <green>255</green>
715 <blue>255</blue>
716 </color>
717 <color>
718 <red>255</red>
719 <green>255</green>
720 <blue>209</blue>
721 </color>
722 <color>
723 <red>118</red>
724 <green>118</green>
725 <blue>89</blue>
726 </color>
727 <color>
728 <red>157</red>
729 <green>157</green>
730 <blue>119</blue>
731 </color>
732 <color>
733 <red>0</red>
734 <green>0</green>
735 <blue>0</blue>
736 </color>
737 <color>
738 <red>255</red>
739 <green>255</green>
740 <blue>255</blue>
741 </color>
742 <color>
743 <red>0</red>
744 <green>0</green>
745 <blue>0</blue>
746 </color>
747 <color>
748 <red>255</red>
749 <green>255</green>
750 <blue>255</blue>
751 </color>
752 <color>
753 <red>222</red>
754 <green>222</green>
755 <blue>222</blue>
756 </color>
757 <color>
758 <red>0</red>
759 <green>0</green>
760 <blue>0</blue>
761 </color>
762 <color>
763 <red>0</red>
764 <green>0</green>
765 <blue>128</blue>
766 </color>
767 <color>
768 <red>255</red>
769 <green>255</green>
770 <blue>255</blue>
771 </color>
772 </inactive>
773 </palette>
774 </property>
775 <property stdset="1">
776 <name>text</name>
777 <string>Restart Server</string>
778 </property>
779 <property stdset="1">
780 <name>buttonGroupId</name>
781 <number>3</number>
782 </property>
783 </widget>
784 <widget row="0" column="0" >
785 <class>QPushButton</class>
786 <property stdset="1">
787 <name>name</name>
788 <cstring>shutdown</cstring>
789 </property>
790 <property stdset="1">
791 <name>palette</name>
792 <palette>
793 <active>
794 <color>
795 <red>0</red>
796 <green>0</green>
797 <blue>0</blue>
798 </color>
799 <color>
800 <red>236</red>
801 <green>183</green>
802 <blue>181</blue>
803 </color>
804 <color>
805 <red>255</red>
806 <green>255</green>
807 <blue>255</blue>
808 </color>
809 <color>
810 <red>245</red>
811 <green>219</green>
812 <blue>218</blue>
813 </color>
814 <color>
815 <red>118</red>
816 <green>92</green>
817 <blue>91</blue>
818 </color>
819 <color>
820 <red>157</red>
821 <green>122</green>
822 <blue>121</blue>
823 </color>
824 <color>
825 <red>0</red>
826 <green>0</green>
827 <blue>0</blue>
828 </color>
829 <color>
830 <red>255</red>
831 <green>255</green>
832 <blue>255</blue>
833 </color>
834 <color>
835 <red>0</red>
836 <green>0</green>
837 <blue>0</blue>
838 </color>
839 <color>
840 <red>255</red>
841 <green>255</green>
842 <blue>255</blue>
843 </color>
844 <color>
845 <red>222</red>
846 <green>222</green>
847 <blue>222</blue>
848 </color>
849 <color>
850 <red>0</red>
851 <green>0</green>
852 <blue>0</blue>
853 </color>
854 <color>
855 <red>0</red>
856 <green>0</green>
857 <blue>128</blue>
858 </color>
859 <color>
860 <red>255</red>
861 <green>255</green>
862 <blue>255</blue>
863 </color>
864 </active>
865 <disabled>
866 <color>
867 <red>128</red>
868 <green>128</green>
869 <blue>128</blue>
870 </color>
871 <color>
872 <red>236</red>
873 <green>183</green>
874 <blue>181</blue>
875 </color>
876 <color>
877 <red>255</red>
878 <green>255</green>
879 <blue>255</blue>
880 </color>
881 <color>
882 <red>255</red>
883 <green>213</green>
884 <blue>212</blue>
885 </color>
886 <color>
887 <red>118</red>
888 <green>92</green>
889 <blue>91</blue>
890 </color>
891 <color>
892 <red>157</red>
893 <green>122</green>
894 <blue>121</blue>
895 </color>
896 <color>
897 <red>128</red>
898 <green>128</green>
899 <blue>128</blue>
900 </color>
901 <color>
902 <red>255</red>
903 <green>255</green>
904 <blue>255</blue>
905 </color>
906 <color>
907 <red>128</red>
908 <green>128</green>
909 <blue>128</blue>
910 </color>
911 <color>
912 <red>255</red>
913 <green>255</green>
914 <blue>255</blue>
915 </color>
916 <color>
917 <red>222</red>
918 <green>222</green>
919 <blue>222</blue>
920 </color>
921 <color>
922 <red>0</red>
923 <green>0</green>
924 <blue>0</blue>
925 </color>
926 <color>
927 <red>0</red>
928 <green>0</green>
929 <blue>128</blue>
930 </color>
931 <color>
932 <red>255</red>
933 <green>255</green>
934 <blue>255</blue>
935 </color>
936 </disabled>
937 <inactive>
938 <color>
939 <red>0</red>
940 <green>0</green>
941 <blue>0</blue>
942 </color>
943 <color>
944 <red>236</red>
945 <green>183</green>
946 <blue>181</blue>
947 </color>
948 <color>
949 <red>255</red>
950 <green>255</green>
951 <blue>255</blue>
952 </color>
953 <color>
954 <red>255</red>
955 <green>213</green>
956 <blue>212</blue>
957 </color>
958 <color>
959 <red>118</red>
960 <green>92</green>
961 <blue>91</blue>
962 </color>
963 <color>
964 <red>157</red>
965 <green>122</green>
966 <blue>121</blue>
967 </color>
968 <color>
969 <red>0</red>
970 <green>0</green>
971 <blue>0</blue>
972 </color>
973 <color>
974 <red>255</red>
975 <green>255</green>
976 <blue>255</blue>
977 </color>
978 <color>
979 <red>0</red>
980 <green>0</green>
981 <blue>0</blue>
982 </color>
983 <color>
984 <red>255</red>
985 <green>255</green>
986 <blue>255</blue>
987 </color>
988 <color>
989 <red>222</red>
990 <green>222</green>
991 <blue>222</blue>
992 </color>
993 <color>
994 <red>0</red>
995 <green>0</green>
996 <blue>0</blue>
997 </color>
998 <color>
999 <red>0</red>
1000 <green>0</green>
1001 <blue>128</blue>
1002 </color>
1003 <color>
1004 <red>255</red>
1005 <green>255</green>
1006 <blue>255</blue>
1007 </color>
1008 </inactive>
1009 </palette>
1010 </property>
1011 <property stdset="1">
1012 <name>text</name>
1013 <string>Shutdown</string>
1014 </property>
1015 <property stdset="1">
1016 <name>buttonGroupId</name>
1017 <number>1</number>
1018 </property>
1019 </widget>
1020 </grid>
1021 </widget>
1022 <widget>
1023 <class>QLabel</class>
1024 <property stdset="1">
1025 <name>name</name>
1026 <cstring>info</cstring>
1027 </property>
1028 <property stdset="1">
1029 <name>text</name>
1030 <string>&lt;p&gt;
1031These termination options are provided primarily for use while developing and testing the Qtopia system. In a normal environment, these concepts are unnecessary.</string>
1032 </property>
1033 </widget>
1034 <widget>
1035 <class>QProgressBar</class>
1036 <property stdset="1">
1037 <name>name</name>
1038 <cstring>progressBar</cstring>
1039 </property>
1040 <property stdset="1">
1041 <name>frameShape</name>
1042 <enum>Panel</enum>
1043 </property>
1044 <property stdset="1">
1045 <name>frameShadow</name>
1046 <enum>Sunken</enum>
1047 </property>
1048 <property stdset="1">
1049 <name>totalSteps</name>
1050 <number>20</number>
1051 </property>
1052 <property stdset="1">
1053 <name>indicatorFollowsStyle</name>
1054 <bool>false</bool>
1055 </property>
1056 </widget>
1057 <spacer>
1058 <property>
1059 <name>name</name>
1060 <cstring>Spacer2</cstring>
1061 </property>
1062 <property stdset="1">
1063 <name>orientation</name>
1064 <enum>Vertical</enum>
1065 </property>
1066 <property stdset="1">
1067 <name>sizeType</name>
1068 <enum>Expanding</enum>
1069 </property>
1070 <property>
1071 <name>sizeHint</name>
1072 <size>
1073 <width>20</width>
1074 <height>20</height>
1075 </size>
1076 </property>
1077 </spacer>
1078 <widget>
1079 <class>QPushButton</class>
1080 <property stdset="1">
1081 <name>name</name>
1082 <cstring>cancel</cstring>
1083 </property>
1084 <property stdset="1">
1085 <name>sizePolicy</name>
1086 <sizepolicy>
1087 <hsizetype>1</hsizetype>
1088 <vsizetype>7</vsizetype>
1089 </sizepolicy>
1090 </property>
1091 <property stdset="1">
1092 <name>palette</name>
1093 <palette>
1094 <active>
1095 <color>
1096 <red>0</red>
1097 <green>0</green>
1098 <blue>0</blue>
1099 </color>
1100 <color>
1101 <red>181</red>
1102 <green>222</green>
1103 <blue>178</blue>
1104 </color>
1105 <color>
1106 <red>255</red>
1107 <green>255</green>
1108 <blue>255</blue>
1109 </color>
1110 <color>
1111 <red>218</red>
1112 <green>238</green>
1113 <blue>216</blue>
1114 </color>
1115 <color>
1116 <red>90</red>
1117 <green>111</green>
1118 <blue>89</blue>
1119 </color>
1120 <color>
1121 <red>120</red>
1122 <green>148</green>
1123 <blue>118</blue>
1124 </color>
1125 <color>
1126 <red>0</red>
1127 <green>0</green>
1128 <blue>0</blue>
1129 </color>
1130 <color>
1131 <red>255</red>
1132 <green>255</green>
1133 <blue>255</blue>
1134 </color>
1135 <color>
1136 <red>0</red>
1137 <green>0</green>
1138 <blue>0</blue>
1139 </color>
1140 <color>
1141 <red>255</red>
1142 <green>255</green>
1143 <blue>255</blue>
1144 </color>
1145 <color>
1146 <red>174</red>
1147 <green>222</green>
1148 <blue>158</blue>
1149 </color>
1150 <color>
1151 <red>0</red>
1152 <green>0</green>
1153 <blue>0</blue>
1154 </color>
1155 <color>
1156 <red>0</red>
1157 <green>0</green>
1158 <blue>128</blue>
1159 </color>
1160 <color>
1161 <red>255</red>
1162 <green>255</green>
1163 <blue>255</blue>
1164 </color>
1165 </active>
1166 <disabled>
1167 <color>
1168 <red>128</red>
1169 <green>128</green>
1170 <blue>128</blue>
1171 </color>
1172 <color>
1173 <red>181</red>
1174 <green>222</green>
1175 <blue>178</blue>
1176 </color>
1177 <color>
1178 <red>255</red>
1179 <green>255</green>
1180 <blue>255</blue>
1181 </color>
1182 <color>
1183 <red>207</red>
1184 <green>255</green>
1185 <blue>204</blue>
1186 </color>
1187 <color>
1188 <red>90</red>
1189 <green>111</green>
1190 <blue>89</blue>
1191 </color>
1192 <color>
1193 <red>120</red>
1194 <green>148</green>
1195 <blue>118</blue>
1196 </color>
1197 <color>
1198 <red>128</red>
1199 <green>128</green>
1200 <blue>128</blue>
1201 </color>
1202 <color>
1203 <red>255</red>
1204 <green>255</green>
1205 <blue>255</blue>
1206 </color>
1207 <color>
1208 <red>128</red>
1209 <green>128</green>
1210 <blue>128</blue>
1211 </color>
1212 <color>
1213 <red>255</red>
1214 <green>255</green>
1215 <blue>255</blue>
1216 </color>
1217 <color>
1218 <red>174</red>
1219 <green>222</green>
1220 <blue>158</blue>
1221 </color>
1222 <color>
1223 <red>0</red>
1224 <green>0</green>
1225 <blue>0</blue>
1226 </color>
1227 <color>
1228 <red>0</red>
1229 <green>0</green>
1230 <blue>128</blue>
1231 </color>
1232 <color>
1233 <red>255</red>
1234 <green>255</green>
1235 <blue>255</blue>
1236 </color>
1237 </disabled>
1238 <inactive>
1239 <color>
1240 <red>0</red>
1241 <green>0</green>
1242 <blue>0</blue>
1243 </color>
1244 <color>
1245 <red>181</red>
1246 <green>222</green>
1247 <blue>178</blue>
1248 </color>
1249 <color>
1250 <red>255</red>
1251 <green>255</green>
1252 <blue>255</blue>
1253 </color>
1254 <color>
1255 <red>207</red>
1256 <green>255</green>
1257 <blue>204</blue>
1258 </color>
1259 <color>
1260 <red>90</red>
1261 <green>111</green>
1262 <blue>89</blue>
1263 </color>
1264 <color>
1265 <red>120</red>
1266 <green>148</green>
1267 <blue>118</blue>
1268 </color>
1269 <color>
1270 <red>0</red>
1271 <green>0</green>
1272 <blue>0</blue>
1273 </color>
1274 <color>
1275 <red>255</red>
1276 <green>255</green>
1277 <blue>255</blue>
1278 </color>
1279 <color>
1280 <red>0</red>
1281 <green>0</green>
1282 <blue>0</blue>
1283 </color>
1284 <color>
1285 <red>255</red>
1286 <green>255</green>
1287 <blue>255</blue>
1288 </color>
1289 <color>
1290 <red>174</red>
1291 <green>222</green>
1292 <blue>158</blue>
1293 </color>
1294 <color>
1295 <red>0</red>
1296 <green>0</green>
1297 <blue>0</blue>
1298 </color>
1299 <color>
1300 <red>0</red>
1301 <green>0</green>
1302 <blue>128</blue>
1303 </color>
1304 <color>
1305 <red>255</red>
1306 <green>255</green>
1307 <blue>255</blue>
1308 </color>
1309 </inactive>
1310 </palette>
1311 </property>
1312 <property stdset="1">
1313 <name>text</name>
1314 <string>Cancel</string>
1315 </property>
1316 <property stdset="1">
1317 <name>default</name>
1318 <bool>true</bool>
1319 </property>
1320 </widget>
1321 </vbox>
1322</widget>
1323</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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "shutdownimpl.h"
22
23#include <qpe/global.h>
24
25#include <qtimer.h>
26#include <qprogressbar.h>
27#include <qpushbutton.h>
28#include <qbuttongroup.h>
29#include <qlabel.h>
30
31
32
33#include <stdio.h>
34ShutdownImpl::ShutdownImpl( QWidget* parent, const char *name, WFlags fl )
35 : Shutdown( parent, name, fl )
36{
37 timer = new QTimer( this );
38 connect( timer, SIGNAL(timeout()), this, SLOT(timeout()) );
39
40 connect( ButtonGroup1, SIGNAL(clicked(int)), this, SLOT(buttonClicked(int)) );
41 connect( cancel, SIGNAL(clicked()), this, SLOT(cancelClicked()) );
42
43 progressBar->hide();
44 Global::hideInputMethod();
45#ifdef QT_QWS_CUSTOM
46 QPushButton *sb = Shutdown::shutdown;
47 sb->hide();
48#endif
49}
50
51void ShutdownImpl::buttonClicked( int b )
52{
53 progress = 0;
54 switch ( b ) {
55 case 1:
56 operation = ShutdownSystem;
57 break;
58 case 2:
59 operation = RebootSystem;
60 break;
61 case 3:
62 operation = RestartDesktop;
63 break;
64 case 4:
65 operation = TerminateDesktop;
66 break;
67 }
68 info->hide();
69 progressBar->show();
70 timer->start( 300 );
71 timeout();
72}
73
74void ShutdownImpl::cancelClicked()
75{
76 progressBar->hide();
77 info->show();
78 if ( timer->isActive() )
79 timer->stop();
80 else
81 close();
82}
83
84void ShutdownImpl::timeout()
85{
86 if ( (progress+=2) > progressBar->totalSteps() ) {
87 progressBar->hide();
88 timer->stop();
89 emit shutdown( operation );
90 } else {
91 progressBar->setProgress( progress );
92 }
93}
94
95
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef SHUTDOWNIMPL_H
21#define SHUTDOWNIMPL_H
22
23#include "shutdown.h"
24
25class QTimer;
26
27class ShutdownImpl : public Shutdown
28{
29 Q_OBJECT
30public:
31 ShutdownImpl( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
32
33 enum Type { ShutdownSystem, RebootSystem, RestartDesktop, TerminateDesktop };
34
35signals:
36 void shutdown( ShutdownImpl::Type );
37
38private slots:
39 void buttonClicked( int );
40 void cancelClicked();
41 void timeout();
42
43private:
44 QTimer *timer;
45 int progress;
46 Type operation;
47};
48
49#endif
50
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "sidething.h"
22
23#include <qpe/resource.h>
24
25#include <qrect.h>
26#include <qpopupmenu.h>
27#include <qpainter.h>
28
29
30void PopupWithLaunchSideThing::setFrameRect( const QRect &r )
31{
32 fr = r;
33 QPopupMenu::setFrameRect( r );
34}
35
36
37void PopupWithLaunchSideThing::paintEvent( QPaintEvent *event )
38{
39 QPainter paint( this );
40
41 if ( !contentsRect().contains( event->rect() ) ) {
42
43 QPopupMenu::setFrameRect( fr );
44 int oldLW = lineWidth();
45 setUpdatesEnabled(FALSE);
46 setLineWidth(oldLW);
47 setUpdatesEnabled(TRUE);
48
49 paint.save();
50 paint.setClipRegion( event->region().intersect( frameRect() ) );
51 QPixmap pm( Resource::loadPixmap( sidePixmap ) );
52 paint.drawPixmap( 2, fr.height() - pm.height() - 2, pm );
53 //Need to draw a filled rectangle that extends the colour from the
54 //end of the pixmap up to the top of the popupmenu
55 //paint.fillRect();
56 drawFrame( &paint );
57 paint.restore();
58
59 }
60 if ( event->rect().intersects( contentsRect() ) /* &&
61 (fstyle & MShape) != HLine && (fstyle & MShape) != VLine */ ) {
62
63 QPopupMenu::setFrameRect( QRect(fr.left() + 21, fr.top(), fr.width() - 21, fr.height()) );
64 int oldLW = lineWidth();
65 setUpdatesEnabled(FALSE);
66 setLineWidth(oldLW);
67 setUpdatesEnabled(TRUE);
68
69 paint.setClipRegion( event->region().intersect( contentsRect() ) );
70 drawContents( &paint );
71 }
72
73}
74
75
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#ifndef __SIDE_THING_H__
22#define __SIDE_THING_H__
23
24
25#include "startmenu.h"
26
27
28class PopupWithLaunchSideThing : public StartPopupMenu
29{
30Q_OBJECT
31public:
32 PopupWithLaunchSideThing( QWidget *parent, QString *pixmap ) : StartPopupMenu( parent ), sidePixmap(*pixmap) { }
33
34protected:
35 void setFrameRect( const QRect & );
36 void paintEvent( QPaintEvent *event );
37 QRect fr;
38 QString sidePixmap;
39};
40
41
42#endif // __SIDE_THING_H__
43
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21
22#include "stabmon.h"
23
24#include <qpe/qcopenvelope_qws.h>
25
26#include <qfile.h>
27#include <qcstring.h>
28
29#include <sys/stat.h>
30#include <unistd.h>
31#include <stdlib.h>
32
33SysFileMonitor::SysFileMonitor(QObject* parent) :
34 QObject(parent)
35{
36 startTimer(2000);
37}
38
39const char * stab0 = "/var/run/stab";
40const char * stab1 = "/var/state/pcmcia/stab";
41const char * stab2 = "/var/lib/pcmcia/stab";
42
43void SysFileMonitor::timerEvent(QTimerEvent*)
44{
45 struct stat s;
46
47 static const char * tab [] = {
48 stab0,
49 stab1,
50 stab2
51 };
52 static const int nstab = sizeof(tab)/sizeof(const char *);
53 static int last[nstab];
54
55 bool ch = FALSE;
56 for ( int i=0; i<nstab; i++ ) {
57 if ( ::stat(tab[i], &s)==0 && (long)s.st_mtime != last[i] ) {
58 last[i] = (long)s.st_mtime;
59 ch=TRUE;
60 }
61 if ( ch ) {
62 QCopEnvelope("QPE/Card", "stabChanged()" );
63 break;
64 }
65 }
66
67 // st_size is no use, it's 0 for /proc/mounts too. Read it all.
68 static int mtabSize = 0;
69 QFile f( "/etc/mtab" );
70 if ( f.open(IO_ReadOnly) ) {
71#if 0
72 // readAll does not work correctly on sequential devices (as eg. /proc files)
73 QByteArray ba = f.readAll();
74 if ( (int)ba.size() != mtabSize ) {
75 mtabSize = (int)ba.size();
76 QCopEnvelope("QPE/Card", "mtabChanged()" );
77 }
78#else
79 QString s;
80 while( !f.atEnd() ) {
81 QString tmp;
82 f.readLine( tmp, 1024 );
83 s += tmp;
84 }
85 if ( (int)s.length() != mtabSize ) {
86 mtabSize = (int)s.length();
87 QCopEnvelope("QPE/Card", "mtabChanged()" );
88 }
89 #endif
90 }
91}
92
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21
22#ifndef STABMON_H
23#define STABMON_H
24
25#include <qobject.h>
26
27class SysFileMonitor : public QObject {
28public:
29 SysFileMonitor(QObject* parent);
30protected:
31 void timerEvent(QTimerEvent*);
32};
33
34#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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "startmenu.h"
22#include "sidething.h"
23#include "mrulist.h"
24#include "info.h"
25
26#include <qpe/qpeapplication.h>
27#include <qpe/config.h>
28#include <qpe/applnk.h>
29#include <qpe/global.h>
30#include <qpe/resource.h>
31
32#include <qdict.h>
33
34#include <stdlib.h>
35
36
37// #define USE_CONFIG_FILE
38
39
40StartMenu::StartMenu(QWidget *parent) : QLabel( parent )
41{
42 loadOptions();
43
44 setPixmap( Resource::loadPixmap( startButtonPixmap ) );
45 setFocusPolicy( NoFocus );
46 //setFlat( startButtonIsFlat );
47
48 apps = new AppLnkSet( QPEApplication::qpeDir() + "apps" );
49
50 createMenu();
51}
52
53
54void StartMenu::mousePressEvent( QMouseEvent * )
55{
56 launch();
57 if (desktopInfo)
58 desktopInfo->menuClicked();
59}
60
61
62StartMenu::~StartMenu()
63{
64 delete apps;
65}
66
67
68void StartMenu::loadOptions()
69{
70#ifdef USE_CONFIG_FILE
71 // Read configuration file
72 Config config("StartMenu");
73 config.setGroup( "StartMenu" );
74 QString tmpBoolString1 = config.readEntry( "UseWidePopupMenu", "FALSE" );
75 useWidePopupMenu = ( tmpBoolString1 == "TRUE" ) ? TRUE : FALSE;
76 QString tmpBoolString2 = config.readEntry( "StartButtonIsFlat", "TRUE" );
77 startButtonIsFlat = ( tmpBoolString2 == "TRUE" ) ? TRUE : FALSE;
78 QString tmpBoolString3 = config.readEntry( "UseMRUList", "TRUE" );
79 popupMenuSidePixmap = config.readEntry( "PopupMenuSidePixmap", "sidebar" );
80 startButtonPixmap = config.readEntry( "StartButtonPixmap", "go" );
81#else
82 // Basically just #include the .qpe_menu.conf file settings
83 useWidePopupMenu = FALSE;
84 popupMenuSidePixmap = "sidebar";
85 startButtonIsFlat = TRUE;
86 startButtonPixmap = "go";
87#endif
88}
89
90
91void StartMenu::createMenu()
92{
93 if ( useWidePopupMenu )
94 launchMenu = new PopupWithLaunchSideThing( this, &popupMenuSidePixmap );
95 else
96 launchMenu = new StartPopupMenu( this );
97
98 loadMenu( apps, launchMenu );
99
100}
101
102void StartMenu::itemSelected( int id )
103{
104 const AppLnk *app = apps->find( id );
105 if ( app )
106 app->execute();
107}
108
109bool StartMenu::loadMenu( AppLnkSet *folder, QPopupMenu *menu )
110{
111 bool result = FALSE;
112
113 QStringList typs = folder->types();
114 QDict<QPopupMenu> typpop;
115 for (QStringList::Iterator tit=typs.begin(); tit!=typs.end(); ++tit) {
116 if ( !(*tit).isEmpty() ) {
117 QPopupMenu *new_menu = new StartPopupMenu( menu );
118 typpop.insert(*tit, new_menu);
119 connect( new_menu, SIGNAL(activated(int)), SLOT(itemSelected(int)) );
120 menu->insertItem( folder->typePixmap(*tit), *tit, new_menu );
121 }
122 }
123
124 QListIterator<AppLnk> it( folder->children() );
125 for ( ; it.current(); ++it ) {
126 AppLnk *app = it.current();
127 if ( app->type() == "Separator" ) {
128 menu->insertSeparator();
129 } else {
130 QString t = app->type();
131 QPopupMenu* pmenu = typpop.find(t);
132 if ( !pmenu )
133 pmenu = menu;
134 pmenu->insertItem( app->pixmap(), app->name(), app->id() );
135 result=TRUE;
136 }
137 }
138
139 if ( result )
140 connect( menu, SIGNAL(activated(int)), SLOT(itemSelected(int)) );
141
142 return result;
143}
144
145
146void StartMenu::launch()
147{
148 int y = mapToGlobal( QPoint() ).y() - launchMenu->sizeHint().height();
149
150 if ( launchMenu->isVisible() )
151 launchMenu->hide();
152 else
153 launchMenu->popup( QPoint( 1, y ) );
154}
155
156const AppLnk* StartMenu::execToLink(const QString& appname)
157{
158 const AppLnk* a = apps->findExec( appname );
159 return a;
160}
161
162void StartPopupMenu::keyPressEvent( QKeyEvent *e )
163{
164 if ( e->key() == Key_F33 || e->key() == Key_Space ) {
165 // "OK" button, little hacky
166 QKeyEvent ke(QEvent::KeyPress, Key_Enter, 13, 0);
167 QPopupMenu::keyPressEvent( &ke );
168 } else {
169 QPopupMenu::keyPressEvent( e );
170 }
171}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#ifndef __START_MENU_H__
22#define __START_MENU_H__
23
24#include <qstring.h>
25#include <qlist.h>
26#include <qlabel.h>
27#include <qpopupmenu.h>
28
29
30class AppLnkSet;
31class AppLnk;
32
33class StartPopupMenu : public QPopupMenu
34{
35public:
36 StartPopupMenu( QWidget *parent ) : QPopupMenu( parent ) {}
37protected:
38 void keyPressEvent( QKeyEvent *e );
39};
40
41class StartMenu : public QLabel {
42 Q_OBJECT
43public:
44 StartMenu( QWidget * );
45 ~StartMenu();
46
47 const AppLnk* execToLink(const QString& appname);
48
49public:
50 StartPopupMenu *launchMenu;
51
52public slots:
53 void launch( );
54 void loadOptions( );
55 void createMenu( );
56
57protected slots:
58 void itemSelected( int id );
59
60protected:
61 virtual void mousePressEvent( QMouseEvent * );
62
63private:
64 bool loadMenu( AppLnkSet *folder, QPopupMenu *menu );
65
66private:
67 bool useWidePopupMenu;
68 QString popupMenuSidePixmap;
69
70 bool startButtonIsFlat;
71 QString startButtonPixmap;
72
73 AppLnkSet *apps;
74};
75
76#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 @@
1<!DOCTYPE UI><UI>
2<class>SyncDialog</class>
3<widget>
4 <class>QDialog</class>
5 <property stdset="1">
6 <name>name</name>
7 <cstring>SyncDialog</cstring>
8 </property>
9 <property stdset="1">
10 <name>geometry</name>
11 <rect>
12 <x>0</x>
13 <y>0</y>
14 <width>210</width>
15 <height>244</height>
16 </rect>
17 </property>
18 <property stdset="1">
19 <name>caption</name>
20 <string>Syncing</string>
21 </property>
22 <property stdset="1">
23 <name>sizeGripEnabled</name>
24 <bool>true</bool>
25 </property>
26 <vbox>
27 <property stdset="1">
28 <name>margin</name>
29 <number>11</number>
30 </property>
31 <property stdset="1">
32 <name>spacing</name>
33 <number>6</number>
34 </property>
35 <spacer>
36 <property>
37 <name>name</name>
38 <cstring>Spacer10</cstring>
39 </property>
40 <property stdset="1">
41 <name>orientation</name>
42 <enum>Vertical</enum>
43 </property>
44 <property stdset="1">
45 <name>sizeType</name>
46 <enum>Expanding</enum>
47 </property>
48 <property>
49 <name>sizeHint</name>
50 <size>
51 <width>20</width>
52 <height>20</height>
53 </size>
54 </property>
55 </spacer>
56 <widget>
57 <class>QLayoutWidget</class>
58 <property stdset="1">
59 <name>name</name>
60 <cstring>Layout3</cstring>
61 </property>
62 <hbox>
63 <property stdset="1">
64 <name>margin</name>
65 <number>0</number>
66 </property>
67 <property stdset="1">
68 <name>spacing</name>
69 <number>6</number>
70 </property>
71 <widget>
72 <class>QLabel</class>
73 <property stdset="1">
74 <name>name</name>
75 <cstring>TextLabel1</cstring>
76 </property>
77 <property stdset="1">
78 <name>text</name>
79 <string>Syncing</string>
80 </property>
81 <property stdset="1">
82 <name>alignment</name>
83 <set>AlignCenter</set>
84 </property>
85 <property>
86 <name>hAlign</name>
87 </property>
88 </widget>
89 <widget>
90 <class>QLabel</class>
91 <property stdset="1">
92 <name>name</name>
93 <cstring>whatLabel</cstring>
94 </property>
95 <property stdset="1">
96 <name>text</name>
97 <string>&lt;b&gt;Contacts&lt;/b&gt;</string>
98 </property>
99 </widget>
100 </hbox>
101 </widget>
102 <spacer>
103 <property>
104 <name>name</name>
105 <cstring>Spacer11</cstring>
106 </property>
107 <property stdset="1">
108 <name>orientation</name>
109 <enum>Vertical</enum>
110 </property>
111 <property stdset="1">
112 <name>sizeType</name>
113 <enum>Expanding</enum>
114 </property>
115 <property>
116 <name>sizeHint</name>
117 <size>
118 <width>20</width>
119 <height>20</height>
120 </size>
121 </property>
122 </spacer>
123 <widget>
124 <class>QLayoutWidget</class>
125 <property stdset="1">
126 <name>name</name>
127 <cstring>Layout4</cstring>
128 </property>
129 <hbox>
130 <property stdset="1">
131 <name>margin</name>
132 <number>0</number>
133 </property>
134 <property stdset="1">
135 <name>spacing</name>
136 <number>6</number>
137 </property>
138 <spacer>
139 <property>
140 <name>name</name>
141 <cstring>Spacer4</cstring>
142 </property>
143 <property stdset="1">
144 <name>orientation</name>
145 <enum>Horizontal</enum>
146 </property>
147 <property stdset="1">
148 <name>sizeType</name>
149 <enum>Expanding</enum>
150 </property>
151 <property>
152 <name>sizeHint</name>
153 <size>
154 <width>20</width>
155 <height>20</height>
156 </size>
157 </property>
158 </spacer>
159 <widget>
160 <class>QPushButton</class>
161 <property stdset="1">
162 <name>name</name>
163 <cstring>buttonCancel</cstring>
164 </property>
165 <property stdset="1">
166 <name>text</name>
167 <string>&amp;Cancel</string>
168 </property>
169 <property stdset="1">
170 <name>autoDefault</name>
171 <bool>true</bool>
172 </property>
173 </widget>
174 <spacer>
175 <property>
176 <name>name</name>
177 <cstring>Spacer5</cstring>
178 </property>
179 <property stdset="1">
180 <name>orientation</name>
181 <enum>Horizontal</enum>
182 </property>
183 <property stdset="1">
184 <name>sizeType</name>
185 <enum>Expanding</enum>
186 </property>
187 <property>
188 <name>sizeHint</name>
189 <size>
190 <width>20</width>
191 <height>20</height>
192 </size>
193 </property>
194 </spacer>
195 </hbox>
196 </widget>
197 <spacer>
198 <property>
199 <name>name</name>
200 <cstring>Spacer12</cstring>
201 </property>
202 <property stdset="1">
203 <name>orientation</name>
204 <enum>Vertical</enum>
205 </property>
206 <property stdset="1">
207 <name>sizeType</name>
208 <enum>Expanding</enum>
209 </property>
210 <property>
211 <name>sizeHint</name>
212 <size>
213 <width>20</width>
214 <height>20</height>
215 </size>
216 </property>
217 </spacer>
218 </vbox>
219</widget>
220<connections>
221 <connection>
222 <sender>buttonCancel</sender>
223 <signal>clicked()</signal>
224 <receiver>SyncDialog</receiver>
225 <slot>reject()</slot>
226 </connection>
227</connections>
228</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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include <qpe/qpeapplication.h>
22#include <qpe/qlibrary.h>
23#include <qpe/config.h>
24
25#include <qlayout.h>
26#include <qdir.h>
27#include <qtranslator.h>
28
29#include "quicklauncher.h"
30#include "systray.h"
31
32#include <stdlib.h>
33
34#ifdef SINGLE_APP
35#include "clockappletimpl.h"
36#endif
37
38SysTray::SysTray( QWidget *parent ) : QFrame( parent ), layout(0)
39{
40 //setFrameStyle( QFrame::Panel | QFrame::Sunken );
41 loadApplets();
42}
43
44void SysTray::loadApplets()
45{
46#ifndef SINGLE_APP
47 QValueList<TaskbarApplet>::Iterator mit;
48 for ( mit = appletList.begin(); mit != appletList.end(); ++mit ) {
49 (*mit).iface->release();
50 (*mit).library->unload();
51 delete (*mit).library;
52 }
53 appletList.clear();
54 if ( layout )
55 delete layout;
56 layout = new QHBoxLayout( this );
57
58 QString path = QPEApplication::qpeDir() + "/plugins/applets";
59 QDir dir( path, "lib*.so" );
60 QStringList list = dir.entryList();
61 QStringList::Iterator it;
62 for ( it = list.begin(); it != list.end(); ++it ) {
63 TaskbarAppletInterface *iface = 0;
64 QLibrary *lib = new QLibrary( path + "/" + *it );
65 if ( lib->queryInterface( IID_TaskbarApplet, (QUnknownInterface**)&iface ) == QS_OK ) {
66 TaskbarApplet applet;
67 applet.library = lib;
68 applet.iface = iface;
69 applet.applet = applet.iface->applet( this );
70 positionApplet( applet );
71 QString lang = getenv( "LANG" );
72 QTranslator * trans = new QTranslator(qApp);
73 QString type = (*it).left( (*it).find(".") );
74 QString tfn = QPEApplication::qpeDir()+"/i18n/"+lang+"/"+type+".qm";
75 qDebug("tr fpr sysapplet: %s", tfn.latin1() );
76 if ( trans->load( tfn ))
77 qApp->installTranslator( trans );
78 else
79 delete trans;
80 } else {
81 delete lib;
82 }
83 }
84#else
85 layout = new QHBoxLayout( this );
86 TaskbarApplet applet;
87 applet.iface = new ClockAppletImpl();
88 applet.applet = applet.iface->applet( this );
89 positionApplet( applet );
90#endif
91}
92
93void SysTray::positionApplet( const TaskbarApplet &a )
94{
95 int p = 0;
96 QValueList<TaskbarApplet>::Iterator it;
97 for ( it = appletList.begin(); it != appletList.end(); ++it ) {
98 if ( (*it).iface->position() > a.iface->position() )
99 break;
100 p += 2;
101 }
102
103 appletList.insert( it, a );
104 layout->insertWidget( p, a.applet );
105 layout->insertSpacing( p, 1 );
106}
107
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#ifndef __SYSTRAY_H__
22#define __SYSTRAY_H__
23
24#include <qpe/taskbarappletinterface.h>
25
26#include <qframe.h>
27#include <qvaluelist.h>
28
29class QHBoxLayout;
30class QLibrary;
31
32struct TaskbarApplet
33{
34#ifndef QT_NO_COMPONENT
35 QLibrary *library;
36#endif
37 TaskbarAppletInterface *iface;
38 QWidget *applet;
39};
40
41class SysTray : public QFrame {
42 Q_OBJECT
43public:
44 SysTray( QWidget *parent );
45
46 void loadApplets();
47
48private:
49 void positionApplet( const TaskbarApplet &a );
50
51private:
52 QHBoxLayout *layout;
53 QValueList<TaskbarApplet> appletList;
54};
55
56
57#endif // __SYSTRAY_H__
58
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "startmenu.h"
22#include "inputmethods.h"
23#include "mrulist.h"
24#include "systray.h"
25#include "calibrate.h"
26#include "wait.h"
27#include "appicons.h"
28
29#include "taskbar.h"
30#include "desktop.h"
31
32#include <qpe/qpeapplication.h>
33#include <qpe/qcopenvelope_qws.h>
34#include <qpe/global.h>
35#ifdef QT_QWS_CUSTOM
36#include <qpe/custom.h>
37#endif
38
39#include <qlabel.h>
40#include <qlayout.h>
41#include <qtimer.h>
42#include <qwindowsystem_qws.h>
43#include <qwidgetstack.h>
44
45#if defined( Q_WS_QWS )
46#include <qwsdisplay_qws.h>
47#include <qgfx_qws.h>
48#endif
49
50
51#define FACTORY(T) \
52 static QWidget *new##T( bool maximized ) { \
53 QWidget *w = new T( 0, "test", QWidget::WDestructiveClose | QWidget::WGroupLeader ); \
54 if ( maximized ) { \
55 if ( qApp->desktop()->width() <= 350 ) { \
56 w->showMaximized(); \
57 } else { \
58 w->resize( QSize( 300, 300 ) ); \
59 } \
60 } \
61 w->show(); \
62 return w; \
63 }
64
65
66#ifdef SINGLE_APP
67#define APP(a,b,c,d) FACTORY(b)
68#include "../taskbar/apps.h"
69#undef APP
70#endif // SINGLE_APP
71
72static Global::Command builtins[] = {
73
74#ifdef SINGLE_APP
75#define APP(a,b,c,d) { a, new##b, c },
76#include "../taskbar/apps.h"
77#undef APP
78#endif
79
80#if defined(QT_QWS_IPAQ) || defined(QT_QWS_CASSIOPEIA) || defined(QT_QWS_EBX)
81 { "calibrate", TaskBar::calibrate,1, 0 },
82#endif
83#if !defined(QT_QWS_CASSIOPEIA)
84 { "shutdown", Global::shutdown, 1, 0 },
85 // { "run", run, 1, 0 },
86#endif
87
88 { 0, TaskBar::calibrate,0, 0 },
89};
90
91static bool initNumLock()
92{
93#ifdef QPE_INITIAL_NUMLOCK_STATE
94 QPE_INITIAL_NUMLOCK_STATE
95#endif
96 return FALSE;
97}
98
99class LockKeyState : public QWidget
100{
101public:
102 LockKeyState( QWidget *parent ) :
103 QWidget(parent),
104 nl(initNumLock()), cl(FALSE)
105 {
106 nl_pm = Resource::loadPixmap("numlock");
107 cl_pm = Resource::loadPixmap("capslock");
108 }
109 QSize sizeHint() const
110 {
111 return QSize(nl_pm.width()+2,nl_pm.width()+nl_pm.height()+1);
112 }
113 void toggleNumLockState()
114 {
115 nl = !nl; repaint();
116 }
117 void toggleCapsLockState()
118 {
119 cl = !cl; repaint();
120 }
121 void paintEvent( QPaintEvent * )
122 {
123 int y = (height()-sizeHint().height())/2;
124 QPainter p(this);
125 if ( nl )
126 p.drawPixmap(1,y,nl_pm);
127 if ( cl )
128 p.drawPixmap(1,y+nl_pm.height()+1,cl_pm);
129 }
130private:
131 QPixmap nl_pm, cl_pm;
132 bool nl, cl;
133};
134
135TaskBar::~TaskBar()
136{
137}
138
139
140TaskBar::TaskBar() : QHBox(0, 0, WStyle_Customize | WStyle_Tool | WStyle_StaysOnTop | WGroupLeader)
141{
142 Global::setBuiltinCommands(builtins);
143
144 sm = new StartMenu( this );
145
146 inputMethods = new InputMethods( this );
147 connect( inputMethods, SIGNAL(inputToggled(bool)),
148 this, SLOT(calcMaxWindowRect()) );
149 //new QuickLauncher( this );
150
151 stack = new QWidgetStack( this );
152 stack->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Minimum ) );
153 label = new QLabel(stack);
154
155 mru = new MRUList( stack );
156 stack->raiseWidget( mru );
157
158 waitIcon = new Wait( this );
159 (void) new AppIcons( this );
160
161 sysTray = new SysTray( this );
162
163 // ## make customizable in some way?
164#ifdef QT_QWS_CUSTOM
165 lockState = new LockKeyState( this );
166#else
167 lockState = 0;
168#endif
169
170#if defined(Q_WS_QWS)
171#if !defined(QT_NO_COP)
172 QCopChannel *channel = new QCopChannel( "QPE/TaskBar", this );
173 connect( channel, SIGNAL(received(const QCString&, const QByteArray&)),
174 this, SLOT(receive(const QCString&, const QByteArray&)) );
175#endif
176#endif
177 waitTimer = new QTimer( this );
178 connect( waitTimer, SIGNAL( timeout() ), this, SLOT( stopWait() ) );
179 clearer = new QTimer( this );
180 QObject::connect(clearer, SIGNAL(timeout()), SLOT(clearStatusBar()));
181 QObject::connect(clearer, SIGNAL(timeout()), sysTray, SLOT(show()));
182}
183
184void TaskBar::setStatusMessage( const QString &text )
185{
186 label->setText( text );
187 stack->raiseWidget( label );
188 if ( sysTray && ( label->fontMetrics().width( text ) > label->width() ) )
189 sysTray->hide();
190 clearer->start( 3000 );
191}
192
193void TaskBar::clearStatusBar()
194{
195 label->clear();
196 stack->raiseWidget( mru );
197}
198
199void TaskBar::startWait()
200{
201 waitIcon->setWaiting( true );
202 // a catchall stop after 10 seconds...
203 waitTimer->start( 10 * 1000, true );
204}
205
206void TaskBar::stopWait(const QString& app)
207{
208 waitTimer->stop();
209 mru->addTask(sm->execToLink(app));
210 waitIcon->setWaiting( false );
211}
212
213void TaskBar::stopWait()
214{
215 waitTimer->stop();
216 waitIcon->setWaiting( false );
217}
218
219void TaskBar::resizeEvent( QResizeEvent *e )
220{
221 QHBox::resizeEvent( e );
222 calcMaxWindowRect();
223}
224
225void TaskBar::styleChange( QStyle &s )
226{
227 QHBox::styleChange( s );
228 calcMaxWindowRect();
229}
230
231void TaskBar::calcMaxWindowRect()
232{
233#ifdef Q_WS_QWS
234 QRect wr;
235 int displayWidth = qApp->desktop()->width();
236 QRect ir = inputMethods->inputRect();
237 if ( ir.isValid() ) {
238 wr.setCoords( 0, 0, displayWidth-1, ir.top()-1 );
239 } else {
240 wr.setCoords( 0, 0, displayWidth-1, y()-1 );
241 }
242
243#if QT_VERSION < 300
244 QWSServer::setMaxWindowRect( qt_screen->mapToDevice(wr,
245 QSize(qt_screen->width(),qt_screen->height()))
246 );
247#else
248 QWSServer::setMaxWindowRect( wr );
249#endif
250#endif
251}
252
253void TaskBar::receive( const QCString &msg, const QByteArray &data )
254{
255 QDataStream stream( data, IO_ReadOnly );
256 if ( msg == "message(QString)" ) {
257 QString text;
258 stream >> text;
259 setStatusMessage( text );
260 } else if ( msg == "hideInputMethod()" ) {
261 inputMethods->hideInputMethod();
262 } else if ( msg == "showInputMethod()" ) {
263 inputMethods->showInputMethod();
264 } else if ( msg == "reloadInputMethods()" ) {
265 inputMethods->loadInputMethods();
266 } else if ( msg == "reloadApplets()" ) {
267 sysTray->loadApplets();
268 } else if ( msg == "soundAlarm()" ) {
269 Desktop::soundAlarm();
270 }
271#ifdef CUSTOM_LEDS
272 else if ( msg == "setLed(int,bool)" ) {
273 int led, status;
274 stream >> led >> status;
275 CUSTOM_LEDS( led, status );
276 }
277#endif
278}
279
280QWidget *TaskBar::calibrate(bool)
281{
282#ifdef Q_WS_QWS
283 Calibrate *c = new Calibrate;
284 c->show();
285 return c;
286#else
287 return 0;
288#endif
289}
290
291void TaskBar::toggleNumLockState()
292{
293 if ( lockState ) lockState->toggleNumLockState();
294}
295
296void TaskBar::toggleCapsLockState()
297{
298 if ( lockState ) lockState->toggleCapsLockState();
299}
300
301void TaskBar::toggleSymbolInput()
302{
303 if ( inputMethods->currentShown() == "Unicode" ) {
304 inputMethods->hideInputMethod();
305 } else {
306 inputMethods->showInputMethod("Unicode");
307 }
308}
309
310bool TaskBar::recoverMemory()
311{
312 return mru->quitOldApps();
313}
314
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#ifndef __TASKBAR_H__
22#define __TASKBAR_H__
23
24#ifdef QT_QWS_CUSTOM
25#include <qpe/custom.h>
26#endif
27
28#include <qhbox.h>
29
30class QLabel;
31class QTimer;
32class InputMethods;
33class Wait;
34class SysTray;
35class MRUList;
36class QWidgetStack;
37class QTimer;
38class QLabel;
39class StartMenu;
40class LockKeyState;
41
42class TaskBar : public QHBox {
43 Q_OBJECT
44public:
45 TaskBar();
46 ~TaskBar();
47
48 static QWidget *calibrate( bool );
49
50 bool recoverMemory();
51
52 StartMenu *startMenu() const { return sm; }
53public slots:
54 void startWait();
55 void stopWait(const QString&);
56 void stopWait();
57 void clearStatusBar();
58 void toggleNumLockState();
59 void toggleCapsLockState();
60 void toggleSymbolInput();
61
62protected:
63 void resizeEvent( QResizeEvent * );
64 void styleChange( QStyle & );
65 void setStatusMessage( const QString &text );
66
67private slots:
68 void calcMaxWindowRect();
69 void receive( const QCString &msg, const QByteArray &data );
70
71private:
72
73 QTimer *waitTimer;
74 Wait *waitIcon;
75 InputMethods *inputMethods;
76 SysTray *sysTray;
77 MRUList *mru;
78 QWidgetStack *stack;
79 QTimer *clearer;
80 QLabel *label;
81 LockKeyState* lockState;
82 StartMenu *sm;
83};
84
85
86#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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#define _XOPEN_SOURCE
21#include <pwd.h>
22#include <sys/types.h>
23#include <unistd.h>
24#include <stdlib.h>
25
26#if defined(_OS_LINUX_)
27#include <shadow.h>
28#endif
29
30#include <qdir.h>
31#include <qfile.h>
32#include <qtextstream.h>
33#include <qdatastream.h>
34#include <qmessagebox.h>
35#include <qstringlist.h>
36#include <qfileinfo.h>
37#include <qregexp.h>
38//#include <qpe/qcopchannel_qws.h>
39#include <qpe/qprocess.h>
40#include <qpe/process.h>
41#include <qpe/config.h>
42#include <qpe/qcopenvelope_qws.h>
43
44#include "transferserver.h"
45
46const int block_size = 51200;
47
48TransferServer::TransferServer( Q_UINT16 port, QObject *parent = 0,
49 const char* name = 0)
50 : QServerSocket( port, 1, parent, name )
51{
52 if ( !ok() )
53 qWarning( "Failed to bind to port %d", port );
54}
55
56TransferServer::~TransferServer()
57{
58
59}
60
61void TransferServer::newConnection( int socket )
62{
63 (void) new ServerPI( socket, this );
64}
65
66bool accessAuthorized(QHostAddress peeraddress)
67{
68 Config cfg("Security");
69 cfg.setGroup("Sync");
70 uint auth_peer = cfg.readNumEntry("auth_peer",0xc0a80100);
71 uint auth_peer_bits = cfg.readNumEntry("auth_peer_bits",24);
72 bool ok = (peeraddress.ip4Addr() & (((1<<auth_peer_bits)-1)<<(32-auth_peer_bits)))
73 == auth_peer;
74 /* Allows denial-of-service attack.
75 if ( !ok ) {
76 QMessageBox::warning(0,tr("Security"),
77 tr("<p>An attempt to access this device from %1 has been denied.")
78 .arg(peeraddress.toString()));
79 }
80 */
81 return ok;
82}
83
84ServerPI::ServerPI( int socket, QObject *parent = 0, const char* name = 0 )
85 : QSocket( parent, name ) , dtp( 0 ), serversocket( 0 ), waitsocket( 0 )
86{
87 state = Connected;
88
89 setSocket( socket );
90
91 peerport = peerPort();
92 peeraddress = peerAddress();
93
94#ifndef INSECURE
95 if ( !accessAuthorized(peeraddress) ) {
96 state = Forbidden;
97 startTimer( 0 );
98 } else
99 #endif
100 {
101 connect( this, SIGNAL( readyRead() ), SLOT( read() ) );
102 connect( this, SIGNAL( connectionClosed() ), SLOT( connectionClosed() ) );
103
104 passiv = FALSE;
105 for( int i = 0; i < 4; i++ )
106 wait[i] = FALSE;
107
108 send( "220 Qtopia transfer service ready!" );
109 state = Wait_USER;
110
111 dtp = new ServerDTP( this );
112 connect( dtp, SIGNAL( completed() ), SLOT( dtpCompleted() ) );
113 connect( dtp, SIGNAL( failed() ), SLOT( dtpFailed() ) );
114 connect( dtp, SIGNAL( error( int ) ), SLOT( dtpError( int ) ) );
115
116
117 directory = QDir::currentDirPath();
118
119 static int p = 1024;
120
121 while ( !serversocket || !serversocket->ok() ) {
122 delete serversocket;
123 serversocket = new ServerSocket( ++p, this );
124 }
125 connect( serversocket, SIGNAL( newIncomming( int ) ),
126 SLOT( newConnection( int ) ) );
127 }
128}
129
130ServerPI::~ServerPI()
131{
132
133}
134
135void ServerPI::connectionClosed()
136{
137 // qDebug( "Debug: Connection closed" );
138 delete this;
139}
140
141void ServerPI::send( const QString& msg )
142{
143 QTextStream os( this );
144 os << msg << endl;
145 //qDebug( "Reply: %s", msg.latin1() );
146}
147
148void ServerPI::read()
149{
150 while ( canReadLine() )
151 process( readLine().stripWhiteSpace() );
152}
153
154bool ServerPI::checkUser( const QString& user )
155{
156 if ( user.isEmpty() ) return FALSE;
157
158 struct passwd *pw;
159 pw = getpwuid( geteuid() );
160 QString euser = QString::fromLocal8Bit( pw->pw_name );
161 return user == euser;
162}
163
164bool ServerPI::checkPassword( const QString& /* password */ )
165{
166 // ### HACK for testing on local host
167 return true;
168
169 /*
170 struct passwd *pw = 0;
171 struct spwd *spw = 0;
172
173 pw = getpwuid( geteuid() );
174 spw = getspnam( pw->pw_name );
175
176 QString cpwd = QString::fromLocal8Bit( pw->pw_passwd );
177 if ( cpwd == "x" && spw )
178 cpwd = QString::fromLocal8Bit( spw->sp_pwdp );
179
180 QString cpassword = QString::fromLocal8Bit( crypt( password.local8Bit(), cpwd.local8Bit() ) );
181 return cpwd == cpassword;
182*/
183}
184
185bool ServerPI::checkReadFile( const QString& file )
186{
187 QString filename;
188
189 if ( file[0] != "/" )
190 filename = directory.path() + "/" + file;
191 else
192 filename = file;
193
194 QFileInfo fi( filename );
195 return ( fi.exists() && fi.isReadable() );
196}
197
198bool ServerPI::checkWriteFile( const QString& file )
199{
200 QString filename;
201
202 if ( file[0] != "/" )
203 filename = directory.path() + "/" + file;
204 else
205 filename = file;
206
207 QFileInfo fi( filename );
208
209 if ( fi.exists() )
210 if ( !QFile( filename ).remove() )
211 return FALSE;
212 return TRUE;
213}
214
215void ServerPI::process( const QString& message )
216{
217 //qDebug( "Command: %s", message.latin1() );
218
219 // split message using "," as separator
220 QStringList msg = QStringList::split( " ", message );
221 if ( msg.isEmpty() ) return;
222
223 // command token
224 QString cmd = msg[0].upper();
225
226 // argument token
227 QString arg;
228 if ( msg.count() >= 2 )
229 arg = msg[1];
230
231 // full argument string
232 QString args;
233 if ( msg.count() >= 2 ) {
234 QStringList copy( msg );
235 // FIXME: for Qt3
236 // copy.pop_front()
237 copy.remove( copy.begin() );
238 args = copy.join( " " );
239 }
240
241 //qDebug( "args: %s", args.latin1() );
242
243 // we always respond to QUIT, regardless of state
244 if ( cmd == "QUIT" ) {
245 send( "211 Good bye!" );
246 delete this;
247 return;
248 }
249
250 // connected to client
251 if ( Connected == state )
252 return;
253
254 // waiting for user name
255 if ( Wait_USER == state ) {
256
257 if ( cmd != "USER" || msg.count() < 2 || !checkUser( arg ) ) {
258 send( "530 Please login with USER and PASS" );
259 return;
260 }
261 send( "331 User name ok, need password" );
262 state = Wait_PASS;
263 return;
264 }
265
266 // waiting for password
267 if ( Wait_PASS == state ) {
268
269 if ( cmd != "PASS" || !checkPassword( arg ) ) {
270 //if ( cmd != "PASS" || msg.count() < 2 || !checkPassword( arg ) ) {
271 send( "530 Please login with USER and PASS" );
272 return;
273 }
274 send( "230 User logged in, proceed" );
275 state = Ready;
276 return;
277 }
278
279 // ACCESS CONTROL COMMANDS
280
281
282 // account (ACCT)
283 if ( cmd == "ACCT" ) {
284 // even wu-ftp does not support it
285 send( "502 Command not implemented" );
286 }
287
288 // change working directory (CWD)
289 else if ( cmd == "CWD" ) {
290
291 if ( !args.isEmpty() ) {
292 if ( directory.cd( args, TRUE ) )
293 send( "250 Requested file action okay, completed" );
294 else
295 send( "550 Requested action not taken" );
296 }
297 else
298 send( "500 Syntax error, command unrecognized" );
299 }
300
301 // change to parent directory (CDUP)
302 else if ( cmd == "CDUP" ) {
303 if ( directory.cdUp() )
304 send( "250 Requested file action okay, completed" );
305 else
306 send( "550 Requested action not taken" );
307 }
308
309 // structure mount (SMNT)
310 else if ( cmd == "SMNT" ) {
311 // even wu-ftp does not support it
312 send( "502 Command not implemented" );
313 }
314
315 // reinitialize (REIN)
316 else if ( cmd == "REIN" ) {
317 // even wu-ftp does not support it
318 send( "502 Command not implemented" );
319 }
320
321
322 // TRANSFER PARAMETER COMMANDS
323
324
325 // data port (PORT)
326 else if ( cmd == "PORT" ) {
327 if ( parsePort( arg ) )
328 send( "200 Command okay" );
329 else
330 send( "500 Syntax error, command unrecognized" );
331 }
332
333 // passive (PASV)
334 else if ( cmd == "PASV" ) {
335 passiv = TRUE;
336 send( "227 Entering Passive Mode ("
337 + address().toString().replace( QRegExp( "\\." ), "," ) + ","
338 + QString::number( ( serversocket->port() ) >> 8 ) + ","
339 + QString::number( ( serversocket->port() ) & 0xFF ) +")" );
340 }
341
342 // representation type (TYPE)
343 else if ( cmd == "TYPE" ) {
344 if ( arg.upper() == "A" || arg.upper() == "I" )
345 send( "200 Command okay" );
346 else
347 send( "504 Command not implemented for that parameter" );
348 }
349
350 // file structure (STRU)
351 else if ( cmd == "STRU" ) {
352 if ( arg.upper() == "F" )
353 send( "200 Command okay" );
354 else
355 send( "504 Command not implemented for that parameter" );
356 }
357
358 // transfer mode (MODE)
359 else if ( cmd == "MODE" ) {
360 if ( arg.upper() == "S" )
361 send( "200 Command okay" );
362 else
363 send( "504 Command not implemented for that parameter" );
364 }
365
366
367 // FTP SERVICE COMMANDS
368
369
370 // retrieve (RETR)
371 else if ( cmd == "RETR" )
372 if ( !args.isEmpty() && checkReadFile( absFilePath( args ) )
373 || backupRestoreGzip( absFilePath( args ) ) ) {
374 send( "150 File status okay" );
375 sendFile( absFilePath( args ) );
376 }
377 else {
378 qDebug("550 Requested action not taken");
379 send( "550 Requested action not taken" );
380 }
381
382 // store (STOR)
383 else if ( cmd == "STOR" )
384 if ( !args.isEmpty() && checkWriteFile( absFilePath( args ) ) ) {
385 send( "150 File status okay" );
386 retrieveFile( absFilePath( args ) );
387 }
388 else
389 send( "550 Requested action not taken" );
390
391 // store unique (STOU)
392 else if ( cmd == "STOU" ) {
393 send( "502 Command not implemented" );
394 }
395
396 // append (APPE)
397 else if ( cmd == "APPE" ) {
398 send( "502 Command not implemented" );
399 }
400
401 // allocate (ALLO)
402 else if ( cmd == "ALLO" ) {
403 send( "200 Command okay" );
404 }
405
406 // restart (REST)
407 else if ( cmd == "REST" ) {
408 send( "502 Command not implemented" );
409 }
410
411 // rename from (RNFR)
412 else if ( cmd == "RNFR" ) {
413 renameFrom = QString::null;
414 if ( args.isEmpty() )
415 send( "500 Syntax error, command unrecognized" );
416 else {
417 QFile file( absFilePath( args ) );
418 if ( file.exists() ) {
419 send( "350 File exists, ready for destination name" );
420 renameFrom = absFilePath( args );
421 }
422 else
423 send( "550 Requested action not taken" );
424 }
425 }
426
427 // rename to (RNTO)
428 else if ( cmd == "RNTO" ) {
429 if ( lastCommand != "RNFR" )
430 send( "503 Bad sequence of commands" );
431 else if ( args.isEmpty() )
432 send( "500 Syntax error, command unrecognized" );
433 else {
434 QDir dir( absFilePath( args ) );
435 if ( dir.rename( renameFrom, absFilePath( args ), TRUE ) )
436 send( "250 Requested file action okay, completed." );
437 else
438 send( "550 Requested action not taken" );
439 }
440 }
441
442 // abort (ABOR)
443 else if ( cmd.contains( "ABOR" ) ) {
444 dtp->close();
445 if ( dtp->dtpMode() != ServerDTP::Idle )
446 send( "426 Connection closed; transfer aborted" );
447 else
448 send( "226 Closing data connection" );
449 }
450
451 // delete (DELE)
452 else if ( cmd == "DELE" ) {
453 if ( args.isEmpty() )
454 send( "500 Syntax error, command unrecognized" );
455 else {
456 QFile file( absFilePath( args ) ) ;
457 if ( file.remove() )
458 send( "250 Requested file action okay, completed" );
459 else
460 send( "550 Requested action not taken" );
461 }
462 }
463
464 // remove directory (RMD)
465 else if ( cmd == "RMD" ) {
466 if ( args.isEmpty() )
467 send( "500 Syntax error, command unrecognized" );
468 else {
469 QDir dir;
470 if ( dir.rmdir( absFilePath( args ), TRUE ) )
471 send( "250 Requested file action okay, completed" );
472 else
473 send( "550 Requested action not taken" );
474 }
475 }
476
477 // make directory (MKD)
478 else if ( cmd == "MKD" ) {
479 if ( args.isEmpty() ) {
480 qDebug(" Error: no arg");
481 send( "500 Syntax error, command unrecognized" );
482 }
483 else {
484 QDir dir;
485 if ( dir.mkdir( absFilePath( args ), TRUE ) )
486 send( "250 Requested file action okay, completed." );
487 else
488 send( "550 Requested action not taken" );
489 }
490 }
491
492 // print working directory (PWD)
493 else if ( cmd == "PWD" ) {
494 send( "257 \"" + directory.path() +"\"" );
495 }
496
497 // list (LIST)
498 else if ( cmd == "LIST" ) {
499 if ( sendList( absFilePath( args ) ) )
500 send( "150 File status okay" );
501 else
502 send( "500 Syntax error, command unrecognized" );
503 }
504
505 // size (SIZE)
506 else if ( cmd == "SIZE" ) {
507 QString filePath = absFilePath( args );
508 QFileInfo fi( filePath );
509 bool gzipfile = backupRestoreGzip( filePath );
510 if ( !fi.exists() && !gzipfile )
511 send( "500 Syntax error, command unrecognized" );
512 else {
513 if ( !gzipfile )
514 send( "213 " + QString::number( fi.size() ) );
515 else {
516 Process duproc( QString("du") );
517 duproc.addArgument("-s");
518 QString in, out;
519 if ( !duproc.exec(in, out) ) {
520 qDebug("du process failed; just sending back 1K");
521 send( "213 1024");
522 }
523 else {
524 QString size = out.left( out.find("\t") );
525 int guess = size.toInt()/5;
526 if ( filePath.contains("doc") )
527 guess *= 1000;
528 qDebug("sending back gzip guess of %d", guess);
529 send( "213 " + QString::number(guess) );
530 }
531 }
532 }
533 }
534 // name list (NLST)
535 else if ( cmd == "NLST" ) {
536 send( "502 Command not implemented" );
537 }
538
539 // site parameters (SITE)
540 else if ( cmd == "SITE" ) {
541 send( "502 Command not implemented" );
542 }
543
544 // system (SYST)
545 else if ( cmd == "SYST" ) {
546 send( "215 UNIX Type: L8" );
547 }
548
549 // status (STAT)
550 else if ( cmd == "STAT" ) {
551 send( "502 Command not implemented" );
552 }
553
554 // help (HELP )
555 else if ( cmd == "HELP" ) {
556 send( "502 Command not implemented" );
557 }
558
559 // noop (NOOP)
560 else if ( cmd == "NOOP" ) {
561 send( "200 Command okay" );
562 }
563
564 // not implemented
565 else
566 send( "502 Command not implemented" );
567
568 lastCommand = cmd;
569}
570
571bool ServerPI::backupRestoreGzip( const QString &file )
572{
573 return (file.find( "backup" ) != -1 &&
574 file.findRev( ".tgz" ) == (int)file.length()-4 );
575}
576
577bool ServerPI::backupRestoreGzip( const QString &file, QStringList &targets )
578{
579 if ( file.find( "backup" ) != -1 &&
580 file.findRev( ".tgz" ) == (int)file.length()-4 ) {
581 QFileInfo info( file );
582 targets = info.dirPath( TRUE );
583 qDebug("ServerPI::backupRestoreGzip for %s = %s", file.latin1(),
584 targets.join(" ").latin1() );
585 return true;
586 }
587 return false;
588}
589
590void ServerPI::sendFile( const QString& file )
591{
592 if ( passiv ) {
593 wait[SendFile] = TRUE;
594 waitfile = file;
595 if ( waitsocket )
596 newConnection( waitsocket );
597 }
598 else {
599 QStringList targets;
600 if ( backupRestoreGzip( file, targets ) )
601 dtp->sendGzipFile( file, targets, peeraddress, peerport );
602 else dtp->sendFile( file, peeraddress, peerport );
603 }
604}
605
606void ServerPI::retrieveFile( const QString& file )
607{
608 if ( passiv ) {
609 wait[RetrieveFile] = TRUE;
610 waitfile = file;
611 if ( waitsocket )
612 newConnection( waitsocket );
613 }
614 else {
615 QStringList targets;
616 if ( backupRestoreGzip( file, targets ) )
617 dtp->retrieveGzipFile( file, peeraddress, peerport );
618 else
619 dtp->retrieveFile( file, peeraddress, peerport );
620 }
621}
622
623bool ServerPI::parsePort( const QString& pp )
624{
625 QStringList p = QStringList::split( ",", pp );
626 if ( p.count() != 6 ) return FALSE;
627
628 // h1,h2,h3,h4,p1,p2
629 peeraddress = QHostAddress( ( p[0].toInt() << 24 ) + ( p[1].toInt() << 16 ) +
630 ( p[2].toInt() << 8 ) + p[3].toInt() );
631 peerport = ( p[4].toInt() << 8 ) + p[5].toInt();
632 return TRUE;
633}
634
635void ServerPI::dtpCompleted()
636{
637 dtp->close();
638 waitsocket = 0;
639 send( "226 Closing data connection, file transfer successful" );
640}
641
642void ServerPI::dtpFailed()
643{
644 dtp->close();
645 waitsocket = 0;
646 send( "451 Requested action aborted: local error in processing" );
647}
648
649void ServerPI::dtpError( int )
650{
651 dtp->close();
652 waitsocket = 0;
653 send( "451 Requested action aborted: local error in processing" );
654}
655
656bool ServerPI::sendList( const QString& arg )
657{
658 QByteArray listing;
659 QBuffer buffer( listing );
660
661 if ( !buffer.open( IO_WriteOnly ) )
662 return FALSE;
663
664 QTextStream ts( &buffer );
665 QString fn = arg;
666
667 if ( fn.isEmpty() )
668 fn = directory.path();
669
670 QFileInfo fi( fn );
671 if ( !fi.exists() ) return FALSE;
672
673 // return file listing
674 if ( fi.isFile() ) {
675 ts << fileListing( &fi ) << endl;
676 }
677
678 // return directory listing
679 else if ( fi.isDir() ) {
680 QDir dir( fn );
681 const QFileInfoList *list = dir.entryInfoList( QDir::All | QDir::Hidden );
682
683 QFileInfoListIterator it( *list );
684 QFileInfo *info;
685
686 unsigned long total = 0;
687 while ( ( info = it.current() ) ) {
688 if ( info->fileName() != "." && info->fileName() != ".." )
689 total += info->size();
690 ++it;
691 }
692
693 ts << "total " << QString::number( total / 1024 ) << endl;
694
695 it.toFirst();
696 while ( ( info = it.current() ) ) {
697 if ( info->fileName() == "." || info->fileName() == ".." ) {
698 ++it;
699 continue;
700 }
701 ts << fileListing( info ) << endl;
702 ++it;
703 }
704 }
705
706 if ( passiv ) {
707 waitarray = buffer.buffer();
708 wait[SendByteArray] = TRUE;
709 if ( waitsocket )
710 newConnection( waitsocket );
711 }
712 else
713 dtp->sendByteArray( buffer.buffer(), peeraddress, peerport );
714 return TRUE;
715}
716
717QString ServerPI::fileListing( QFileInfo *info )
718{
719 if ( !info ) return QString::null;
720 QString s;
721
722 // type char
723 if ( info->isDir() )
724 s += "d";
725 else if ( info->isSymLink() )
726 s += "l";
727 else
728 s += "-";
729
730 // permisson string
731 s += permissionString( info ) + " ";
732
733 // number of hardlinks
734 int subdirs = 1;
735
736 if ( info->isDir() )
737 subdirs = 2;
738 // FIXME : this is to slow
739 //if ( info->isDir() )
740 //subdirs = QDir( info->absFilePath() ).entryList( QDir::Dirs ).count();
741
742 s += QString::number( subdirs ).rightJustify( 3, ' ', TRUE ) + " ";
743
744 // owner
745 s += info->owner().leftJustify( 8, ' ', TRUE ) + " ";
746
747 // group
748 s += info->group().leftJustify( 8, ' ', TRUE ) + " ";
749
750 // file size in bytes
751 s += QString::number( info->size() ).rightJustify( 9, ' ', TRUE ) + " ";
752
753 // last modified date
754 QDate date = info->lastModified().date();
755 QTime time = info->lastModified().time();
756 s += date.monthName( date.month() ) + " "
757 + QString::number( date.day() ).rightJustify( 2, ' ', TRUE ) + " "
758 + QString::number( time.hour() ).rightJustify( 2, '0', TRUE ) + ":"
759 + QString::number( time.minute() ).rightJustify( 2,'0', TRUE ) + " ";
760
761 // file name
762 s += info->fileName();
763
764 return s;
765}
766
767QString ServerPI::permissionString( QFileInfo *info )
768{
769 if ( !info ) return QString( "---------" );
770 QString s;
771
772 // user
773 if ( info->permission( QFileInfo::ReadUser ) ) s += "r";
774 else s += "-";
775 if ( info->permission( QFileInfo::WriteUser ) ) s += "w";
776 else s += "-";
777 if ( info->permission( QFileInfo::ExeUser ) ) s += "x";
778 else s += "-";
779
780 // group
781 if ( info->permission( QFileInfo::ReadGroup ) ) s += "r";
782 else s += "-";
783 if ( info->permission( QFileInfo::WriteGroup ) )s += "w";
784 else s += "-";
785 if ( info->permission( QFileInfo::ExeGroup ) ) s += "x";
786 else s += "-";
787
788 // exec
789 if ( info->permission( QFileInfo::ReadOther ) ) s += "r";
790 else s += "-";
791 if ( info->permission( QFileInfo::WriteOther ) ) s += "w";
792 else s += "-";
793 if ( info->permission( QFileInfo::ExeOther ) ) s += "x";
794 else s += "-";
795
796 return s;
797}
798
799void ServerPI::newConnection( int socket )
800{
801 //qDebug( "New incomming connection" );
802
803 if ( !passiv ) return;
804
805 if ( wait[SendFile] ) {
806 QStringList targets;
807 if ( backupRestoreGzip( waitfile, targets ) )
808 dtp->sendGzipFile( waitfile, targets );
809 else
810 dtp->sendFile( waitfile );
811 dtp->setSocket( socket );
812 }
813 else if ( wait[RetrieveFile] ) {
814 qDebug("check retrieve file");
815 if ( backupRestoreGzip( waitfile ) )
816 dtp->retrieveGzipFile( waitfile );
817 else
818 dtp->retrieveFile( waitfile );
819 dtp->setSocket( socket );
820 }
821 else if ( wait[SendByteArray] ) {
822 dtp->sendByteArray( waitarray );
823 dtp->setSocket( socket );
824 }
825 else if ( wait[RetrieveByteArray] ) {
826 qDebug("retrieve byte array");
827 dtp->retrieveByteArray();
828 dtp->setSocket( socket );
829 }
830 else
831 waitsocket = socket;
832
833 for( int i = 0; i < 4; i++ )
834 wait[i] = FALSE;
835}
836
837QString ServerPI::absFilePath( const QString& file )
838{
839 if ( file.isEmpty() ) return file;
840
841 QString filepath( file );
842 if ( file[0] != "/" )
843 filepath = directory.path() + "/" + file;
844
845 return filepath;
846}
847
848
849void ServerPI::timerEvent( QTimerEvent * )
850{
851 connectionClosed();
852}
853
854
855ServerDTP::ServerDTP( QObject *parent = 0, const char* name = 0)
856 : QSocket( parent, name ), mode( Idle ), createTargzProc( 0 ),
857retrieveTargzProc( 0 ), gzipProc( 0 )
858{
859
860 connect( this, SIGNAL( connected() ), SLOT( connected() ) );
861 connect( this, SIGNAL( connectionClosed() ), SLOT( connectionClosed() ) );
862 connect( this, SIGNAL( bytesWritten( int ) ), SLOT( bytesWritten( int ) ) );
863 connect( this, SIGNAL( readyRead() ), SLOT( readyRead() ) );
864
865 gzipProc = new QProcess( this, "gzipProc" );
866 gzipProc->setCommunication( QProcess::Stdin | QProcess::Stdout );
867
868 createTargzProc = new QProcess( QString("tar"), this, "createTargzProc");
869 createTargzProc->setCommunication( QProcess::Stdout );
870 createTargzProc->setWorkingDirectory( QDir::rootDirPath() );
871 connect( createTargzProc, SIGNAL( processExited() ), SLOT( targzDone() ) );
872
873 QStringList args = "tar";
874 args += "-xv";
875 retrieveTargzProc = new QProcess( args, this, "retrieveTargzProc" );
876 retrieveTargzProc->setCommunication( QProcess::Stdin );
877 retrieveTargzProc->setWorkingDirectory( QDir::rootDirPath() );
878 connect( retrieveTargzProc, SIGNAL( processExited() ),
879 SIGNAL( completed() ) );
880 connect( retrieveTargzProc, SIGNAL( processExited() ),
881 SLOT( extractTarDone() ) );
882}
883
884ServerDTP::~ServerDTP()
885{
886 buf.close();
887 file.close();
888 createTargzProc->kill();
889}
890
891void ServerDTP::extractTarDone()
892{
893 qDebug("extract done");
894 QCopEnvelope e( "QPE/Desktop", "restoreDone(QString)" );
895 e << file.name();
896}
897
898void ServerDTP::connected()
899{
900 // send file mode
901 switch ( mode ) {
902 case SendFile :
903 if ( !file.exists() || !file.open( IO_ReadOnly) ) {
904 emit failed();
905 mode = Idle;
906 return;
907 }
908
909 //qDebug( "Debug: Sending file '%s'", file.name().latin1() );
910
911 bytes_written = 0;
912 if ( file.size() == 0 ) {
913 //make sure it doesn't hang on empty files
914 file.close();
915 emit completed();
916 mode = Idle;
917 } else {
918
919 if( !file.atEnd() ) {
920 QCString s;
921 s.resize( block_size );
922 int bytes = file.readBlock( s.data(), block_size );
923 writeBlock( s.data(), bytes );
924 }
925 }
926 break;
927 case SendGzipFile:
928 if ( createTargzProc->isRunning() ) {
929 // SHOULDN'T GET HERE, BUT DOING A SAFETY CHECK ANYWAY
930 qWarning("Previous tar --gzip process is still running; killing it...");
931 createTargzProc->kill();
932 }
933
934 bytes_written = 0;
935 qDebug("==>start send tar process");
936 if ( !createTargzProc->start() )
937 qWarning("Error starting %s or %s",
938 createTargzProc->arguments().join(" ").latin1(),
939 gzipProc->arguments().join(" ").latin1() );
940 break;
941 case SendBuffer:
942 if ( !buf.open( IO_ReadOnly) ) {
943 emit failed();
944 mode = Idle;
945 return;
946 }
947
948 // qDebug( "Debug: Sending byte array" );
949 bytes_written = 0;
950 while( !buf.atEnd() )
951 putch( buf.getch() );
952 buf.close();
953 break;
954 case RetrieveFile:
955 // retrieve file mode
956 if ( file.exists() && !file.remove() ) {
957 emit failed();
958 mode = Idle;
959 return;
960 }
961
962 if ( !file.open( IO_WriteOnly) ) {
963 emit failed();
964 mode = Idle;
965 return;
966 }
967 // qDebug( "Debug: Retrieving file %s", file.name().latin1() );
968 break;
969 case RetrieveGzipFile:
970 qDebug("=-> starting tar process to receive .tgz file");
971 break;
972 case RetrieveBuffer:
973 // retrieve buffer mode
974 if ( !buf.open( IO_WriteOnly) ) {
975 emit failed();
976 mode = Idle;
977 return;
978 }
979 // qDebug( "Debug: Retrieving byte array" );
980 break;
981 case Idle:
982 qDebug("connection established but mode set to Idle; BUG!");
983 break;
984 }
985}
986
987void ServerDTP::connectionClosed()
988{
989 //qDebug( "Debug: Data connection closed %ld bytes written", bytes_written );
990
991 // send file mode
992 if ( SendFile == mode ) {
993 if ( bytes_written == file.size() )
994 emit completed();
995 else
996 emit failed();
997 }
998
999 // send buffer mode
1000 else if ( SendBuffer == mode ) {
1001 if ( bytes_written == buf.size() )
1002 emit completed();
1003 else
1004 emit failed();
1005 }
1006
1007 // retrieve file mode
1008 else if ( RetrieveFile == mode ) {
1009 file.close();
1010 emit completed();
1011 }
1012
1013 else if ( RetrieveGzipFile == mode ) {
1014 qDebug("Done writing ungzip file; closing input");
1015 gzipProc->flushStdin();
1016 gzipProc->closeStdin();
1017 }
1018
1019 // retrieve buffer mode
1020 else if ( RetrieveBuffer == mode ) {
1021 buf.close();
1022 emit completed();
1023 }
1024
1025 mode = Idle;
1026}
1027
1028void ServerDTP::bytesWritten( int bytes )
1029{
1030 bytes_written += bytes;
1031
1032 // send file mode
1033 if ( SendFile == mode ) {
1034
1035 if ( bytes_written == file.size() ) {
1036 // qDebug( "Debug: Sending complete: %d bytes", file.size() );
1037 file.close();
1038 emit completed();
1039 mode = Idle;
1040 }
1041 else if( !file.atEnd() ) {
1042 QCString s;
1043 s.resize( block_size );
1044 int bytes = file.readBlock( s.data(), block_size );
1045 writeBlock( s.data(), bytes );
1046 }
1047 }
1048
1049 // send buffer mode
1050 if ( SendBuffer == mode ) {
1051
1052 if ( bytes_written == buf.size() ) {
1053 // qDebug( "Debug: Sending complete: %d bytes", buf.size() );
1054 emit completed();
1055 mode = Idle;
1056 }
1057 }
1058}
1059
1060void ServerDTP::readyRead()
1061{
1062 // retrieve file mode
1063 if ( RetrieveFile == mode ) {
1064 QCString s;
1065 s.resize( bytesAvailable() );
1066 readBlock( s.data(), bytesAvailable() );
1067 file.writeBlock( s.data(), s.size() );
1068 }
1069 else if ( RetrieveGzipFile == mode ) {
1070 if ( !gzipProc->isRunning() )
1071 gzipProc->start();
1072
1073 QByteArray s;
1074 s.resize( bytesAvailable() );
1075 readBlock( s.data(), bytesAvailable() );
1076 gzipProc->writeToStdin( s );
1077 qDebug("wrote %d bytes to ungzip ", s.size() );
1078 }
1079 // retrieve buffer mode
1080 else if ( RetrieveBuffer == mode ) {
1081 QCString s;
1082 s.resize( bytesAvailable() );
1083 readBlock( s.data(), bytesAvailable() );
1084 buf.writeBlock( s.data(), s.size() );
1085 }
1086}
1087
1088void ServerDTP::writeTargzBlock()
1089{
1090 QByteArray block = gzipProc->readStdout();
1091 writeBlock( block.data(), block.size() );
1092 qDebug("writeTargzBlock %d", block.size());
1093 if ( !createTargzProc->isRunning() ) {
1094 qDebug("tar and gzip done");
1095 emit completed();
1096 mode = Idle;
1097 disconnect( gzipProc, SIGNAL( readyReadStdout() ),
1098 this, SLOT( writeTargzBlock() ) );
1099 }
1100}
1101
1102void ServerDTP::targzDone()
1103{
1104 //qDebug("targz done");
1105 disconnect( createTargzProc, SIGNAL( readyReadStdout() ),
1106 this, SLOT( gzipTarBlock() ) );
1107 gzipProc->closeStdin();
1108}
1109
1110void ServerDTP::gzipTarBlock()
1111{
1112 //qDebug("gzipTarBlock");
1113 if ( !gzipProc->isRunning() ) {
1114 //qDebug("auto start gzip proc");
1115 gzipProc->start();
1116 }
1117 gzipProc->writeToStdin( createTargzProc->readStdout() );
1118}
1119
1120void ServerDTP::sendFile( const QString fn, const QHostAddress& host, Q_UINT16 port )
1121{
1122 file.setName( fn );
1123 mode = SendFile;
1124 connectToHost( host.toString(), port );
1125}
1126
1127void ServerDTP::sendFile( const QString fn )
1128{
1129 file.setName( fn );
1130 mode = SendFile;
1131}
1132
1133void ServerDTP::sendGzipFile( const QString &fn,
1134 const QStringList &archiveTargets,
1135 const QHostAddress& host, Q_UINT16 port )
1136{
1137 sendGzipFile( fn, archiveTargets );
1138 connectToHost( host.toString(), port );
1139}
1140
1141void ServerDTP::sendGzipFile( const QString &fn,
1142 const QStringList &archiveTargets )
1143{
1144 mode = SendGzipFile;
1145 file.setName( fn );
1146
1147 QStringList args = "tar";
1148 args += "-cv";
1149 args += archiveTargets;
1150 qDebug("sendGzipFile %s", args.join(" ").latin1() );
1151 createTargzProc->setArguments( args );
1152 connect( createTargzProc,
1153 SIGNAL( readyReadStdout() ), SLOT( gzipTarBlock() ) );
1154
1155 gzipProc->setArguments( "gzip" );
1156 connect( gzipProc, SIGNAL( readyReadStdout() ),
1157 SLOT( writeTargzBlock() ) );
1158}
1159
1160void ServerDTP::gunzipDone()
1161{
1162 qDebug("gunzipDone");
1163 disconnect( gzipProc, SIGNAL( processExited() ),
1164 this, SLOT( gunzipDone() ) );
1165 retrieveTargzProc->closeStdin();
1166 disconnect( gzipProc, SIGNAL( readyReadStdout() ),
1167 this, SLOT( tarExtractBlock() ) );
1168}
1169
1170void ServerDTP::tarExtractBlock()
1171{
1172 qDebug("ungzipTarBlock");
1173 if ( !retrieveTargzProc->isRunning() ) {
1174 qDebug("auto start ungzip proc");
1175 if ( !retrieveTargzProc->start() )
1176 qWarning(" failed to start tar -x process");
1177 }
1178 retrieveTargzProc->writeToStdin( gzipProc->readStdout() );
1179}
1180
1181
1182void ServerDTP::retrieveFile( const QString fn, const QHostAddress& host, Q_UINT16 port )
1183{
1184 file.setName( fn );
1185 mode = RetrieveFile;
1186 connectToHost( host.toString(), port );
1187}
1188
1189void ServerDTP::retrieveFile( const QString fn )
1190{
1191 file.setName( fn );
1192 mode = RetrieveFile;
1193}
1194
1195void ServerDTP::retrieveGzipFile( const QString &fn )
1196{
1197 qDebug("retrieveGzipFile %s", fn.latin1());
1198 file.setName( fn );
1199 mode = RetrieveGzipFile;
1200
1201 gzipProc->setArguments( "gunzip" );
1202 connect( gzipProc, SIGNAL( readyReadStdout() ),
1203 SLOT( tarExtractBlock() ) );
1204 connect( gzipProc, SIGNAL( processExited() ),
1205 SLOT( gunzipDone() ) );
1206}
1207
1208void ServerDTP::retrieveGzipFile( const QString &fn, const QHostAddress& host, Q_UINT16 port )
1209{
1210 retrieveGzipFile( fn );
1211 connectToHost( host.toString(), port );
1212}
1213
1214void ServerDTP::sendByteArray( const QByteArray& array, const QHostAddress& host, Q_UINT16 port )
1215{
1216 buf.setBuffer( array );
1217 mode = SendBuffer;
1218 connectToHost( host.toString(), port );
1219}
1220
1221void ServerDTP::sendByteArray( const QByteArray& array )
1222{
1223 buf.setBuffer( array );
1224 mode = SendBuffer;
1225}
1226
1227void ServerDTP::retrieveByteArray( const QHostAddress& host, Q_UINT16 port )
1228{
1229 buf.setBuffer( QByteArray() );
1230 mode = RetrieveBuffer;
1231 connectToHost( host.toString(), port );
1232}
1233
1234void ServerDTP::retrieveByteArray()
1235{
1236 buf.setBuffer( QByteArray() );
1237 mode = RetrieveBuffer;
1238}
1239
1240void ServerDTP::setSocket( int socket )
1241{
1242 QSocket::setSocket( socket );
1243 connected();
1244}
1245
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#include <qserversocket.h>
21#include <qsocket.h>
22#include <qdir.h>
23#include <qfile.h>
24#include <qbuffer.h>
25
26class QFileInfo;
27class QProcess;
28class TransferServer : public QServerSocket
29{
30 Q_OBJECT
31
32public:
33 TransferServer( Q_UINT16 port, QObject *parent = 0, const char* name = 0 );
34 virtual ~TransferServer();
35
36 void newConnection( int socket );
37};
38
39
40class ServerDTP : public QSocket
41{
42 Q_OBJECT
43
44public:
45 ServerDTP( QObject *parent = 0, const char* name = 0 );
46 ~ServerDTP();
47
48 enum Mode{ Idle = 0, SendFile, SendGzipFile, SendBuffer,
49 RetrieveFile, RetrieveGzipFile, RetrieveBuffer };
50
51 void sendFile( const QString fn );
52 void sendFile( const QString fn, const QHostAddress& host, Q_UINT16 port );
53 void sendGzipFile( const QString &fn, const QStringList &archiveTargets );
54 void sendGzipFile( const QString &fn, const QStringList &archiveTargets,
55 const QHostAddress& host, Q_UINT16 port );
56 void sendByteArray( const QByteArray& array );
57 void sendByteArray( const QByteArray& array, const QHostAddress& host, Q_UINT16 port );
58
59 void retrieveFile( const QString fn );
60 void retrieveFile( const QString fn, const QHostAddress& host, Q_UINT16 port );
61 void retrieveGzipFile( const QString &fn );
62 void retrieveGzipFile( const QString &fn, const QHostAddress& host, Q_UINT16 port );
63 void retrieveByteArray();
64 void retrieveByteArray( const QHostAddress& host, Q_UINT16 port );
65
66 Mode dtpMode() { return mode; }
67 QByteArray buffer() { return buf.buffer(); }
68
69 void setSocket( int socket );
70
71signals:
72 void completed();
73 void failed();
74
75private slots:
76 void connectionClosed();
77 void connected();
78 void bytesWritten( int bytes );
79 void readyRead();
80 void writeTargzBlock();
81 void targzDone();
82
83 void gzipTarBlock();
84 void tarExtractBlock();
85 void gunzipDone();
86 void extractTarDone();
87
88private:
89
90 unsigned long bytes_written;
91 Mode mode;
92 QFile file;
93 QBuffer buf;
94 QProcess *createTargzProc;
95 QProcess *retrieveTargzProc;
96 QProcess *gzipProc;
97};
98
99class ServerSocket : public QServerSocket
100{
101 Q_OBJECT
102
103public:
104 ServerSocket( Q_UINT16 port, QObject *parent = 0, const char* name = 0 )
105 : QServerSocket( port, 1, parent, name ) {}
106
107 void newConnection( int socket ) { emit newIncomming( socket ); }
108signals:
109 void newIncomming( int socket );
110};
111
112class ServerPI : public QSocket
113{
114 Q_OBJECT
115
116 enum State { Connected, Wait_USER, Wait_PASS, Ready, Forbidden };
117 enum Transfer { SendFile = 0, RetrieveFile = 1, SendByteArray = 2, RetrieveByteArray = 3 };
118
119public:
120 ServerPI( int socket, QObject *parent = 0, const char* name = 0 );
121 virtual ~ServerPI();
122
123protected slots:
124 void read();
125 void send( const QString& msg );
126 void process( const QString& command );
127 void connectionClosed();
128 void dtpCompleted();
129 void dtpFailed();
130 void dtpError( int );
131 void newConnection( int socket );
132
133protected:
134 bool checkUser( const QString& user );
135 bool checkPassword( const QString& pw );
136 bool checkReadFile( const QString& file );
137 bool checkWriteFile( const QString& file );
138 bool parsePort( const QString& pw );
139 bool backupRestoreGzip( const QString &file, QStringList &targets );
140 bool backupRestoreGzip( const QString &file );
141
142 bool sendList( const QString& arg );
143 void sendFile( const QString& file );
144 void retrieveFile( const QString& file );
145
146 QString permissionString( QFileInfo *info );
147 QString fileListing( QFileInfo *info );
148 QString absFilePath( const QString& file );
149
150 void timerEvent( QTimerEvent *e );
151
152private:
153 State state;
154 Q_UINT16 peerport;
155 QHostAddress peeraddress;
156 bool passiv;
157 bool wait[4];
158 ServerDTP *dtp;
159 ServerSocket *serversocket;
160 QString waitfile;
161 QDir directory;
162 QByteArray waitarray;
163 QString renameFrom;
164 QString lastCommand;
165 int waitsocket;
166};
167
168bool 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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "wait.h"
22
23#include <qpe/resource.h>
24
25#include <qwidget.h>
26#include <qpixmap.h>
27#include <qpainter.h>
28
29
30Wait *lastWaitObject = NULL;
31
32
33Wait::Wait( QWidget *parent ) : QWidget( parent ),
34 pm( Resource::loadPixmap( "wait" ) ), waiting( FALSE )
35{
36 setFixedSize( pm.size() );
37 lastWaitObject = this;
38 hide();
39}
40
41
42Wait *Wait::getWaitObject()
43{
44 return lastWaitObject;
45}
46
47
48void Wait::setWaiting( bool w )
49{
50 waiting = w;
51 if ( w )
52 show();
53 else
54 hide();
55}
56
57
58void Wait::paintEvent( QPaintEvent * )
59{
60 QPainter p( this );
61 p.drawPixmap( 0, 0, pm );
62}
63
64
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#ifndef __WAIT_H__
22#define __WAIT_H__
23
24#include <qpe/resource.h>
25
26#include <qwidget.h>
27#include <qpixmap.h>
28#include <qpainter.h>
29
30
31class Wait : public QWidget
32{
33public:
34 Wait( QWidget *parent );
35 void setWaiting( bool w );
36 void paintEvent( QPaintEvent * );
37 static Wait *getWaitObject();
38private:
39 QPixmap pm;
40 bool waiting;
41};
42
43
44#endif // __WAIT_H__
45
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 @@
1moc_*
2Makefile
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 @@
1#############################################################################
2
3####### Compiler, tools and options
4
5 CXX =$(SYSCONF_CXX) $(QT_CXX_MT)
6 CXXFLAGS=$(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS) -DQCONFIG=\"qpe\"
7 CC =$(SYSCONF_CC) $(QT_C_MT)
8 CFLAGS =$(SYSCONF_CFLAGS) -DQCONFIG=\"qpe\"
9 INCPATH =-I$(QPEDIR)/include
10 LFLAGS =$(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
11 LIBS =$(SUBLIBS) -lqpe -lpthread $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
12 MOC =$(SYSCONF_MOC)
13 UIC =$(SYSCONF_UIC)
14
15####### Target
16
17DESTDIR = $(QPEDIR)/bin/
18VER_MAJ = 1
19VER_MIN = 0
20VER_PATCH = 0
21 TARGET= mpegplayer
22TARGET1 = lib$(TARGET).so.$(VER_MAJ)
23
24####### Files
25
26 HEADERS =loopcontrol.h \
27 mediaplayerplugininterface.h \
28 playlistselection.h \
29 mediaplayerstate.h \
30 videowidget.h \
31 audiowidget.h \
32 playlistwidget.h \
33 mediaplayer.h \
34 audiodevice.h
35 SOURCES =main.cpp \
36 loopcontrol.cpp \
37 playlistselection.cpp \
38 mediaplayerstate.cpp \
39 videowidget.cpp \
40 audiowidget.cpp \
41 playlistwidget.cpp \
42 mediaplayer.cpp \
43 audiodevice.cpp
44 OBJECTS =main.o \
45 loopcontrol.o \
46 playlistselection.o \
47 mediaplayerstate.o \
48 videowidget.o \
49 audiowidget.o \
50 playlistwidget.o \
51 mediaplayer.o \
52 audiodevice.o
53INTERFACES =
54UICDECLS =
55UICIMPLS =
56 SRCMOC =moc_loopcontrol.cpp \
57 moc_playlistselection.cpp \
58 moc_mediaplayerstate.cpp \
59 moc_videowidget.cpp \
60 moc_audiowidget.cpp \
61 moc_playlistwidget.cpp \
62 moc_mediaplayer.cpp \
63 moc_audiodevice.cpp
64 OBJMOC =moc_loopcontrol.o \
65 moc_playlistselection.o \
66 moc_mediaplayerstate.o \
67 moc_videowidget.o \
68 moc_audiowidget.o \
69 moc_playlistwidget.o \
70 moc_mediaplayer.o \
71 moc_audiodevice.o
72
73
74####### Implicit rules
75
76.SUFFIXES: .cpp .cxx .cc .C .c
77
78.cpp.o:
79 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
80
81.cxx.o:
82 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
83
84.cc.o:
85 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
86
87.C.o:
88 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
89
90.c.o:
91 $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
92
93####### Build rules
94
95
96all: $(DESTDIR)$(TARGET)
97
98$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
99 $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
100
101moc: $(SRCMOC)
102
103tmake:
104 tmake mpegplayer.pro
105
106clean:
107 -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
108 -rm -f *~ core
109 -rm -f allmoc.cpp
110
111####### Extension Modules
112
113listpromodules:
114 @echo
115
116listallmodules:
117 @echo
118
119listaddonpromodules:
120 @echo
121
122listaddonentmodules:
123 @echo
124
125
126REQUIRES=
127
128####### Sub-libraries
129
130
131###### Combined headers
132
133
134
135####### Compile
136
137main.o: main.cpp \
138 $(QPEDIR)/include/qpe/qpeapplication.h \
139 mediaplayerstate.h \
140 playlistwidget.h \
141 $(QPEDIR)/include/qpe/applnk.h \
142 audiowidget.h \
143 videowidget.h \
144 loopcontrol.h \
145 mediaplayer.h \
146 $(QPEDIR)/include/qpe/qlibrary.h \
147 $(QPEDIR)/include/qpe/qcom.h \
148 $(QPEDIR)/include/qpe/quuid.h \
149 mediaplayerplugininterface.h
150
151loopcontrol.o: loopcontrol.cpp \
152 $(QPEDIR)/include/qpe/qpeapplication.h \
153 $(QPEDIR)/include/qpe/qcopenvelope_qws.h \
154 loopcontrol.h \
155 videowidget.h \
156 audiodevice.h \
157 mediaplayerplugininterface.h \
158 $(QPEDIR)/include/qpe/qcom.h \
159 $(QPEDIR)/include/qpe/quuid.h \
160 mediaplayerstate.h
161
162playlistselection.o: playlistselection.cpp \
163 $(QPEDIR)/include/qpe/applnk.h \
164 $(QPEDIR)/include/qpe/resource.h \
165 playlistselection.h
166
167mediaplayerstate.o: mediaplayerstate.cpp \
168 $(QPEDIR)/include/qpe/qpeapplication.h \
169 $(QPEDIR)/include/qpe/qlibrary.h \
170 $(QPEDIR)/include/qpe/qcom.h \
171 $(QPEDIR)/include/qpe/quuid.h \
172 $(QPEDIR)/include/qpe/config.h \
173 mediaplayerplugininterface.h \
174 mediaplayerstate.h \
175 libmad/libmadpluginimpl.h \
176 libmpeg3/libmpeg3pluginimpl.h \
177 wavplugin/wavpluginimpl.h
178
179videowidget.o: videowidget.cpp \
180 $(QPEDIR)/include/qpe/resource.h \
181 videowidget.h \
182 mediaplayerplugininterface.h \
183 $(QPEDIR)/include/qpe/qcom.h \
184 $(QPEDIR)/include/qpe/quuid.h \
185 mediaplayerstate.h
186
187audiowidget.o: audiowidget.cpp \
188 $(QPEDIR)/include/qpe/resource.h \
189 audiowidget.h \
190 mediaplayerstate.h
191
192playlistwidget.o: playlistwidget.cpp \
193 $(QPEDIR)/include/qpe/qpemenubar.h \
194 $(QPEDIR)/include/qpe/qpetoolbar.h \
195 $(QPEDIR)/include/qpe/fileselector.h \
196 $(QPEDIR)/include/qpe/applnk.h \
197 $(QPEDIR)/include/qpe/config.h \
198 $(QPEDIR)/include/qpe/global.h \
199 $(QPEDIR)/include/qpe/resource.h \
200 playlistselection.h \
201 playlistwidget.h \
202 mediaplayerstate.h
203
204mediaplayer.o: mediaplayer.cpp \
205 $(QPEDIR)/include/qpe/qpeapplication.h \
206 $(QPEDIR)/include/qpe/qlibrary.h \
207 $(QPEDIR)/include/qpe/qcom.h \
208 $(QPEDIR)/include/qpe/quuid.h \
209 $(QPEDIR)/include/qpe/resource.h \
210 $(QPEDIR)/include/qpe/config.h \
211 mediaplayer.h \
212 mediaplayerplugininterface.h \
213 playlistwidget.h \
214 $(QPEDIR)/include/qpe/applnk.h \
215 audiowidget.h \
216 loopcontrol.h \
217 audiodevice.h \
218 mediaplayerstate.h
219
220audiodevice.o: audiodevice.cpp \
221 $(QPEDIR)/include/qpe/qpeapplication.h \
222 $(QPEDIR)/include/qpe/config.h \
223 audiodevice.h \
224 $(QPEDIR)/include/qpe/qcopenvelope_qws.h
225
226moc_loopcontrol.o: moc_loopcontrol.cpp \
227 loopcontrol.h
228
229moc_playlistselection.o: moc_playlistselection.cpp \
230 playlistselection.h \
231 $(QPEDIR)/include/qpe/applnk.h
232
233moc_mediaplayerstate.o: moc_mediaplayerstate.cpp \
234 mediaplayerstate.h
235
236moc_videowidget.o: moc_videowidget.cpp \
237 videowidget.h
238
239moc_audiowidget.o: moc_audiowidget.cpp \
240 audiowidget.h
241
242moc_playlistwidget.o: moc_playlistwidget.cpp \
243 playlistwidget.h \
244 $(QPEDIR)/include/qpe/applnk.h
245
246moc_mediaplayer.o: moc_mediaplayer.cpp \
247 mediaplayer.h \
248 $(QPEDIR)/include/qpe/qlibrary.h \
249 $(QPEDIR)/include/qpe/qcom.h \
250 $(QPEDIR)/include/qpe/quuid.h \
251 mediaplayerplugininterface.h
252
253moc_audiodevice.o: moc_audiodevice.cpp \
254 audiodevice.h
255
256moc_loopcontrol.cpp: loopcontrol.h
257 $(MOC) loopcontrol.h -o moc_loopcontrol.cpp
258
259moc_playlistselection.cpp: playlistselection.h
260 $(MOC) playlistselection.h -o moc_playlistselection.cpp
261
262moc_mediaplayerstate.cpp: mediaplayerstate.h
263 $(MOC) mediaplayerstate.h -o moc_mediaplayerstate.cpp
264
265moc_videowidget.cpp: videowidget.h
266 $(MOC) videowidget.h -o moc_videowidget.cpp
267
268moc_audiowidget.cpp: audiowidget.h
269 $(MOC) audiowidget.h -o moc_audiowidget.cpp
270
271moc_playlistwidget.cpp: playlistwidget.h
272 $(MOC) playlistwidget.h -o moc_playlistwidget.cpp
273
274moc_mediaplayer.cpp: mediaplayer.h
275 $(MOC) mediaplayer.h -o moc_mediaplayer.cpp
276
277moc_audiodevice.cpp: audiodevice.h
278 $(MOC) audiodevice.h -o moc_audiodevice.cpp
279
280
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#include <stdlib.h>
21#include <qpe/qpeapplication.h>
22#include <qpe/config.h>
23#include "audiodevice.h"
24
25#if ( defined Q_WS_QWS || defined(_WS_QWS_) ) && !defined(QT_NO_COP)
26#include "qpe/qcopenvelope_qws.h"
27#endif
28
29#ifdef Q_WS_WIN
30#include <windows.h>
31#include <mmsystem.h>
32#include <mmreg.h>
33#endif
34
35#if defined(Q_WS_X11) || defined(Q_WS_QWS)
36#include <fcntl.h>
37#include <sys/ioctl.h>
38#include <sys/soundcard.h>
39#include <sys/stat.h>
40#include <sys/time.h>
41#include <sys/types.h>
42#include <unistd.h>
43#endif
44
45#if defined(Q_OS_WIN32)
46static const int expectedBytesPerMilliSecond = 2 * 2 * 44000 / 1000;
47static const int timerResolutionMilliSeconds = 30;
48static const int sound_fragment_bytes = timerResolutionMilliSeconds * expectedBytesPerMilliSecond;
49#else
50# if defined(QT_QWS_IPAQ)
51static const int sound_fragment_shift = 14;
52# else
53static const int sound_fragment_shift = 16;
54# endif
55static const int sound_fragment_bytes = (1<<sound_fragment_shift);
56#endif
57
58
59class AudioDevicePrivate {
60public:
61 int handle;
62 unsigned int frequency;
63 unsigned int channels;
64 unsigned int bytesPerSample;
65 unsigned int bufferSize;
66#ifndef Q_OS_WIN32
67 bool can_GETOSPACE;
68 char* unwrittenBuffer;
69 unsigned int unwritten;
70#endif
71
72 static int dspFd;
73 static bool muted;
74 static unsigned int leftVolume;
75 static unsigned int rightVolume;
76};
77
78
79#ifdef Q_WS_QWS
80// This is for keeping the device open in-between playing files when
81// the device makes clicks and it starts to drive you insane! :)
82// Best to have the device not open when not using it though
83//#define KEEP_DEVICE_OPEN
84#endif
85
86
87int AudioDevicePrivate::dspFd = 0;
88bool AudioDevicePrivate::muted = FALSE;
89unsigned int AudioDevicePrivate::leftVolume = 0;
90unsigned int AudioDevicePrivate::rightVolume = 0;
91
92
93void AudioDevice::getVolume( unsigned int& leftVolume, unsigned int& rightVolume, bool &muted ) {
94 muted = AudioDevicePrivate::muted;
95 unsigned int volume;
96#ifdef Q_OS_WIN32
97 HWAVEOUT handle;
98 WAVEFORMATEX formatData;
99 formatData.cbSize = sizeof(WAVEFORMATEX);
100 formatData.wFormatTag = WAVE_FORMAT_PCM;
101 formatData.nAvgBytesPerSec = 4 * 44000;
102 formatData.nBlockAlign = 4;
103 formatData.nChannels = 2;
104 formatData.nSamplesPerSec = 44000;
105 formatData.wBitsPerSample = 16;
106 waveOutOpen(&handle, WAVE_MAPPER, &formatData, 0L, 0L, CALLBACK_NULL);
107 if ( waveOutGetVolume( handle, (LPDWORD)&volume ) )
108 qDebug( "get volume of audio device failed" );
109 waveOutClose( handle );
110 leftVolume = volume & 0xFFFF;
111 rightVolume = volume >> 16;
112#else
113 int mixerHandle = open( "/dev/mixer", O_RDWR );
114 if ( mixerHandle >= 0 ) {
115 ioctl( mixerHandle, MIXER_READ(0), &volume );
116 close( mixerHandle );
117 } else
118 qDebug( "get volume of audio device failed" );
119 leftVolume = ((volume & 0x00FF) << 16) / 101;
120 rightVolume = ((volume & 0xFF00) << 8) / 101;
121#endif
122}
123
124
125void AudioDevice::setVolume( unsigned int leftVolume, unsigned int rightVolume, bool muted ) {
126 AudioDevicePrivate::muted = muted;
127 if ( muted ) {
128 AudioDevicePrivate::leftVolume = leftVolume;
129 AudioDevicePrivate::rightVolume = rightVolume;
130 leftVolume = 0;
131 rightVolume = 0;
132 } else {
133 leftVolume = ( (int) leftVolume < 0 ) ? 0 : (( leftVolume > 0xFFFF ) ? 0xFFFF : leftVolume );
134 rightVolume = ( (int)rightVolume < 0 ) ? 0 : (( rightVolume > 0xFFFF ) ? 0xFFFF : rightVolume );
135 }
136#ifdef Q_OS_WIN32
137 HWAVEOUT handle;
138 WAVEFORMATEX formatData;
139 formatData.cbSize = sizeof(WAVEFORMATEX);
140 formatData.wFormatTag = WAVE_FORMAT_PCM;
141 formatData.nAvgBytesPerSec = 4 * 44000;
142 formatData.nBlockAlign = 4;
143 formatData.nChannels = 2;
144 formatData.nSamplesPerSec = 44000;
145 formatData.wBitsPerSample = 16;
146 waveOutOpen(&handle, WAVE_MAPPER, &formatData, 0L, 0L, CALLBACK_NULL);
147 unsigned int volume = (rightVolume << 16) | leftVolume;
148 if ( waveOutSetVolume( handle, volume ) )
149 qDebug( "set volume of audio device failed" );
150 waveOutClose( handle );
151#else
152 // Volume can be from 0 to 100 which is 101 distinct values
153 unsigned int rV = (rightVolume * 101) >> 16;
154
155# if 0
156 unsigned int lV = (leftVolume * 101) >> 16;
157 unsigned int volume = ((rV << 8) & 0xFF00) | (lV & 0x00FF);
158 int mixerHandle = 0;
159 if ( ( mixerHandle = open( "/dev/mixer", O_RDWR ) ) >= 0 ) {
160 ioctl( mixerHandle, MIXER_WRITE(0), &volume );
161 close( mixerHandle );
162 } else
163 qDebug( "set volume of audio device failed" );
164# else
165 // This is the way this has to be done now I guess, doesn't allow for
166 // independant right and left channel setting, or setting for different outputs
167 Config cfg("Sound");
168 cfg.setGroup("System");
169 cfg.writeEntry("Volume",(int)rV);
170# endif
171
172#endif
173// qDebug( "setting volume to: 0x%x", volume );
174#if ( defined Q_WS_QWS || defined(_WS_QWS_) ) && !defined(QT_NO_COP)
175 // Send notification that the volume has changed
176 QCopEnvelope( "QPE/System", "volumeChange(bool)" ) << muted;
177#endif
178}
179
180
181
182
183AudioDevice::AudioDevice( unsigned int f, unsigned int chs, unsigned int bps ) {
184 d = new AudioDevicePrivate;
185 d->frequency = f;
186 d->channels = chs;
187 d->bytesPerSample = bps;
188
189 connect( qApp, SIGNAL( volumeChanged(bool) ), this, SLOT( volumeChanged(bool) ) );
190
191#ifdef Q_OS_WIN32
192 UINT result;
193 WAVEFORMATEX formatData;
194 formatData.cbSize = sizeof(WAVEFORMATEX);
195/*
196 // Other possible formats windows supports
197 formatData.wFormatTag = WAVE_FORMAT_MPEG;
198 formatData.wFormatTag = WAVE_FORMAT_MPEGLAYER3;
199 formatData.wFormatTag = WAVE_FORMAT_ADPCM;
200*/
201 formatData.wFormatTag = WAVE_FORMAT_PCM;
202 formatData.nAvgBytesPerSec = bps * chs * f;
203 formatData.nBlockAlign = bps * chs;
204 formatData.nChannels = chs;
205 formatData.nSamplesPerSec = f;
206 formatData.wBitsPerSample = bps * 8;
207 // Open a waveform device for output
208 if (result = waveOutOpen((LPHWAVEOUT)&d->handle, WAVE_MAPPER, &formatData, 0L, 0L, CALLBACK_NULL)) {
209 QString errorMsg = "error opening audio device.\nReason: %i - ";
210 switch (result) {
211 case MMSYSERR_ALLOCATED:errorMsg += "Specified resource is already allocated."; break;
212 case MMSYSERR_BADDEVICEID:errorMsg += "Specified device identifier is out of range."; break;
213 case MMSYSERR_NODRIVER:errorMsg += "No device driver is present."; break;
214 case MMSYSERR_NOMEM:errorMsg += "Unable to allocate or lock memory."; break;
215 case WAVERR_BADFORMAT:errorMsg += "Attempted to open with an unsupported waveform-audio format."; break;
216 case WAVERR_SYNC: errorMsg += "The device is synchronous but waveOutOpen was called without using the WAVE_ALLOWSYNC flag."; break;
217 default: errorMsg += "Undefined error"; break;
218 }
219 qDebug( errorMsg, result );
220 }
221
222 d->bufferSize = sound_fragment_bytes;
223#else
224
225 int fragments = 0x10000 * 8 + sound_fragment_shift;
226 int format = AFMT_S16_LE;
227 int capabilities = 0;
228
229#ifdef KEEP_DEVICE_OPEN
230 if ( AudioDevicePrivate::dspFd == 0 ) {
231#endif
232 if ( ( d->handle = ::open( "/dev/dsp", O_WRONLY ) ) < 0 ) {
233 qDebug( "error opening audio device /dev/dsp, sending data to /dev/null instead" );
234 d->handle = ::open( "/dev/null", O_WRONLY );
235 }
236#ifdef KEEP_DEVICE_OPEN
237 AudioDevicePrivate::dspFd = d->handle;
238 } else {
239 d->handle = AudioDevicePrivate::dspFd;
240 }
241#endif
242
243 ioctl( d->handle, SNDCTL_DSP_GETCAPS, &capabilities );
244 ioctl( d->handle, SNDCTL_DSP_SETFRAGMENT, &fragments );
245 ioctl( d->handle, SNDCTL_DSP_SETFMT, &format );
246 ioctl( d->handle, SNDCTL_DSP_SPEED, &d->frequency );
247 if ( ioctl( d->handle, SNDCTL_DSP_CHANNELS, &d->channels ) == -1 ) {
248 d->channels = ( d->channels == 1 ) ? 2 : d->channels;
249 ioctl( d->handle, SNDCTL_DSP_CHANNELS, &d->channels );
250 }
251
252 d->bufferSize = sound_fragment_bytes;
253 d->unwrittenBuffer = new char[d->bufferSize];
254 d->unwritten = 0;
255 d->can_GETOSPACE = TRUE; // until we find otherwise
256
257 //if ( chs != d->channels ) qDebug( "Wanted %d, got %d channels", chs, d->channels );
258 //if ( f != d->frequency ) qDebug( "wanted %dHz, got %dHz", f, d->frequency );
259 //if ( capabilities & DSP_CAP_BATCH ) qDebug( "Sound card has local buffer" );
260 //if ( capabilities & DSP_CAP_REALTIME )qDebug( "Sound card has realtime sync" );
261 //if ( capabilities & DSP_CAP_TRIGGER ) qDebug( "Sound card has precise trigger" );
262 //if ( capabilities & DSP_CAP_MMAP ) qDebug( "Sound card can mmap" );
263#endif
264}
265
266
267AudioDevice::~AudioDevice() {
268#ifdef Q_OS_WIN32
269 waveOutClose( (HWAVEOUT)d->handle );
270#else
271# ifndef KEEP_DEVICE_OPEN
272 close( d->handle ); // Now it should be safe to shut the handle
273# endif
274 delete d->unwrittenBuffer;
275 delete d;
276#endif
277}
278
279
280void AudioDevice::volumeChanged( bool muted )
281{
282 AudioDevicePrivate::muted = muted;
283}
284
285
286void AudioDevice::write( char *buffer, unsigned int length )
287{
288#ifdef Q_OS_WIN32
289 // returns immediately and (to be implemented) emits completedIO() when finished writing
290 WAVEHDR *lpWaveHdr = (WAVEHDR *)malloc( sizeof(WAVEHDR) );
291 // maybe the buffer should be copied so that this fool proof, but its a performance hit
292 lpWaveHdr->lpData = buffer;
293 lpWaveHdr->dwBufferLength = length;
294 lpWaveHdr->dwFlags = 0L;
295 lpWaveHdr->dwLoops = 0L;
296 waveOutPrepareHeader( (HWAVEOUT)d->handle, lpWaveHdr, sizeof(WAVEHDR) );
297 // waveOutWrite returns immediately. the data is sent in the background.
298 if ( waveOutWrite( (HWAVEOUT)d->handle, lpWaveHdr, sizeof(WAVEHDR) ) )
299 qDebug( "failed to write block to audio device" );
300 // emit completedIO();
301#else
302 int t = ::write( d->handle, buffer, length );
303 if ( t<0 ) t = 0;
304 if ( t != (int)length) {
305 qDebug("Ahhh!! memcpys 1");
306 memcpy(d->unwrittenBuffer,buffer+t,length-t);
307 d->unwritten = length-t;
308 }
309#endif
310}
311
312
313unsigned int AudioDevice::channels() const
314{
315 return d->channels;
316}
317
318
319unsigned int AudioDevice::frequency() const
320{
321 return d->frequency;
322}
323
324
325unsigned int AudioDevice::bytesPerSample() const
326{
327 return d->bytesPerSample;
328}
329
330
331unsigned int AudioDevice::bufferSize() const
332{
333 return d->bufferSize;
334}
335
336unsigned int AudioDevice::canWrite() const
337{
338#ifdef Q_OS_WIN32
339 return bufferSize(); // Any better?
340#else
341 audio_buf_info info;
342 if ( d->can_GETOSPACE && ioctl(d->handle,SNDCTL_DSP_GETOSPACE,&info) ) {
343 d->can_GETOSPACE = FALSE;
344 fcntl( d->handle, F_SETFL, O_NONBLOCK );
345 }
346 if ( d->can_GETOSPACE ) {
347 int t = info.fragments * sound_fragment_bytes;
348 return QMIN(t,(int)bufferSize());
349 } else {
350 if ( d->unwritten ) {
351 int t = ::write( d->handle, d->unwrittenBuffer, d->unwritten );
352 if ( t<0 ) t = 0;
353 if ( (unsigned)t!=d->unwritten ) {
354 memcpy(d->unwrittenBuffer,d->unwrittenBuffer+t,d->unwritten-t);
355 d->unwritten -= t;
356 } else {
357 d->unwritten = 0;
358 }
359 }
360 if ( d->unwritten )
361 return 0;
362 else
363 return d->bufferSize;
364 }
365#endif
366}
367
368
369int AudioDevice::bytesWritten() {
370#ifdef Q_OS_WIN32
371 MMTIME pmmt = { TIME_BYTES, 0 };
372 if ( ( waveOutGetPosition( (HWAVEOUT)d->handle, &pmmt, sizeof(MMTIME) ) != MMSYSERR_NOERROR ) || ( pmmt.wType != TIME_BYTES ) ) {
373 qDebug( "failed to get audio device position" );
374 return -1;
375 }
376 return pmmt.u.cb;
377#else
378 int buffered = 0;
379 if ( ioctl( d->handle, SNDCTL_DSP_GETODELAY, &buffered ) ) {
380 qDebug( "failed to get audio device position" );
381 return -1;
382 }
383 return buffered;
384#endif
385}
386
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef AUDIODEVICE_H
21#define AUDIODEVICE_H
22
23
24#include <qobject.h>
25
26
27class AudioDevicePrivate;
28
29
30class AudioDevice : public QObject {
31 Q_OBJECT
32public:
33 AudioDevice( unsigned int freq = 44000, unsigned int channels = 2, unsigned int bytesPerSample = 2 );
34 ~AudioDevice();
35
36 unsigned int canWrite() const;
37 void write( char *buffer, unsigned int length );
38 int bytesWritten();
39
40 unsigned int channels() const;
41 unsigned int frequency() const;
42 unsigned int bytesPerSample() const;
43 unsigned int bufferSize() const;
44
45 // Each volume level is from 0 to 0xFFFF
46 static void getVolume( unsigned int& left, unsigned int& right, bool& muted );
47 static void setVolume( unsigned int left, unsigned int right, bool muted );
48
49 static unsigned int leftVolume() { bool muted; unsigned int l, r; getVolume( l, r, muted ); return l; }
50 static unsigned int rightVolume() { bool muted; unsigned int l, r; getVolume( l, r, muted ); return r; }
51 static bool isMuted() { bool muted; unsigned int l, r; getVolume( l, r, muted ); return muted; }
52
53 static void increaseVolume() { setVolume( leftVolume() + 1968, rightVolume() + 1968, isMuted() ); }
54 static void decreaseVolume() { setVolume( leftVolume() - 1966, rightVolume() - 1966, isMuted() ); }
55
56public slots:
57 // Convinence functions derived from above functions
58 void setVolume( unsigned int level ) { setVolume( level, level, isMuted() ); }
59 void mute() { setVolume( leftVolume(), rightVolume(), TRUE ); }
60 void volumeChanged( bool muted );
61
62signals:
63 void completedIO();
64
65private:
66 AudioDevicePrivate *d;
67};
68
69
70#endif // AUDIODEVICE_H
71
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#include <qwidget.h>
21#include <qpixmap.h>
22#include <qbutton.h>
23#include <qpainter.h>
24#include <qframe.h>
25#include <qpe/resource.h>
26#include "audiowidget.h"
27#include "mediaplayerstate.h"
28
29
30extern MediaPlayerState *mediaPlayerState;
31
32
33static const int xo = -2; // movable x offset
34static const int yo = 22; // movable y offset
35
36
37struct MediaButton {
38 int xPos, yPos;
39 int color;
40 bool isToggle, isBig, isHeld, isDown;
41};
42
43
44// Layout information for the audioButtons (and if it is a toggle button or not)
45MediaButton audioButtons[] = {
46 { 3*30-15+xo, 3*30-13+yo, 0, TRUE, TRUE, FALSE, FALSE }, // play
47 { 1*30+xo, 5*30+yo, 2, FALSE, FALSE, FALSE, FALSE }, // stop
48 { 5*30+xo, 5*30+yo, 2, TRUE, FALSE, FALSE, FALSE }, // pause
49 { 6*30-5+xo, 3*30+yo, 1, FALSE, FALSE, FALSE, FALSE }, // next
50 { 0*30+5+xo, 3*30+yo, 1, FALSE, FALSE, FALSE, FALSE }, // previous
51 { 3*30+xo, 0*30+5+yo, 3, FALSE, FALSE, FALSE, FALSE }, // volume up
52 { 3*30+xo, 6*30-5+yo, 3, FALSE, FALSE, FALSE, FALSE }, // volume down
53 { 5*30+xo, 1*30+yo, 0, TRUE, FALSE, FALSE, FALSE }, // repeat/loop
54 { 1*30+xo, 1*30+yo, 0, FALSE, FALSE, FALSE, FALSE } // playlist
55};
56
57
58static const int numButtons = (sizeof(audioButtons)/sizeof(MediaButton));
59
60
61AudioWidget::AudioWidget(QWidget* parent, const char* name, WFlags f) :
62 QWidget( parent, name, f )
63{
64 setCaption( tr("MediaPlayer") );
65 setBackgroundPixmap( Resource::loadPixmap( "mpegplayer/metalFinish" ) );
66 pixmaps[0] = new QPixmap( Resource::loadPixmap( "mpegplayer/mediaButtonsAll" ) );
67 pixmaps[1] = new QPixmap( Resource::loadPixmap( "mpegplayer/mediaButtonsBig" ) );
68 pixmaps[2] = new QPixmap( Resource::loadPixmap( "mpegplayer/mediaControls" ) );
69 pixmaps[3] = new QPixmap( Resource::loadPixmap( "mpegplayer/animatedButton" ) );
70
71 songInfo = new Ticker( this );
72 songInfo->setFocusPolicy( QWidget::NoFocus );
73 songInfo->setGeometry( QRect( 7, 3, 220, 20 ) );
74
75 slider = new QSlider( Qt::Horizontal, this );
76 slider->setFixedWidth( 220 );
77 slider->setFixedHeight( 20 );
78 slider->setMinValue( 0 );
79 slider->setMaxValue( 1 );
80 slider->setBackgroundPixmap( Resource::loadPixmap( "mpegplayer/metalFinish" ) );
81 slider->setFocusPolicy( QWidget::NoFocus );
82 slider->setGeometry( QRect( 7, 262, 220, 20 ) );
83
84 connect( slider, SIGNAL( sliderPressed() ), this, SLOT( sliderPressed() ) );
85 connect( slider, SIGNAL( sliderReleased() ), this, SLOT( sliderReleased() ) );
86
87 connect( mediaPlayerState, SIGNAL( lengthChanged(long) ), this, SLOT( setLength(long) ) );
88 connect( mediaPlayerState, SIGNAL( positionChanged(long) ),this, SLOT( setPosition(long) ) );
89 connect( mediaPlayerState, SIGNAL( positionUpdated(long) ),this, SLOT( setPosition(long) ) );
90 connect( mediaPlayerState, SIGNAL( viewChanged(char) ), this, SLOT( setView(char) ) );
91 connect( mediaPlayerState, SIGNAL( loopingToggled(bool) ), this, SLOT( setLooping(bool) ) );
92 connect( mediaPlayerState, SIGNAL( pausedToggled(bool) ), this, SLOT( setPaused(bool) ) );
93 connect( mediaPlayerState, SIGNAL( playingToggled(bool) ), this, SLOT( setPlaying(bool) ) );
94
95 // Intialise state
96 setLength( mediaPlayerState->length() );
97 setPosition( mediaPlayerState->position() );
98 setLooping( mediaPlayerState->fullscreen() );
99 setPaused( mediaPlayerState->paused() );
100 setPlaying( mediaPlayerState->playing() );
101
102}
103
104
105AudioWidget::~AudioWidget() {
106 for ( int i = 0; i < 4; i++ )
107 delete pixmaps[i];
108}
109
110
111static bool audioSliderBeingMoved = FALSE;
112
113
114void AudioWidget::sliderPressed() {
115 audioSliderBeingMoved = TRUE;
116}
117
118
119void AudioWidget::sliderReleased() {
120 audioSliderBeingMoved = FALSE;
121 if ( slider->width() == 0 )
122 return;
123 long val = long((double)slider->value() * mediaPlayerState->length() / slider->width());
124 mediaPlayerState->setPosition( val );
125}
126
127
128void AudioWidget::setPosition( long i ) {
129 updateSlider( i, mediaPlayerState->length() );
130}
131
132
133void AudioWidget::setLength( long max ) {
134 updateSlider( mediaPlayerState->position(), max );
135}
136
137
138void AudioWidget::setView( char view ) {
139 if ( view == 'a' ) {
140 startTimer( 150 );
141 showMaximized();
142 } else {
143 killTimers();
144 hide();
145 }
146}
147
148
149void AudioWidget::updateSlider( long i, long max ) {
150 if ( max == 0 )
151 return;
152 // Will flicker too much if we don't do this
153 // Scale to something reasonable
154 int width = slider->width();
155 int val = int((double)i * width / max);
156 if ( !audioSliderBeingMoved ) {
157 if ( slider->value() != val )
158 slider->setValue( val );
159 if ( slider->maxValue() != width )
160 slider->setMaxValue( width );
161 }
162}
163
164
165void AudioWidget::setToggleButton( int i, bool down ) {
166 if ( down != audioButtons[i].isDown )
167 toggleButton( i );
168}
169
170
171void AudioWidget::toggleButton( int i ) {
172 audioButtons[i].isDown = !audioButtons[i].isDown;
173 QPainter p(this);
174 paintButton ( &p, i );
175}
176
177
178void AudioWidget::paintButton( QPainter *p, int i ) {
179 int x = audioButtons[i].xPos;
180 int y = audioButtons[i].yPos;
181 int offset = 22 + 14 * audioButtons[i].isBig + audioButtons[i].isDown;
182 int buttonSize = 64 + audioButtons[i].isBig * (90 - 64);
183 p->drawPixmap( x, y, *pixmaps[audioButtons[i].isBig], buttonSize * (audioButtons[i].isDown + 2 * audioButtons[i].color), 0, buttonSize, buttonSize );
184 p->drawPixmap( x + offset, y + offset, *pixmaps[2], 18 * i, 0, 18, 18 );
185}
186
187
188void AudioWidget::timerEvent( QTimerEvent * ) {
189 static int frame = 0;
190 if ( !mediaPlayerState->paused() && audioButtons[ AudioPlay ].isDown ) {
191 frame = frame >= 7 ? 0 : frame + 1;
192 int x = audioButtons[AudioPlay].xPos;
193 int y = audioButtons[AudioPlay].yPos;
194 QPainter p( this );
195 // Optimize to only draw the little bit of the changing images which is different
196 p.drawPixmap( x + 14, y + 8, *pixmaps[3], 32 * frame, 0, 32, 32 );
197 p.drawPixmap( x + 37, y + 37, *pixmaps[2], 18 * AudioPlay, 0, 6, 3 );
198 }
199}
200
201
202void AudioWidget::mouseMoveEvent( QMouseEvent *event ) {
203 for ( int i = 0; i < numButtons; i++ ) {
204 int size = audioButtons[i].isBig;
205 int x = audioButtons[i].xPos;
206 int y = audioButtons[i].yPos;
207 if ( event->state() == QMouseEvent::LeftButton ) {
208 // The test to see if the mouse click is inside the circular button or not
209 // (compared with the radius squared to avoid a square-root of our distance)
210 int radius = 32 + 13 * size;
211 QPoint center = QPoint( x + radius, y + radius );
212 QPoint dXY = center - event->pos();
213 int dist = dXY.x() * dXY.x() + dXY.y() * dXY.y();
214 bool isOnButton = dist <= (radius * radius);
215 // QRect r( x, y, 64 + 22*size, 64 + 22*size );
216 // bool isOnButton = r.contains( event->pos() ); // Rectangular Button code
217 if ( isOnButton && !audioButtons[i].isHeld ) {
218 audioButtons[i].isHeld = TRUE;
219 toggleButton(i);
220 switch (i) {
221 case AudioVolumeUp: emit moreClicked(); return;
222 case AudioVolumeDown: emit lessClicked(); return;
223 }
224 } else if ( !isOnButton && audioButtons[i].isHeld ) {
225 audioButtons[i].isHeld = FALSE;
226 toggleButton(i);
227 }
228 } else {
229 if ( audioButtons[i].isHeld ) {
230 audioButtons[i].isHeld = FALSE;
231 if ( !audioButtons[i].isToggle )
232 setToggleButton( i, FALSE );
233 switch (i) {
234 case AudioPlay: mediaPlayerState->setPlaying(audioButtons[i].isDown); return;
235 case AudioStop: mediaPlayerState->setPlaying(FALSE); return;
236 case AudioPause: mediaPlayerState->setPaused(audioButtons[i].isDown); return;
237 case AudioNext: mediaPlayerState->setNext(); return;
238 case AudioPrevious: mediaPlayerState->setPrev(); return;
239 case AudioLoop: mediaPlayerState->setLooping(audioButtons[i].isDown); return;
240 case AudioVolumeUp: emit moreReleased(); return;
241 case AudioVolumeDown: emit lessReleased(); return;
242 case AudioPlayList: mediaPlayerState->setList(); return;
243 }
244 }
245 }
246 }
247}
248
249
250void AudioWidget::mousePressEvent( QMouseEvent *event ) {
251 mouseMoveEvent( event );
252}
253
254
255void AudioWidget::mouseReleaseEvent( QMouseEvent *event ) {
256 mouseMoveEvent( event );
257}
258
259
260void AudioWidget::showEvent( QShowEvent* ) {
261 QMouseEvent event( QEvent::MouseMove, QPoint( 0, 0 ), 0, 0 );
262 mouseMoveEvent( &event );
263}
264
265
266void AudioWidget::closeEvent( QCloseEvent* ) {
267 mediaPlayerState->setList();
268}
269
270
271void AudioWidget::paintEvent( QPaintEvent * ) {
272 QPainter p( this );
273 for ( int i = 0; i < numButtons; i++ )
274 paintButton( &p, i );
275}
276
277
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef AUDIO_WIDGET_H
21#define AUDIO_WIDGET_H
22
23
24#include <qwidget.h>
25#include <qpainter.h>
26#include <qdrawutil.h>
27#include <qpixmap.h>
28#include <qstring.h>
29#include <qslider.h>
30#include <qframe.h>
31
32
33class QPixmap;
34
35
36enum AudioButtons {
37 AudioPlay,
38 AudioStop,
39 AudioPause,
40 AudioNext,
41 AudioPrevious,
42 AudioVolumeUp,
43 AudioVolumeDown,
44 AudioLoop,
45 AudioPlayList
46};
47
48
49#define USE_DBLBUF
50
51
52class Ticker : public QFrame {
53 Q_OBJECT
54public:
55 Ticker( QWidget* parent=0 ) : QFrame( parent ) {
56 setFrameStyle( WinPanel | Sunken );
57 setText( "No Song" );
58 }
59 ~Ticker() { }
60 void setText( const QString& text ) {
61 pos = 0; // reset it everytime the text is changed
62 scrollText = text;
63 pixelLen = fontMetrics().width( scrollText );
64 killTimers();
65 if ( pixelLen > width() )
66 startTimer( 50 );
67 update();
68 }
69protected:
70 void timerEvent( QTimerEvent * ) {
71 pos = ( pos + 1 > pixelLen ) ? 0 : pos + 1;
72#ifndef USE_DBLBUF
73 scroll( -1, 0, contentsRect() );
74#else
75 repaint( FALSE );
76#endif
77 }
78 void drawContents( QPainter *p ) {
79#ifndef USE_DBLBUF
80 for ( int i = 0; i - pos < width() && (i < 1 || pixelLen > width()); i += pixelLen )
81 p->drawText( i - pos, 0, INT_MAX, height(), AlignVCenter, scrollText );
82#else
83 // Double buffering code.
84 // Looks like qvfb makes it look like it flickers but I don't think it really is
85 QPixmap pm( width(), height() );
86 pm.fill( colorGroup().base() );
87 QPainter pmp( &pm );
88 for ( int i = 0; i - pos < width() && (i < 1 || pixelLen > width()); i += pixelLen )
89 pmp.drawText( i - pos, 0, INT_MAX, height(), AlignVCenter, scrollText );
90 p->drawPixmap( 0, 0, pm );
91#endif
92 }
93private:
94 QString scrollText;
95 int pos, pixelLen;
96};
97
98
99class AudioWidget : public QWidget {
100 Q_OBJECT
101public:
102 AudioWidget( QWidget* parent=0, const char* name=0, WFlags f=0 );
103 ~AudioWidget();
104 void setTickerText( const QString &text ) { songInfo->setText( text ); }
105
106public slots:
107 void updateSlider( long, long );
108 void sliderPressed( );
109 void sliderReleased( );
110 void setPaused( bool b) { setToggleButton( AudioPause, b ); }
111 void setLooping( bool b) { setToggleButton( AudioLoop, b ); }
112 void setPlaying( bool b) { setToggleButton( AudioPlay, b ); }
113 void setPosition( long );
114 void setLength( long );
115 void setView( char );
116
117signals:
118 void moreClicked();
119 void lessClicked();
120 void moreReleased();
121 void lessReleased();
122 void sliderMoved(long);
123
124protected:
125 void paintEvent( QPaintEvent *pe );
126 void showEvent( QShowEvent *se );
127 void mouseMoveEvent( QMouseEvent *event );
128 void mousePressEvent( QMouseEvent *event );
129 void mouseReleaseEvent( QMouseEvent *event );
130 void timerEvent( QTimerEvent *event );
131 void closeEvent( QCloseEvent *event );
132
133private:
134 void toggleButton( int );
135 void setToggleButton( int, bool );
136 void paintButton( QPainter *p, int i );
137 QPixmap *pixmaps[4];
138 Ticker *songInfo;
139 QSlider *slider;
140};
141
142
143#endif // AUDIO_WIDGET_H
144
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 @@
1#############################################################################
2
3####### Compiler, tools and options
4
5 CXX =$(SYSCONF_CXX) $(QT_CXX_MT)
6 CXXFLAGS=$(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS) $(SYSCONF_CXXFLAGS_LIB)
7 CC =$(SYSCONF_CC) $(QT_C_MT)
8 CFLAGS =$(SYSCONF_CFLAGS) $(SYSCONF_CFLAGS_LIB)
9 INCPATH =-I$(QPEDIR)/include
10 LFLAGS =$(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
11 LIBS =$(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS_QTAPP)
12 MOC =$(SYSCONF_MOC)
13 UIC =$(SYSCONF_UIC)
14
15####### Target
16
17DESTDIR = ../../plugins/codecs/
18VER_MAJ = 1
19VER_MIN = 0
20VER_PATCH = 0
21 TARGET= flashplugin
22TARGET1 = lib$(TARGET).so.$(VER_MAJ)
23
24####### Files
25
26 HEADERS =libflashplugin.h \
27 libflashpluginimpl.h
28 SOURCES =libflashplugin.cpp \
29 libflashpluginimpl.cpp \
30 adpcm.cc \
31 character.cc \
32 flash.cc \
33 graphic16.cc \
34 matrix.cc \
35 script.cc \
36 sprite.cc \
37 bitmap.cc \
38 cxform.cc \
39 font.cc \
40 graphic24.cc \
41 movie.cc \
42 shape.cc \
43 sqrt.cc \
44 button.cc \
45 displaylist.cc \
46 graphic.cc \
47 graphic32.cc \
48 program.cc \
49 sound.cc \
50 text.cc
51 OBJECTS =libflashplugin.o \
52 libflashpluginimpl.o \
53 adpcm.o \
54 character.o \
55 flash.o \
56 graphic16.o \
57 matrix.o \
58 script.o \
59 sprite.o \
60 bitmap.o \
61 cxform.o \
62 font.o \
63 graphic24.o \
64 movie.o \
65 shape.o \
66 sqrt.o \
67 button.o \
68 displaylist.o \
69 graphic.o \
70 graphic32.o \
71 program.o \
72 sound.o \
73 text.o
74INTERFACES =
75UICDECLS =
76UICIMPLS =
77 SRCMOC =
78 OBJMOC =
79
80
81####### Implicit rules
82
83.SUFFIXES: .cpp .cxx .cc .C .c
84
85.cpp.o:
86 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
87
88.cxx.o:
89 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
90
91.cc.o:
92 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
93
94.C.o:
95 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
96
97.c.o:
98 $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
99
100####### Build rules
101
102
103all: $(DESTDIR)$(SYSCONF_LINK_TARGET)
104
105$(DESTDIR)$(SYSCONF_LINK_TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
106 $(SYSCONF_LINK_LIB)
107
108moc: $(SRCMOC)
109
110tmake: Makefile.in
111
112Makefile.in: libflash.pro
113 tmake libflash.pro -o Makefile.in
114
115clean:
116 -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
117 -rm -f *~ core
118 -rm -f allmoc.cpp
119
120####### Extension Modules
121
122listpromodules:
123 @echo
124
125listallmodules:
126 @echo
127
128listaddonpromodules:
129 @echo
130
131listaddonentmodules:
132 @echo
133
134
135REQUIRES=
136
137####### Sub-libraries
138
139
140###### Combined headers
141
142
143
144####### Compile
145
146libflashplugin.o: libflashplugin.cpp \
147 libflashplugin.h \
148 flash.h \
149 ../mediaplayerplugininterface.h
150
151libflashpluginimpl.o: libflashpluginimpl.cpp \
152 libflashplugin.h \
153 flash.h \
154 ../mediaplayerplugininterface.h \
155 libflashpluginimpl.h \
156 ../mediaplayerplugininterface.h
157
158adpcm.o: adpcm.cc \
159 swf.h \
160 flash.h \
161 matrix.h \
162 cxform.h \
163 rect.h \
164 jpeglib.h \
165 jconfig.h \
166 jmorecfg.h \
167 jerror.h \
168 graphic.h \
169 character.h \
170 bitmap.h \
171 shape.h \
172 displaylist.h \
173 sound.h \
174 button.h \
175 font.h \
176 text.h \
177 adpcm.h \
178 program.h \
179 sprite.h \
180 script.h \
181 movie.h
182
183character.o: character.cc \
184 swf.h \
185 flash.h \
186 matrix.h \
187 cxform.h \
188 rect.h \
189 jpeglib.h \
190 jconfig.h \
191 jmorecfg.h \
192 jerror.h \
193 graphic.h \
194 character.h \
195 bitmap.h \
196 shape.h \
197 displaylist.h \
198 sound.h \
199 button.h \
200 font.h \
201 text.h \
202 adpcm.h \
203 program.h \
204 sprite.h \
205 script.h \
206 movie.h
207
208flash.o: flash.cc \
209 swf.h \
210 flash.h \
211 matrix.h \
212 cxform.h \
213 rect.h \
214 jpeglib.h \
215 jconfig.h \
216 jmorecfg.h \
217 jerror.h \
218 graphic.h \
219 character.h \
220 bitmap.h \
221 shape.h \
222 displaylist.h \
223 sound.h \
224 button.h \
225 font.h \
226 text.h \
227 adpcm.h \
228 program.h \
229 sprite.h \
230 script.h \
231 movie.h \
232 graphic16.h \
233 graphic24.h \
234 graphic32.h
235
236graphic16.o: graphic16.cc \
237 swf.h \
238 flash.h \
239 matrix.h \
240 cxform.h \
241 rect.h \
242 jpeglib.h \
243 jconfig.h \
244 jmorecfg.h \
245 jerror.h \
246 graphic.h \
247 character.h \
248 bitmap.h \
249 shape.h \
250 displaylist.h \
251 sound.h \
252 button.h \
253 font.h \
254 text.h \
255 adpcm.h \
256 program.h \
257 sprite.h \
258 script.h \
259 movie.h \
260 graphic16.h
261
262matrix.o: matrix.cc \
263 matrix.h
264
265script.o: script.cc \
266 swf.h \
267 flash.h \
268 matrix.h \
269 cxform.h \
270 rect.h \
271 jpeglib.h \
272 jconfig.h \
273 jmorecfg.h \
274 jerror.h \
275 graphic.h \
276 character.h \
277 bitmap.h \
278 shape.h \
279 displaylist.h \
280 sound.h \
281 button.h \
282 font.h \
283 text.h \
284 adpcm.h \
285 program.h \
286 sprite.h \
287 script.h \
288 movie.h
289
290sprite.o: sprite.cc \
291 swf.h \
292 flash.h \
293 matrix.h \
294 cxform.h \
295 rect.h \
296 jpeglib.h \
297 jconfig.h \
298 jmorecfg.h \
299 jerror.h \
300 graphic.h \
301 character.h \
302 bitmap.h \
303 shape.h \
304 displaylist.h \
305 sound.h \
306 button.h \
307 font.h \
308 text.h \
309 adpcm.h \
310 program.h \
311 sprite.h \
312 script.h \
313 movie.h
314
315bitmap.o: bitmap.cc \
316 swf.h \
317 flash.h \
318 matrix.h \
319 cxform.h \
320 rect.h \
321 jpeglib.h \
322 jconfig.h \
323 jmorecfg.h \
324 jerror.h \
325 graphic.h \
326 character.h \
327 bitmap.h \
328 shape.h \
329 displaylist.h \
330 sound.h \
331 button.h \
332 font.h \
333 text.h \
334 adpcm.h \
335 program.h \
336 sprite.h \
337 script.h \
338 movie.h
339
340cxform.o: cxform.cc \
341 swf.h \
342 flash.h \
343 matrix.h \
344 cxform.h \
345 rect.h \
346 jpeglib.h \
347 jconfig.h \
348 jmorecfg.h \
349 jerror.h \
350 graphic.h \
351 character.h \
352 bitmap.h \
353 shape.h \
354 displaylist.h \
355 sound.h \
356 button.h \
357 font.h \
358 text.h \
359 adpcm.h \
360 program.h \
361 sprite.h \
362 script.h \
363 movie.h
364
365font.o: font.cc \
366 swf.h \
367 flash.h \
368 matrix.h \
369 cxform.h \
370 rect.h \
371 jpeglib.h \
372 jconfig.h \
373 jmorecfg.h \
374 jerror.h \
375 graphic.h \
376 character.h \
377 bitmap.h \
378 shape.h \
379 displaylist.h \
380 sound.h \
381 button.h \
382 font.h \
383 text.h \
384 adpcm.h \
385 program.h \
386 sprite.h \
387 script.h \
388 movie.h
389
390graphic24.o: graphic24.cc \
391 swf.h \
392 flash.h \
393 matrix.h \
394 cxform.h \
395 rect.h \
396 jpeglib.h \
397 jconfig.h \
398 jmorecfg.h \
399 jerror.h \
400 graphic.h \
401 character.h \
402 bitmap.h \
403 shape.h \
404 displaylist.h \
405 sound.h \
406 button.h \
407 font.h \
408 text.h \
409 adpcm.h \
410 program.h \
411 sprite.h \
412 script.h \
413 movie.h \
414 graphic24.h
415
416movie.o: movie.cc \
417 movie.h \
418 swf.h \
419 flash.h \
420 matrix.h \
421 cxform.h \
422 rect.h \
423 jpeglib.h \
424 jconfig.h \
425 jmorecfg.h \
426 jerror.h \
427 graphic.h \
428 character.h \
429 bitmap.h \
430 shape.h \
431 displaylist.h \
432 sound.h \
433 button.h \
434 font.h \
435 text.h \
436 adpcm.h \
437 program.h \
438 sprite.h \
439 script.h
440
441shape.o: shape.cc \
442 swf.h \
443 flash.h \
444 matrix.h \
445 cxform.h \
446 rect.h \
447 jpeglib.h \
448 jconfig.h \
449 jmorecfg.h \
450 jerror.h \
451 graphic.h \
452 character.h \
453 bitmap.h \
454 shape.h \
455 displaylist.h \
456 sound.h \
457 button.h \
458 font.h \
459 text.h \
460 adpcm.h \
461 program.h \
462 sprite.h \
463 script.h \
464 movie.h
465
466sqrt.o: sqrt.cc
467
468button.o: button.cc \
469 swf.h \
470 flash.h \
471 matrix.h \
472 cxform.h \
473 rect.h \
474 jpeglib.h \
475 jconfig.h \
476 jmorecfg.h \
477 jerror.h \
478 graphic.h \
479 character.h \
480 bitmap.h \
481 shape.h \
482 displaylist.h \
483 sound.h \
484 button.h \
485 font.h \
486 text.h \
487 adpcm.h \
488 program.h \
489 sprite.h \
490 script.h \
491 movie.h
492
493displaylist.o: displaylist.cc \
494 swf.h \
495 flash.h \
496 matrix.h \
497 cxform.h \
498 rect.h \
499 jpeglib.h \
500 jconfig.h \
501 jmorecfg.h \
502 jerror.h \
503 graphic.h \
504 character.h \
505 bitmap.h \
506 shape.h \
507 displaylist.h \
508 sound.h \
509 button.h \
510 font.h \
511 text.h \
512 adpcm.h \
513 program.h \
514 sprite.h \
515 script.h \
516 movie.h
517
518graphic.o: graphic.cc \
519 swf.h \
520 flash.h \
521 matrix.h \
522 cxform.h \
523 rect.h \
524 jpeglib.h \
525 jconfig.h \
526 jmorecfg.h \
527 jerror.h \
528 graphic.h \
529 character.h \
530 bitmap.h \
531 shape.h \
532 displaylist.h \
533 sound.h \
534 button.h \
535 font.h \
536 text.h \
537 adpcm.h \
538 program.h \
539 sprite.h \
540 script.h \
541 movie.h
542
543graphic32.o: graphic32.cc \
544 swf.h \
545 flash.h \
546 matrix.h \
547 cxform.h \
548 rect.h \
549 jpeglib.h \
550 jconfig.h \
551 jmorecfg.h \
552 jerror.h \
553 graphic.h \
554 character.h \
555 bitmap.h \
556 shape.h \
557 displaylist.h \
558 sound.h \
559 button.h \
560 font.h \
561 text.h \
562 adpcm.h \
563 program.h \
564 sprite.h \
565 script.h \
566 movie.h \
567 graphic32.h
568
569program.o: program.cc \
570 swf.h \
571 flash.h \
572 matrix.h \
573 cxform.h \
574 rect.h \
575 jpeglib.h \
576 jconfig.h \
577 jmorecfg.h \
578 jerror.h \
579 graphic.h \
580 character.h \
581 bitmap.h \
582 shape.h \
583 displaylist.h \
584 sound.h \
585 button.h \
586 font.h \
587 text.h \
588 adpcm.h \
589 program.h \
590 sprite.h \
591 script.h \
592 movie.h
593
594sound.o: sound.cc \
595 swf.h \
596 flash.h \
597 matrix.h \
598 cxform.h \
599 rect.h \
600 jpeglib.h \
601 jconfig.h \
602 jmorecfg.h \
603 jerror.h \
604 graphic.h \
605 character.h \
606 bitmap.h \
607 shape.h \
608 displaylist.h \
609 sound.h \
610 button.h \
611 font.h \
612 text.h \
613 adpcm.h \
614 program.h \
615 sprite.h \
616 script.h \
617 movie.h
618
619text.o: text.cc \
620 swf.h \
621 flash.h \
622 matrix.h \
623 cxform.h \
624 rect.h \
625 jpeglib.h \
626 jconfig.h \
627 jmorecfg.h \
628 jerror.h \
629 graphic.h \
630 character.h \
631 bitmap.h \
632 shape.h \
633 displaylist.h \
634 sound.h \
635 button.h \
636 font.h \
637 text.h \
638 adpcm.h \
639 program.h \
640 sprite.h \
641 script.h \
642 movie.h
643
644
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 @@
1
2MODIFICATIONS BY TROLLTECH
3--------------------------
4
5Oct. 2001
6
7Just the Lib directory of the flash library source archive
8has been copied in to the QPE CVS tree. For the full source code
9to create a KDE screensaver or stand alone player etc, download
10the orginal source tar ball from http://www.swift-tools.com/Flash
11The files libflashplugin* have been added to wrapper the library
12to produce a Qtopia Media Player plugin out of the code.
13
14John R.
15
16
17INTRODUCTION
18------------
19
20Jun. 12th 2000
21
22This the Version 0.4.10 of the Flash Library for Linux.
23
24Flash Plugin is under GPL, see COPYING file.
25
26Provides:
27- Lib contains the FlashLib sources.
28- Plugin contains plugin sources.
29- Player contains the standalone player sources.
30- Kflash a Flash KDE screen saver.
31
32New features:
33- Bug fixes.
34- 24 and 32 modes supported.
35- Flash Library as screen saver (for xcreensaver and KDE).
36
37To get some information on this library check out the following link :
38http://www.swift-tools.com/Flash
39
40 Authors:Olivier Debon <odebon@club-internet.fr>
41 Fabrice Bellard <fabrice.bellard@netgem.com>
42
43FEATURES
44--------
45
46Limitations :
47 - The plugin and the player use XShm extensions, so remote display is not possible.
48 - No Flash 4 features (but no crash on Flash 4 files).
49
50Not functional :
51 - No Morphing.
52 - No vertical anti-aliasing.
53
54SOUND SUPPORT
55-------------
56
57Limitations :
58 - No streamed sound supported (interleaved data).
59 - No sound envelop. So no fading or balancing effect.
60
61But the main feature is here and sound can be enjoyed.
62
63I recommend OSS drivers, but it is not required at all
64(http://www.opensound.com)
65
66If you have troubles with sound put the -DNOSOUND option
67for compilation. Also do this for non-Linux Unix.
68
69THE PLAYER
70----------
71
72The standalone player can simply control movie by
73pressing Q to quit, P to pause, C to continue and
74R to replay.
75There is also the possibility to zoom in or out
76and scroll using Keypad +/- and cursor keys, but
77it is buggy on frozen images.
78
79THE SCREEN SAVERS
80-----------------
81
82The standalone player can be run though xscreensaver. Modify
83your .xscreensaver file to add swfplayer:
84programs: swfplayer -root /home/olivier/Flash/Test/test.swf
85(See xscreensaver doc for more details on Xscreensaver).
86
87For KDE, just install the kflash.kss file from the Kflash
88directory in /usr/bin (or where your KDE installation expects
89kss file to be).
90In your KDE start menu, select Settings->Desktop->Screensaver
91Choose 'Flash Movies' and click on SetUp button. You'll have
92to select a Flash file (take the test.swf file provided with
93this distribution). The fullscreen option will scale the movie
94to the entire screen (it can be very CPU intensive). The
95enable sound option will allow to play sounds, but as a screen
96saver mode this is not a good idea :)
97
98BUG REPORT
99----------
100
101If Netscape crashes when it started to play a Flash file, please
102report the complete url where you have found the file.
103Do not send the actual file !
104
105If you have rendering problem also report the url.
106
107If the plugin does not seem to show anything or does not do what it
108is supposed to do, please consider that the plugin does not support
109all Flash 2/4 features. Anyway it tries to play it but may fail then.
110
111COMPILATION
112-----------
113
114If you use Linux just type 'make'.
115
116Warning : the plugin compilation should not fail, but you may
117have problem with Netscape at startup. See INSTALLATION section
118for workarounds.
119
120For other Unices like FreeBSD or Solaris you may have to change
121some flags. See Plugin/Makefile for hints.
122
123INSTALLATION
124------------
125
126Once you have successfully compiled the plugin, put the file
127npflash.so (located in the Plugin directory) into your
128~/.netscape/plugins directory or into the system-wide
129/opt/netscape/plugins directory (depends on where you have installed
130Netscape).
131
132If Netscape already runs type 'javascript:navigator.plugins.refresh'
133in the Location field.
134
135 PROBLEMS
136 --------
137
138If you have problem to successfully install the plugin, please
139read the following hints. Otherwise, report the problem with full
140description of your configuration :
141- Distribution.
142- Compiler.
143- Libs (the output of ldconfig -p is useful).
144- The netscape version and the output of 'ldd netscape'.
145
146If some symbols like _rtti or _throw are unresolved, it seems
147that you have egcs. Just uncomment the proper line in the main
148Makefile.
149You may then still have some unresolved symbols like __sigsetjmp.
150This time, add -DC6R5 in the Plugin/Makefile at the PLUGIN_DEFINES
151line.
152
153 CHECKING
154 --------
155
156To verify that the plugin is installed properly, type "about:plugins"
157in Netscape's "Location:" or "Netsite:" field. The plugin should show
158up there, something like
159
160___________________________________________________________________________
161
162 Shockwave Flash
163
164 File name: /opt/netscape/plugins/npflash.so
165
166 Flash file player Version 0.4.10
167
168 Shockwave is a trademark of Macromedia®
169
170 Author: Olivier Debon
171
172 ---------------------------------------------------------------------------------
173| Mime Type | Description | Suffixes | Enabled |
174|--------------------------------+-------------------+-------------+--------------|
175| application/futuresplash | Flash Plugin | spl | Yes |
176| application/x-shockwave-flash | | swf | Yes |
177 ---------------------------------------------------------------------------------
178
179___________________________________________________________________________
180
181
182If it shows up, but the "Enabled" column says "No", you need to
183configure the Flash plugin as a helper application. Go to
184Edit/Preferences/Navigator/Applications, and add it as follows:
185
186Description: Flash Plugin
187MIME Type: application/x-shockwave-flash
188Suffixes: swf
189Handled By: Plug In (select "Shockwave Flash")
190
191------
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 @@
1
2#include "swf.h"
3
4#ifdef RCSID
5static char *rcsid = "$Id$";
6#endif
7
8// This file has been rearranged from the code posted
9// on news:forums.macromedia.com by Jonathan Gay.
10// Courtesy of Macromedia
11
12//
13// ADPCM tables
14//
15
16static const int indexTable2[2] = {
17 -1, 2,
18};
19
20// Is this ok?
21static const int indexTable3[4] = {
22 -1, -1, 2, 4,
23};
24
25static const int indexTable4[8] = {
26 -1, -1, -1, -1, 2, 4, 6, 8,
27};
28
29static const int indexTable5[16] = {
30 -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 4, 6, 8, 10, 13, 16,
31};
32
33static const int* indexTables[] = {
34 indexTable2,
35 indexTable3,
36 indexTable4,
37 indexTable5
38};
39
40static const int stepsizeTable[89] = {
41 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
42 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
43 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
44 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
45 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
46 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
47 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
48 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
49 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
50};
51
52long
53Adpcm::GetBits(int n)
54{
55 if ( bitPos < n ) FillBuffer();
56
57 assert(bitPos >= n);
58
59 long v = ((unsigned long)bitBuf << (32-bitPos)) >> (32-n);
60 bitPos -= n;
61
62 return v;
63}
64
65long
66Adpcm::GetSBits(int n)
67{
68 if ( bitPos < n ) FillBuffer();
69
70 assert(bitPos >= n);
71
72 long v = ((long)bitBuf << (32-bitPos)) >> (32-n);
73 bitPos -= n;
74
75 return v;
76}
77
78//
79// The Decompressor
80//
81
82// Constructor
83Adpcm::Adpcm(unsigned char *buffer, long isStereo)
84{
85 stereo = isStereo;
86 src = buffer;
87
88 nBits = 0; // flag that it is not inited
89 nSamples = 0;
90
91 bitPos = 0;
92 bitBuf = 0;
93}
94
95void
96Adpcm::FillBuffer()
97{
98 while ( bitPos <= 24 /*&& srcSize > 0*/ ) {
99 bitBuf = (bitBuf<<8) | *src++;
100 bitPos += 8;
101 }
102}
103
104void
105Adpcm::Decompress(short *dst, long n)
106{
107 if ( nBits == 0 ) {
108 // Get the compression header
109 nBits = (int)GetBits(2)+2;
110 }
111
112 const int* indexTable = indexTables[nBits-2];
113 int k0 = 1 << (nBits-2);
114 int signmask = 1 << (nBits-1);
115
116 if ( !stereo ) {
117 // Optimize for mono
118 long vp = valpred[0]; // maybe these can get into registers...
119 int ind = index[0];
120 long ns = nSamples;
121
122 while ( n-- > 0 ) {
123 ns++;
124
125 if ( (ns & 0xFFF) == 1 ) {
126 // Get a new block header
127 *dst++ = (short)(vp = GetSBits(16));
128
129 ind = (int)GetBits(6); // The first sample in a block does not have a delta
130 } else {
131 // Process a delta value
132 int delta = (int)GetBits(nBits);
133
134 // Compute difference and new predicted value
135 // Computes 'vpdiff = (delta+0.5)*step/4'
136 int step = stepsizeTable[ind];
137 long vpdiff = 0;
138 int k = k0;
139
140 do {
141 if ( delta & k )
142 vpdiff += step;
143 step >>= 1;
144 k >>= 1;
145 } while ( k );
146
147 vpdiff += step; // add 0.5
148
149 if ( delta & signmask ) // the sign bit
150 vp -= vpdiff;
151 else
152 vp += vpdiff;
153
154 // Find new index value
155 ind += indexTable[delta&(~signmask)];
156
157 if ( ind < 0 )
158 ind = 0;
159 else if ( ind > 88 )
160 ind = 88;
161
162 // clamp output value
163 if ( vp != (short)vp )
164 vp = vp < 0 ? -32768 : 32767;
165
166 /* Step 7 - Output value */
167 *dst++ = (short)vp;
168 }
169 }
170
171 valpred[0] = vp;
172 index[0] = ind;
173 nSamples = ns;
174
175 } else {
176 int sn = stereo ? 2 : 1;
177
178 // Stereo
179 while ( n-- > 0 ) {
180
181 nSamples++;
182
183 if ( (nSamples & 0xFFF) == 1 ) {
184 // Get a new block header
185 for ( int i = 0; i < sn; i++ ) {
186
187 *dst++ = (short)(valpred[i] = GetSBits(16));
188
189 // The first sample in a block does not have a delta
190 index[i] = (int)GetBits(6);
191 }
192 } else {
193 // Process a delta value
194 for ( int i = 0; i < sn; i++ ) {
195 int delta = (int)GetBits(nBits);
196
197 // Compute difference and new predicted value
198 // Computes 'vpdiff = (delta+0.5)*step/4'
199
200 int step = stepsizeTable[index[i]];
201 long vpdiff = 0;
202 int k = k0;
203
204 do {
205 if ( delta & k ) vpdiff += step;
206 step >>= 1;
207 k >>= 1;
208 } while ( k );
209 vpdiff += step; // add 0.5
210
211
212 if ( delta & signmask ) // the sign bit
213 valpred[i] -= vpdiff;
214 else
215 valpred[i] += vpdiff;
216
217 // Find new index value
218 index[i] += indexTable[delta&(~signmask)];
219
220 if ( index[i] < 0 )
221 index[i] = 0;
222 else if ( index[i] > 88 )
223 index[i] = 88;
224
225 // clamp output value
226 if ( valpred[i] != (short)valpred[i] )
227 valpred[i] = valpred[i] < 0 ? -32768 : 32767;
228
229 /* Step 7 - Output value */
230 *dst++ = (short)valpred[i];
231 }
232 }
233 }
234 }
235}
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 @@
1#ifndef _ADPCM_H_
2#define _ADPCM_H_
3
4class Adpcm {
5
6 // Destination format - note we always decompress to 16 bit
7 long stereo;
8 int nBits; // number of bits in each sample
9
10 long valpred[2]; // Current state
11 int index[2];
12
13 long nSamples; // number of samples decompressed so far
14
15 // Parsing Info
16 unsigned char *src;
17 long bitBuf; // this should always contain at least 24 bits of data
18 int bitPos;
19
20 void FillBuffer();
21
22 long GetBits(int n);
23
24 long GetSBits(int n);
25
26public:
27 Adpcm(unsigned char *buffer, long isStereo);
28
29 void Decompress(short * dst, long n); // return number of good samples
30#ifdef DUMP
31 void dump(BitStream *bs);
32 void Compress(short *pcm, long n, int bits);
33#endif
34};
35
36#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 @@
1/////////////////////////////////////////////////////////////
2// Flash Plugin and Player
3// Copyright (C) 1998 Olivier Debon
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19///////////////////////////////////////////////////////////////
20// Author : Olivier Debon <odebon@club-internet.fr>
21//
22
23#include "swf.h"
24
25#ifdef RCSID
26static char *rcsid = "$Id$";
27#endif
28
29static unsigned char *inputData;
30
31// Class variables
32
33int Bitmap::haveTables = 0;
34
35struct jpeg_decompress_struct Bitmap::jpegObject;
36
37struct jpeg_source_mgr Bitmap::jpegSourceManager;
38
39MyErrorHandler Bitmap::jpegErrorMgr;
40
41Bitmap::Bitmap(long id, int level) : Character(BitmapType, id )
42{
43 pixels = NULL;
44 alpha_buf = NULL;
45 colormap = NULL;
46 nbColors = 0;
47 defLevel = level;
48}
49
50Bitmap::~Bitmap()
51{
52 if (pixels) {
53 delete[] pixels;
54 }
55 if (alpha_buf) {
56 delete[] alpha_buf;
57 }
58 if (colormap)
59 {
60 delete colormap;
61 }
62 if (haveTables) {
63 jpeg_destroy_decompress(&jpegObject);
64 haveTables = 0;
65 }
66}
67
68static void errorExit(j_common_ptr info)
69{
70 (*info->err->output_message) (info);
71 longjmp(((MyErrorHandler *)info->err)->setjmp_buffer, 1);
72}
73
74// Methods for Source data manager
75static void initSource(struct jpeg_decompress_struct *cInfo)
76{
77 cInfo->src->bytes_in_buffer = 0;
78}
79
80static boolean fillInputBuffer(struct jpeg_decompress_struct *cInfo)
81{
82 cInfo->src->next_input_byte = inputData;
83 cInfo->src->bytes_in_buffer = 1;
84 inputData++;
85
86 return 1;
87}
88
89static void skipInputData(struct jpeg_decompress_struct *cInfo, long count)
90{
91 cInfo->src->bytes_in_buffer = 0;
92 inputData += count;
93}
94
95static boolean resyncToRestart(struct jpeg_decompress_struct *cInfo, int desired)
96{
97 return jpeg_resync_to_restart(cInfo, desired);
98}
99
100static void termSource(struct jpeg_decompress_struct *cInfo)
101{
102}
103
104long Bitmap::getWidth()
105{
106 return width;
107}
108
109long Bitmap::getHeight()
110{
111 return height;
112}
113
114Color *
115Bitmap::getColormap(long *n) {
116 if (n) *n = nbColors;
117 return colormap;
118}
119
120unsigned char *
121Bitmap::getPixels()
122{
123 return pixels;
124}
125
126// Read Tables and Compressed data to produce an image
127
128static int
129buildJpegAlpha(Bitmap *b, unsigned char *buffer)
130{
131 z_streamstream;
132 int status;
133 unsigned char *data;
134
135 data = new unsigned char[b->width*b->height];
136 if (data == NULL)
137 return -1;
138
139 stream.next_in = buffer;
140 stream.avail_in = 1;
141 stream.next_out = data;
142 stream.avail_out = b->width*b->height;
143 stream.zalloc = Z_NULL;
144 stream.zfree = Z_NULL;
145
146 status = inflateInit(&stream);
147
148 while (1) {
149 status = inflate(&stream, Z_SYNC_FLUSH) ;
150 if (status == Z_STREAM_END) {
151 break;
152 }
153 if (status != Z_OK) {
154 printf("Zlib data error : %s\n", stream.msg);
155 delete data;
156 return -1;
157 }
158 stream.avail_in = 1;
159 }
160
161 inflateEnd(&stream);
162
163 b->alpha_buf = data;
164
165 return 0;
166}
167
168int
169Bitmap::buildFromJpegInterchangeData(unsigned char *stream, int read_alpha, long offset)
170{
171 struct jpeg_decompress_struct cInfo;
172 struct jpeg_source_mgr mySrcMgr;
173 MyErrorHandler errorMgr;
174 JSAMPROW buffer[1];
175 unsigned char *ptrPix;
176 int stride;
177 long n;
178
179#if PRINT&1
180 printf("flash: loading jpeg (interchange)\n");
181#endif
182
183 // Kludge to correct some corrupted files
184 if (stream[1] == 0xd9 && stream[3] == 0xd8) {
185 stream[3] = 0xd9;
186 stream[1] = 0xd8;
187 }
188
189 // Setup error handler
190 cInfo.err = jpeg_std_error(&errorMgr.pub);
191 errorMgr.pub.error_exit = errorExit;
192
193 if (setjmp(errorMgr.setjmp_buffer)) {
194 // JPEG data Error
195 jpeg_destroy_decompress(&cInfo);
196 if (pixels) {
197 delete[] pixels;
198 pixels = NULL;
199 }
200 return -1;
201 }
202
203 // Set current stream pointer to stream
204 inputData = stream;
205
206 // Here it's Ok
207
208 jpeg_create_decompress(&cInfo);
209
210 // Setup source manager structure
211 mySrcMgr.init_source = initSource;
212 mySrcMgr.fill_input_buffer = fillInputBuffer;
213 mySrcMgr.skip_input_data = skipInputData;
214 mySrcMgr.resync_to_restart = resyncToRestart;
215 mySrcMgr.term_source = termSource;
216
217 // Set default source manager
218 cInfo.src = &mySrcMgr;
219
220 jpeg_read_header(&cInfo, FALSE);
221
222 jpeg_read_header(&cInfo, TRUE);
223 cInfo.quantize_colors = TRUE;// Create colormapped image
224 jpeg_start_decompress(&cInfo);
225
226 // Set objet dimensions
227 height = cInfo.output_height;
228 width = cInfo.output_width;
229 bpl = width;
230 pixels = new unsigned char [height*width];
231 if (pixels == NULL) {
232 jpeg_finish_decompress(&cInfo);
233 jpeg_destroy_decompress(&cInfo);
234 return -1;
235 }
236 ptrPix = pixels;
237
238 stride = cInfo.output_width * cInfo.output_components;
239
240 buffer[0] = (JSAMPROW)malloc(stride);
241
242 while (cInfo.output_scanline < cInfo.output_height) {
243
244 jpeg_read_scanlines(&cInfo, buffer, 1);
245
246 memcpy(ptrPix,buffer[0],stride);
247
248 ptrPix+= stride;
249 }
250
251 free(buffer[0]);
252
253 colormap = new Color[cInfo.actual_number_of_colors];
254 if (colormap == NULL) {
255 delete pixels;
256 jpeg_finish_decompress(&cInfo);
257 jpeg_destroy_decompress(&cInfo);
258 return -1;
259 }
260 nbColors = cInfo.actual_number_of_colors;
261
262 for(n=0; n < nbColors; n++)
263 {
264 colormap[n].red = cInfo.colormap[0][n];
265 colormap[n].green = cInfo.colormap[1][n];
266 colormap[n].blue = cInfo.colormap[2][n];
267 }
268
269 jpeg_finish_decompress(&cInfo);
270 jpeg_destroy_decompress(&cInfo);
271
272 if (read_alpha) {
273 if (buildJpegAlpha(this, stream + offset) < 0) {
274 return -1;
275 }
276 }
277 return 0;
278}
279
280// Read JPEG image using pre-loaded Tables
281
282int
283Bitmap::buildFromJpegAbbreviatedData(unsigned char *stream)
284{
285 JSAMPROW buffer[1];
286 unsigned char *ptrPix;
287 int stride;
288 long n;
289 int status;
290
291#if PRINT&1
292 printf("flash: loading jpeg (abbreviated)\n");
293#endif
294
295 // Set current stream pointer to stream
296 inputData = stream;
297
298 // Error handler
299 if (setjmp(jpegErrorMgr.setjmp_buffer)) {
300 // JPEG data Error
301 //jpeg_destroy_decompress(&jpegObject);
302 if (pixels) {
303 delete[] pixels;
304 pixels = NULL;
305 }
306 return -1;
307 }
308
309 // Here it's ok
310
311 jpeg_read_header(&jpegObject, TRUE);
312 jpegObject.quantize_colors = TRUE;// Create colormapped image
313 jpeg_start_decompress(&jpegObject);
314
315 // Set objet dimensions
316 height = jpegObject.output_height;
317 width = jpegObject.output_width;
318 bpl = width;
319 pixels = new unsigned char [height*width];
320 if (pixels == NULL) {
321 jpeg_finish_decompress(&jpegObject);
322 return -1;
323 }
324 ptrPix = pixels;
325
326 stride = jpegObject.output_width * jpegObject.output_components;
327
328 buffer[0] = (JSAMPROW)malloc(stride);
329
330 while (jpegObject.output_scanline < jpegObject.output_height) {
331
332 status = jpeg_read_scanlines(&jpegObject, buffer, 1);
333
334 memcpy(ptrPix,buffer[0],stride);
335
336 ptrPix+= stride;
337 }
338
339 free(buffer[0]);
340
341 colormap = new Color[jpegObject.actual_number_of_colors];
342 if (colormap == NULL) {
343 jpeg_finish_decompress(&jpegObject);
344 delete pixels;
345 return -1;
346 }
347 nbColors = jpegObject.actual_number_of_colors;
348
349 for(n=0; n < nbColors; n++)
350 {
351 colormap[n].red = jpegObject.colormap[0][n];
352 colormap[n].green = jpegObject.colormap[1][n];
353 colormap[n].blue = jpegObject.colormap[2][n];
354 }
355
356 status = jpeg_finish_decompress(&jpegObject);
357
358 return 0;
359}
360
361// Just init JPEG object and read JPEG Tables
362
363int
364Bitmap::readJpegTables(unsigned char *stream)
365{
366 if (haveTables) {
367 //Error, it has already been initialized
368 return -1;
369 }
370
371 // Setup error handler
372 jpegObject.err = jpeg_std_error(&jpegErrorMgr.pub);
373 jpegErrorMgr.pub.error_exit = errorExit;
374
375 if (setjmp(jpegErrorMgr.setjmp_buffer)) {
376 // JPEG data Error
377 jpeg_destroy_decompress(&jpegObject);
378 return -1;
379 }
380
381 // Set current stream pointer to stream
382 inputData = stream;
383
384 // Here it's Ok
385
386 jpeg_create_decompress(&jpegObject);
387
388 // Setup source manager structure
389 jpegSourceManager.init_source = initSource;
390 jpegSourceManager.fill_input_buffer = fillInputBuffer;
391 jpegSourceManager.skip_input_data = skipInputData;
392 jpegSourceManager.resync_to_restart = resyncToRestart;
393 jpegSourceManager.term_source = termSource;
394
395 // Set default source manager
396 jpegObject.src = &jpegSourceManager;
397
398 jpeg_read_header(&jpegObject, FALSE);
399
400 haveTables = 1;
401
402 return 0;
403}
404
405int
406Bitmap::buildFromZlibData(unsigned char *buffer, int width, int height, int format, int tableSize, int tableHasAlpha)
407{
408 z_streamstream;
409 int status;
410 unsigned char *data;
411 int elementSize;
412
413#if PRINT&1
414 printf("flash: loading with zlib\n");
415#endif
416
417 this->width = width;
418 this->height = height;
419 this->bpl = width;
420
421 if (tableHasAlpha) {
422 elementSize = 4;// Cmap is RGBA
423 } else {
424 elementSize = 3;// Cmap is RGB
425 }
426
427 stream.next_in = buffer;
428 stream.avail_in = 1;
429 stream.zalloc = Z_NULL;
430 stream.zfree = Z_NULL;
431
432 tableSize++;
433
434 // Uncompress Color Table
435 if (format == 3) {
436 unsigned char *colorTable;
437 long n;
438
439 // Ajust width for 32 bit padding
440 width = (width+3)/4*4;
441 this->width = width;
442 this->bpl = width;
443
444 depth = 1;
445 colorTable = new unsigned char[tableSize*elementSize];
446 if (colorTable == NULL) {
447 return -1;
448 }
449
450 stream.next_out = colorTable;
451 stream.avail_out = tableSize*elementSize;
452
453 inflateInit(&stream);
454
455 while (1) {
456 status = inflate(&stream, Z_SYNC_FLUSH);
457 if (status == Z_STREAM_END) {
458 break;
459 }
460 if (status != Z_OK) {
461 printf("Zlib cmap error : %s\n", stream.msg);
462 return -1;
463 }
464 stream.avail_in = 1;
465 // Colormap if full
466 if (stream.avail_out == 0) {
467 break;
468 }
469 }
470
471 nbColors = tableSize;
472
473 colormap = new Color[nbColors];
474 if (colormap == NULL) {
475 delete colorTable;
476 return -1;
477 }
478
479 for(n=0; n < nbColors; n++) {
480 colormap[n].red = colorTable[n*elementSize+0];
481 colormap[n].green = colorTable[n*elementSize+1];
482 colormap[n].blue = colorTable[n*elementSize+2];
483 if (tableHasAlpha) {
484 colormap[n].alpha = colorTable[n*elementSize+3];
485 }
486 }
487
488 delete colorTable;
489
490 } else if (format == 4) {
491 depth = 2;
492 width = (width+1)/2*2;
493 this->bpl = width;
494 } else if (format == 5) {
495 depth = 4;
496 }
497
498 data = new unsigned char[depth*width*height];
499 if (data == NULL) {
500 if (colormap) delete colormap;
501 return -1;
502 }
503
504 stream.next_out = data;
505 stream.avail_out = depth*width*height;
506
507 if (format != 3) {
508 status = inflateInit(&stream);
509 }
510
511 while (1) {
512 status = inflate(&stream, Z_SYNC_FLUSH) ;
513 if (status == Z_STREAM_END) {
514 break;
515 }
516 if (status != Z_OK) {
517 printf("Zlib data error : %s\n", stream.msg);
518 delete data;
519 return -1;
520 }
521 stream.avail_in = 1;
522 }
523
524 inflateEnd(&stream);
525
526 pixels = new unsigned char [height*width];
527 if (pixels == NULL) {
528 if (colormap) delete colormap;
529 delete data;
530 return -1;
531 }
532
533 if (format != 3) {
534 int n,c;
535 unsigned char r,g,b,a;
536 unsigned char *ptr;
537
538 r = g = b = a = 0; /* to supress warnings */
539
540 nbColors = 0;
541 colormap = new Color[256];
542 if (colormap == NULL) {
543 delete data;
544 delete pixels;
545 return -1;
546 }
547 memset(colormap, 0, 256 * sizeof(Color));
548 ptr = pixels;
549
550 for(n=0; n < width*height*depth; n+=depth,ptr++) {
551
552 switch (format) {
553 case 4:
554 a = 1;
555 r = (data[n] & 0x78)<<1;
556 g = ((data[n] & 0x03)<<6) | (data[n+1] & 0xc0)>>2;
557 b = (data[n+1] & 0x1e)<<3;
558 break;
559 case 5:
560 a = data[n];
561 // Reduce color dynamic range
562 r = data[n+1]&0xe0;
563 g = data[n+2]&0xe0;
564 b = data[n+3]&0xe0;
565 break;
566 }
567 for(c=0; c < nbColors; c++) {
568 if (r == colormap[c].red
569 && g == colormap[c].green
570 && b == colormap[c].blue) {
571 *ptr = c;
572 break;
573 }
574 }
575 if (c == nbColors) {
576 if (nbColors == 256) continue;
577 nbColors++;
578 if (nbColors == 256) {
579 //printf("Colormap entries exhausted. After %d scanned pixels\n", n/4);
580 }
581 colormap[c].alpha = a;
582 colormap[c].red = r;
583 colormap[c].green = g;
584 colormap[c].blue = b;
585 *ptr = c;
586 }
587 }
588 } else {
589 memcpy(pixels, data, width*height);
590 if (tableHasAlpha) {
591 int n;
592 unsigned char *ptr, *alpha;
593
594 alpha_buf = (unsigned char *)malloc(width*height);
595 ptr = data;
596 alpha = alpha_buf;
597 for(n=0; n < width*height; n++, ptr++, alpha++) {
598 *alpha = colormap[*ptr].alpha;
599 }
600 }
601 }
602
603 delete data;
604 return 0;
605}
606
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 @@
1/////////////////////////////////////////////////////////////
2// Flash Plugin and Player
3// Copyright (C) 1998 Olivier Debon
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19///////////////////////////////////////////////////////////////
20#ifndef _BITMAP_H_
21#define _BITMAP_H_
22
23struct MyErrorHandler {
24 struct jpeg_error_mgr pub;
25 jmp_buf setjmp_buffer;
26};
27
28class Bitmap : public Character {
29 public:
30 long width;
31 long height;
32 long bpl;
33 long depth;
34
35 unsigned char *pixels; // Array of Pixels
36 Color *colormap; // Array of color definitions
37 long nbColors;
38
39 unsigned char *alpha_buf;// Array of alpha values (no alpha if NULL)
40
41 int defLevel;
42
43// Class Variables
44
45 static int haveTables;
46 static struct jpeg_decompress_struct jpegObject;
47 static struct jpeg_source_mgr jpegSourceManager;
48 static MyErrorHandler jpegErrorMgr;
49
50public:
51 Bitmap(long id, int level = 1);
52 ~Bitmap();
53
54 // JPEG handling methods
55 int buildFromJpegInterchangeData(unsigned char *stream, int alpha, long offset);// Complete
56 int buildFromJpegAbbreviatedData(unsigned char *stream);// Abbreviated
57
58 // Class Method
59 static int readJpegTables(unsigned char *stream);// Tables Only
60
61 // ZLIB handling methods
62 int buildFromZlibData(unsigned char *buffer,
63 int width, int height,
64 int format, int tableSize, int tableHasAlpha);
65
66 long getWidth();
67 long getHeight();
68 Color *getColormap(long *n);
69 unsigned char *getPixels();
70};
71
72#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 @@
1/////////////////////////////////////////////////////////////
2// Flash Plugin and Player
3// Copyright (C) 1998 Olivier Debon
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19///////////////////////////////////////////////////////////////
20// Author : Olivier Debon <odebon@club-internet.fr>
21//
22
23#include "swf.h"
24
25#ifdef RCSID
26static char *rcsid = "$Id$";
27#endif
28
29#define PRINT 0
30
31// Contructor
32
33Button::Button(long id, int level) : Character(ButtonType, id)
34{
35 defLevel = level;
36 actionRecords = 0;
37 buttonRecords = 0;
38 conditionList = 0;
39 reset();
40 isMenu = 0;
41 sound[0] = sound[1] = sound[2] = sound[3] = 0;
42}
43
44// Destructor
45
46Button::~Button()
47{
48 if (actionRecords) {
49 ActionRecord *ar,*del;
50 for(ar = actionRecords; ar;) {
51 del = ar;
52 ar = ar->next;
53 delete del;
54 }
55 }
56 if (buttonRecords) {
57 ButtonRecord *br,*del;
58 for(br = buttonRecords; br;) {
59 del = br;
60 br = br->next;
61 if (del->cxform)
62 delete del->cxform;
63 delete del;
64 }
65 }
66 if (conditionList) {
67 Condition *cond,*del;
68 for(cond = conditionList; cond;) {
69 ActionRecord *ar,*d;
70
71 for(ar = cond->actions; ar;) {
72 d = ar;
73 ar = ar->next;
74 delete d;
75 }
76
77 del = cond;
78 cond = cond->next;
79 delete del;
80 }
81 }
82}
83
84ButtonRecord *
85Button::getButtonRecords()
86{
87 return buttonRecords;
88}
89
90ActionRecord *
91Button::getActionRecords()
92{
93 return actionRecords;
94}
95
96Sound **
97Button::getSounds()
98{
99 return sound;
100}
101
102Condition *
103Button::getConditionList()
104{
105 return conditionList;
106}
107
108void
109Button::setButtonSound(Sound *s, int state)
110{
111 if (state >=0 && state < 4) {
112 sound[state] = s;
113 }
114}
115
116void
117Button::setButtonMenu(int menu)
118{
119 isMenu = menu;
120}
121
122void
123Button::addButtonRecord( ButtonRecord *br )
124{
125#if 0
126 /* SURTOUT PAS !!! */
127 ButtonRecord **l;
128
129 /* sort by layer */
130 l=&buttonRecords;
131 while (*l != NULL && (*l)->layer < br->layer) l = &(*l)->next;
132 br->next = *l;
133 *l = br;
134#else
135 br->next = 0;
136
137 if (buttonRecords == 0) {
138 buttonRecords = br;
139 } else {
140 ButtonRecord *current;
141
142 for(current = buttonRecords; current->next; current = current->next);
143
144 current->next = br;
145 }
146#endif
147}
148
149void
150Button::addCondition( long transition )
151{
152 Condition *condition;
153
154 condition = new Condition;
155 if (condition == NULL) return;
156
157 condition->transition = transition;
158 condition->next = conditionList;
159
160 // Move current actionRecords to this condition
161 condition->actions = actionRecords;
162 actionRecords = 0;
163
164 conditionList = condition;
165}
166
167void
168Button::addActionRecord( ActionRecord *ar )
169{
170 ar->next = 0;
171
172 if (actionRecords == 0) {
173 actionRecords = ar;
174 } else {
175 ActionRecord *current;
176
177 for(current = actionRecords; current->next; current = current->next);
178
179 current->next = ar;
180 }
181}
182
183void
184Button::getRegion(GraphicDevice *gd, Matrix *matrix, void *id, ScanLineFunc scan_line_func)
185{
186 ButtonRecord *br;
187
188 for (br = buttonRecords; br; br = br->next)
189 {
190 if ((br->state & stateHitTest) && br->character /* Temporaire */) {
191 Matrix mat;
192
193 mat = (*matrix) * br->buttonMatrix;
194 br->character->getRegion(gd, &mat, id, scan_line_func);
195 }
196 }
197}
198
199int
200Button::execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform, ButtonState renderState)
201{
202 ButtonRecord *br;
203 int sprite = 0;
204 Cxform *cxf = 0;
205
206#if PRINT==2
207 printf("Rendering Button %d for State(s) ", getTagId());
208#endif
209 for (br = buttonRecords; br; br = br->next)
210 {
211 if ((br->state & renderState) && br->character != NULL) {
212 Matrix mat;
213
214#if PRINT==2
215 printf("%d ", br->state);
216#endif
217 mat = (*matrix) * br->buttonMatrix;
218
219 if (cxform) {
220 cxf = cxform;
221 } else if (br->cxform) {
222 cxf = br->cxform;
223 }
224
225 if (br->character->execute(gd, &mat, cxf)) {
226 sprite = 1;
227 }
228 }
229 }
230#if PRINT==2
231 printf("\n");
232#endif
233 return sprite;
234}
235
236ActionRecord *
237Button::getActionFromTransition(ButtonState cur, ButtonState old)
238{
239 Condition *cond;
240 long mask;
241
242 if (old == cur) return NULL;
243
244 /* transitions */
245 mask = 0;
246 if (old == stateUp && cur == stateOver)
247 mask |= 0x001;
248 else if (old == stateOver && cur == stateUp)
249 mask |= 0x002;
250 else if (old == stateOver && cur == stateDown)
251 mask |= 0x004;
252 else if (old == stateDown && cur == stateOver)
253 mask |= 0x008;
254
255 if (!isMenu) {
256 /* push button transitions (XXX: not quite correct) */
257 if (old == stateDown && cur == stateUp)
258 mask = 0x010;
259 else if (old == stateUp && cur == stateDown)
260 mask = 0x020;
261 /* XXX: what is transition 0x040 ?? */
262 } else {
263 /* menu button transitions (XXX: not quite correct) */
264 if (old == stateUp && cur == stateDown)
265 mask = 0x080;
266 else if (old == stateDown && cur == stateUp)
267 mask = 0x100;
268 }
269
270 for (cond = conditionList; cond; cond = cond->next) {
271 if (cond->transition & mask) {
272 return cond->actions;
273 }
274 }
275 return 0;
276}
277
278void
279Button::getBoundingBox(Rect *bbox, DisplayListEntry *e)
280{
281 ButtonRecord *br;
282
283 bbox->reset();
284 for (br = buttonRecords; br; br = br->next)
285 {
286 if (br->state & e->renderState) {
287 if (br->character) {
288 Rect bb;
289
290 bb.reset();
291 br->character->getBoundingBox(&bb,e);
292 transformBoundingBox(bbox, &br->buttonMatrix, &bb, 0);
293 }
294 }
295 }
296}
297
298/* Get current render character, actually it should be a list of characters
299 so a DisplayList after all */
300Character *
301Button::getRenderCharacter(ButtonState state)
302{
303 ButtonRecord *br;
304
305 for (br = buttonRecords; br; br = br->next)
306 {
307 if (br->state & state) {
308 return br->character;
309 }
310 }
311 return 0;
312}
313
314void
315Button::updateButtonState(DisplayListEntry *e)
316{
317 ButtonRecord *br;
318
319 e->buttonCharacter = 0;
320 for (br = buttonRecords; br; br = br->next)
321 {
322 if (br->state & e->renderState) {
323 e->buttonCharacter = br->character;
324 e->buttonMatrix = br->buttonMatrix;
325 return;
326 }
327 }
328}
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 @@
1/////////////////////////////////////////////////////////////
2// Flash Plugin and Player
3// Copyright (C) 1998 Olivier Debon
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19///////////////////////////////////////////////////////////////
20#ifndef _BUTTON_H_
21#define _BUTTON_H_
22
23struct ButtonRecord {
24 ButtonState state;
25 Character *character;
26 long layer;
27 Matrix buttonMatrix;
28 Cxform *cxform;
29
30 struct ButtonRecord*next;
31};
32
33struct Condition {
34 long transition;
35 ActionRecord *actions;
36
37 Condition *next;
38};
39
40class Button : public Character {
41public:
42 long defLevel;
43
44 ButtonRecord *buttonRecords;
45 ActionRecord *actionRecords;
46 Condition *conditionList;
47
48 long isMenu;
49
50 Sound *sound[4];
51
52 Button(long id, int level = 1);
53 ~Button();
54 void addActionRecord( ActionRecord *ar );
55 void addButtonRecord( ButtonRecord *br );
56 void addCondition( long transition );
57 int execute(GraphicDevice *gd, Matrix *matrix,
58 Cxform *cxform, ButtonState renderState);
59 ActionRecord*getActionFromTransition(ButtonState currentState,
60 ButtonState old);
61 void getRegion(GraphicDevice *gd, Matrix *matrix,
62 void *id, ScanLineFunc scan_line_func);
63 ButtonRecord*getButtonRecords();
64 void setButtonSound(Sound *, int);
65 void setButtonMenu(int);
66
67 ActionRecord*getActionRecords();
68 Condition*getConditionList();
69 Sound **getSounds();
70
71 void getBoundingBox(Rect *bb, DisplayListEntry *);
72
73 void updateButtonState(DisplayListEntry *);
74 Character*getRenderCharacter(ButtonState state);
75
76 // Builtin
77 int isButton() {
78 return 1;
79 };
80
81#ifdef DUMP
82 void dump(BitStream *);
83 void dumpButtonRecords(BitStream *, int putCxform = 0);
84 void dumpButtonConditions(BitStream *);
85#endif
86};
87
88#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 @@
1/////////////////////////////////////////////////////////////
2// Flash Plugin and Player
3// Copyright (C) 1998 Olivier Debon
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19///////////////////////////////////////////////////////////////
20// Author : Olivier Debon <odebon@club-internet.fr>
21//
22
23#include "swf.h"
24
25#ifdef RCSID
26static char *rcsid = "$Id$";
27#endif
28
29///// Character member definitions
30
31Character::Character(ObjectType objectType, long tagid)
32{
33 type = objectType;
34 tagId = tagid;
35 name = NULL;
36}
37
38Character::~Character()
39{
40 delete name;
41}
42
43int
44Character::execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform)
45{
46 printf("Cannot be executed\n");
47 return 0;
48}
49
50ActionRecord *
51Character::eventHandler(GraphicDevice *gd, FlashEvent *ev)
52{
53 fprintf(stderr,"Unable to handle event !!!\n");
54 return 0;
55}
56
57int
58Character::isButton()
59{
60 return 0;
61}
62
63int
64Character::isSprite(void)
65{
66 return 0;
67}
68
69char *
70Character::getName()
71{
72 return name;
73}
74
75void
76Character::getBoundingBox(Rect *bb, DisplayListEntry *e)
77{
78 //fprintf(stderr,"Unable to handle getBoundingBox !!!\n");
79 bb->xmin = LONG_MAX;
80 bb->ymin = LONG_MAX;
81 bb->ymax = LONG_MIN;
82 bb->ymax = LONG_MIN;
83 return;
84}
85
86void
87Character::getRegion(GraphicDevice *gd, Matrix *matrix,
88 void *id, ScanLineFunc scan_line_func)
89{
90 fprintf(stderr,"Unable to handle getRegion !!!\n");
91 return;
92}
93
94long
95Character::getTagId()
96{
97 return tagId;
98}
99
100void
101Character::reset()
102{
103}
104
105ObjectType
106Character::getType()
107{
108 return type;
109}
110
111char *
112Character::getTypeString()
113{
114 switch (type) {
115 case BitmapType:
116 return "Bitmap";
117 case FontType:
118 return "Font";
119 case ButtonType:
120 return "Button";
121 case SpriteType:
122 return "Sprite";
123 case ShapeType:
124 return "Shape";
125 case SoundType:
126 return "Sound";
127 case TextType:
128 return "Text";
129 default:
130 return "Unknown";
131 }
132}
133
134void
135Character::setName(char* string)
136{
137 name = strdup(string);
138}
139
140///// Dict methods definitions
141
142Dict::Dict()
143{
144 head = 0;
145}
146
147Dict::~Dict()
148{
149 struct sCharCell *cell,*del;
150
151 for(cell = head; cell;)
152 {
153 del = cell;
154 cell = cell->next;
155 delete del->elt;
156 delete del;
157 }
158}
159
160void
161Dict::addCharacter(Character *character)
162{
163 struct sCharCell *cell;
164
165 cell = new sCharCell;
166 if (cell == NULL) {
167 delete character;
168 return;
169 }
170 cell->elt = character;
171 cell->next = head;
172
173 head = cell;
174}
175
176Character *
177Dict::getCharacter(long id)
178{
179 struct sCharCell *cell;
180
181 for(cell = head; cell; cell = cell->next)
182 {
183 if (id == cell->elt->getTagId()) return cell->elt;
184 }
185 return 0;
186}
187
188void
189Dict::dictRewind()
190{
191 currentCell = head;
192}
193
194Character *
195Dict::dictNextCharacter()
196{
197 if (currentCell) {
198 struct sCharCell *cell;
199
200 cell = currentCell;
201 currentCell = currentCell->next;
202 return cell->elt;
203 } else {
204 return 0;
205 }
206}
207
208void
209Dict::nameCharacter(long id, char *string)
210{
211 struct sCharCell *cell;
212
213 for(cell = head; cell; cell = cell->next)
214 {
215 if (cell->elt->getTagId() == id) {
216 cell->elt->setName(string);
217 break;
218 }
219 }
220}
221
222#ifdef DUMP
223void
224Dict::dictSetUnsaved()
225{
226 struct sCharCell *cell;
227
228 for(cell = head; cell; cell = cell->next)
229 {
230 cell->elt->saved = 0;
231 }
232}
233#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 @@
1/////////////////////////////////////////////////////////////
2// Flash Plugin and Player
3// Copyright (C) 1998 Olivier Debon
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19///////////////////////////////////////////////////////////////
20#ifndef _CHARACTER_H_
21#define _CHARACTER_H_
22
23enum ObjectType {
24 ShapeType,
25 TextType,
26 FontType,
27 SoundType,
28 BitmapType,
29 SpriteType,
30 ButtonType
31};
32
33class DisplayListEntry;
34
35// Character definition
36
37class Character {
38 long tagId;
39 ObjectType type;
40 char *name;
41
42public:
43 Character(ObjectType type, long tagId);
44 virtual ~Character();
45
46 virtual int execute(GraphicDevice *, Matrix *, Cxform *);// Display, play or whatever
47 virtual int isButton(void);// True if Character is a button
48 virtual int isSprite(void);
49 virtual ActionRecord*eventHandler(GraphicDevice *, FlashEvent *);
50 virtual void getRegion(GraphicDevice *gd, Matrix *matrix, void *id, ScanLineFunc scan_line_func);
51 virtual void reset();// Reset internal state of object
52 virtual void getBoundingBox(Rect *bb, DisplayListEntry *de);
53#ifdef DUMP
54 virtual void dump(BitStream *main);
55
56 int saved;
57#endif
58
59 long getTagId();// Return tagId
60 ObjectType getType();
61 char *getTypeString();
62 char *getName();
63 void setName(char *);
64};
65
66struct sCharCell {
67 Character *elt;
68 struct sCharCell *next;
69};
70
71class Dict {
72 struct sCharCell *head;
73 struct sCharCell *currentCell;// Iteration variable for dictNextCharacter
74
75public:
76 Dict();
77 ~Dict();
78
79 void addCharacter(Character *character);
80 void nameCharacter(long id, char *string);
81 Character*getCharacter(long id);
82 void dictRewind();
83 Character*dictNextCharacter();
84
85#ifdef DUMP
86 void dictSetUnsaved();
87#endif
88};
89
90#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 @@
1/////////////////////////////////////////////////////////////
2// Flash Plugin and Player
3// Copyright (C) 1998,1999 Olivier Debon
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19///////////////////////////////////////////////////////////////
20// Author : Olivier Debon <odebon@club-internet.fr>
21//
22
23#include "swf.h"
24
25#ifdef RCSID
26static char *rcsid = "$Id";
27#endif
28
29long
30Cxform::getRed(long v) {
31 long val;
32
33 val = (long)(ra*v+rb);
34 if (val > 255) val = 255;
35 else if (val < 0) val = 0;
36 return val;
37}
38
39long
40Cxform::getGreen(long v) {
41 long val;
42
43 val = (long)(ga*v+gb);
44 if (val > 255) val = 255;
45 else if (val < 0) val = 0;
46 return val;
47}
48
49long
50Cxform::getBlue(long v) {
51 long val;
52
53 val = (long)(ba*v+bb);
54 if (val > 255) val = 255;
55 else if (val < 0) val = 0;
56 return val;
57}
58
59long
60Cxform::getAlpha(long v) {
61 long val;
62
63 val = (long)(aa*v+ab);
64 if (val > 255) val = 255;
65 else if (val < 0) val = 0;
66 return val;
67}
68
69Color
70Cxform::getColor(Color color) {
71 Color newColor;
72
73 newColor.red = getRed(color.red);
74 newColor.green = getGreen(color.green);
75 newColor.blue = getBlue(color.blue);
76 newColor.alpha = getAlpha(color.alpha);
77
78 return newColor;
79}
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 @@
1/////////////////////////////////////////////////////////////
2// Flash Plugin and Player
3// Copyright (C) 1998,1999 Olivier Debon
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19///////////////////////////////////////////////////////////////
20#ifndef _CXFORM_H_
21#define _CXFORM_H_
22
23struct Color {
24 unsigned char red,green,blue,alpha;
25 long pixel;
26};
27
28struct Cxform
29{
30 float aa; long ab;// a is multiply factor, b is addition factor
31 float ra; long rb;
32 float ga; long gb;
33 float ba; long bb;
34
35 longgetRed(long v);
36 longgetGreen(long v);
37 longgetBlue(long v);
38 longgetAlpha(long v);
39 ColorgetColor(Color color);
40
41#ifdef DUMP
42 void dump(BitStream *bs, int alpha = 0);
43#endif
44};
45
46#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 @@
1////////////////////////////////////////////////////////////
2// Flash Plugin and Player
3// Copyright (C) 1998,1999 Olivier Debon
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19///////////////////////////////////////////////////////////////
20// Author : Olivier Debon <odebon@club-internet.fr>
21//
22
23#include "swf.h"
24
25#ifdef RCSID
26static char *rcsid = "$Id$";
27#endif
28
29#define PRINT 0
30
31void deleteButton(FlashMovie *movie, DisplayListEntry *e)
32{
33 /* save the focus */
34 if (movie->mouse_active == 0 && e->renderState == stateOver) {
35 movie->lost_over = (Button *)e->character;
36 movie->cur_focus = NULL;
37 }
38
39 if (e == movie->cur_focus) {
40 movie->cur_focus = NULL;
41 }
42}
43
44void addButton(FlashMovie *movie, DisplayListEntry *e)
45{
46 if (movie->mouse_active == 0 &&
47 movie->cur_focus == NULL &&
48 movie->lost_over == (Button *)e->character) {
49 /* restore the lost focus */
50 e->renderState = stateOver;
51 e->oldState = stateOver;
52 ((Button *)e->character)->updateButtonState(e);
53 movie->lost_over = NULL;
54 movie->cur_focus = e;
55 }
56}
57
58DisplayList::DisplayList(FlashMovie *movie)
59{
60 list = NULL;
61 this->movie = movie;
62 bbox.reset();
63 isSprite = 0;
64}
65
66DisplayList::~DisplayList()
67{
68 clearList();
69}
70
71void
72DisplayList::clearList()
73{
74 DisplayListEntry *del, *e;
75
76 for(e = list; e;)
77 {
78 updateBoundingBox(e);
79 if (e->character->isButton()) {
80 deleteButton(movie,e);
81 }
82 del = e;
83 e = e->next;
84 delete del;
85 }
86 list = 0;
87}
88
89DisplayListEntry *
90DisplayList::getList()
91{
92 return list;
93}
94
95static void bbox(Rect *rect, Matrix *m, long x1, long y1)
96{
97 long x,y;
98
99 x = m->getX(x1,y1);
100 y = m->getY(x1,y1);
101 if (x < rect->xmin) rect->xmin = x;
102 if (x > rect->xmax) rect->xmax = x;
103 if (y < rect->ymin) rect->ymin = y;
104 if (y > rect->ymax) rect->ymax = y;
105}
106
107// Update bb to include boundary, optional reset of bb
108void transformBoundingBox(Rect *bb, Matrix *matrix, Rect *boundary, int reset)
109{
110 if (reset) {
111 bb->reset();
112 }
113
114 if (boundary->xmin != LONG_MAX) {
115 bbox(bb, matrix, boundary->xmin, boundary->ymin);
116 bbox(bb, matrix, boundary->xmax, boundary->ymin);
117 bbox(bb, matrix, boundary->xmin, boundary->ymax);
118 bbox(bb, matrix, boundary->xmax, boundary->ymax);
119 }
120}
121
122void
123DisplayList::placeObject(GraphicDevice *gd,Character *character, long depth, Matrix *matrix, Cxform *cxform, char *name)
124{
125 DisplayListEntry *n,*e,*prev;
126
127 n = new DisplayListEntry;
128 if (n == NULL) return;
129
130 n->depth = depth;
131 n->matrix = matrix;
132 n->cxform = cxform;
133 n->character = character;
134 n->instanceName = name;
135 n->owner = this;
136
137#if 0
138 printf("Dl %lx: placeObject: depth=%d character=%d cxform=%p\n",
139 this, n->depth,n->character ? n->character->getTagId() : 0, cxform);
140#endif
141
142 if (character == 0 || matrix == 0 || cxform == 0) {
143 for (e = list; e; prev = e, e = e->next) {
144 if (e->depth == n->depth) {
145 if (character == 0) {
146 n->character = e->character;
147 }
148 if (matrix == 0) {
149 n->matrix = e->matrix;
150 }
151 if (cxform == 0) {
152 n->cxform = e->cxform;
153 }
154 break;
155 }
156 }
157 }
158
159 if (n->character == 0) {
160 // Not found !!! Should not happen
161 // printf("PlaceObject cannot find character at depth %ld\n", n->depth);
162 delete n;
163 return;
164 }
165
166 prev = 0;
167 for (e = list; e; prev = e, e = e->next)
168 {
169 if (e->depth == n->depth) {
170 if (e->character->isButton()) {
171 deleteButton(movie, e);
172 }
173
174 // Do update, object has moved or been resized
175 updateBoundingBox(e);
176
177 // Replace object
178 e->depth = n->depth;
179 e->matrix = n->matrix;
180 e->cxform = n->cxform;
181 e->character = n->character;
182 /* if it is a button, we must update its state */
183 if (e->character->isButton()) {
184 movie->buttons_updated = 1;
185 addButton(movie, e);
186 }
187
188 updateBoundingBox(e);
189
190 delete n;
191 return;
192 }
193 if (e->depth > n->depth) break;
194 }
195 /* new object */
196
197 /* button instantiation */
198 if (n->character->isButton()) {
199 n->renderState = stateUp;
200 n->oldState = stateUp;
201 ((Button *)n->character)->updateButtonState(n);
202 addButton(movie,n);
203 }
204
205 updateBoundingBox(n);
206
207 if (prev == 0) {
208 // Object comes at first place
209 n->next = list;
210 list = n;
211 } else {
212 // Insert object
213 n->next = prev->next;
214 prev->next = n;
215 }
216}
217
218
219Character *
220DisplayList::removeObject(GraphicDevice *gd,Character *character, long depth)
221{
222 DisplayListEntry *e,*prev;
223
224 // List should not be empty
225 if (list == 0) return 0;
226
227#if 0
228 printf("removeObject: depth=%d character=%d\n",
229 depth,character ? character->getTagId() : 0);
230#endif
231
232 prev = 0;
233 for (e = list; e; prev = e, e = e->next) {
234 if (e->depth == depth) {
235 if (prev) {
236 prev->next = e->next;
237 } else {
238 list = e->next;
239 }
240 if (character == 0) {
241 character = e->character;
242 }
243 if (e->character->isButton()) {
244 deleteButton(movie, e);
245 }
246 if (e->character->isSprite()) {
247 ((Sprite*)e->character)->reset();
248 }
249
250 updateBoundingBox(e);
251
252 delete e;
253 return character;
254 }
255 }
256 return 0;// Should not happen
257}
258
259void
260DisplayList::updateBoundingBox(DisplayListEntry *e)
261{
262 Rect rect;
263
264 //rect.reset();
265 e->character->getBoundingBox(&rect,e);
266 transformBoundingBox(&this->bbox, e->matrix, &rect, 0);
267}
268
269int
270DisplayList::updateSprites()
271{
272 Sprite *sprite;
273 DisplayListEntry *e;
274 int refresh = 0;
275
276 for (e = this->list; e != NULL; e = e->next) {
277 if (e->character->isButton() && e->buttonCharacter) {
278 if (e->buttonCharacter->isSprite()) {
279 Matrix mat;
280
281 sprite = (Sprite *)e->buttonCharacter;
282 refresh |= sprite->program->dl->updateSprites();
283 refresh |= sprite->program->nestedMovie(this->movie->gd,this->movie->sm, e->matrix, e->cxform);
284 mat = (*e->matrix) * e->buttonMatrix;
285 transformBoundingBox(&this->bbox, &mat,
286 &(sprite->program->dl->bbox),
287 0);
288 }
289 }
290 if (e->character->isSprite()) {
291 sprite = (Sprite *)e->character;
292 refresh |= sprite->program->dl->updateSprites();
293 refresh |= sprite->program->nestedMovie(this->movie->gd,this->movie->sm, e->matrix, e->cxform);
294 transformBoundingBox(&this->bbox, e->matrix,
295 &(sprite->program->dl->bbox),
296 0);
297 }
298 }
299 return refresh;
300}
301
302/* Function can return either 0,1 or 2
303 0: Nothing match, continue
304 1: Something matches, but continue searching
305 2: Something matches, but stop searching
306*/
307
308static int exploreButtons1(Program *prg, void *opaque,
309 ExploreButtonFunc func)
310{
311 DisplayListEntry *e;
312 int ret, ret2 = 0;
313
314 for(e=prg->dl->list; e != NULL; e = e->next) {
315 if (e->character == NULL) continue;
316 if (e->character->isButton()) {
317 ret = func(opaque,prg,e);
318 if (ret == 2) return ret;// Func asks to return at once !!!
319 if (ret) ret2 = 1;
320 }
321 if (e->character->isSprite()) {
322 ret = exploreButtons1(((Sprite *)e->character)->program,
323 opaque,func);
324 if (ret == 2) return ret;// Func asks to return at once !!!
325 if (ret) ret2 = 1;
326 }
327 }
328 return ret2;
329}
330
331int exploreButtons(FlashMovie *movie, void *opaque, ExploreButtonFunc func)
332{
333 CInputScript *script;
334 int ret;
335
336 script = movie->main;
337 while (script != NULL) {
338 if (script->program) {
339 ret = exploreButtons1(script->program, opaque, func);
340 if (ret) return ret;
341 }
342 script = script->next;
343 }
344 return 0;
345}
346
347typedef struct {
348 long x,y;
349 int hit;
350 DisplayListEntry *bhit;
351} HitTable;
352
353static void button_hit_func(void *id, long y, long start, long end)
354{
355 HitTable *h = (HitTable *) id;
356 if ( y == h->y && (h->x >= start && h->x < end) )
357 h->hit = 1;
358}
359
360typedef struct {
361 FlashMovie *movie;
362 DisplayListEntry *bhit;
363} ButtonHit;
364
365static int button_hit(void *opaque, Program *prg, DisplayListEntry *e)
366{
367 ButtonHit *h = (ButtonHit *) opaque;
368 HitTable hit_table;
369 FlashMovie *movie = h->movie;
370 Rect bb,boundary;
371 Matrix mat;
372 ButtonState save;
373
374 hit_table.x = movie->mouse_x;
375 hit_table.y = movie->mouse_y / FRAC;
376 hit_table.hit = 0;
377
378 // Compute the bounding box in screen coordinates
379 save = e->renderState;
380 e->renderState = stateHitTest;
381 e->character->getBoundingBox(&boundary,e);
382 e->renderState = save;
383 mat = (*movie->gd->adjust) * e->renderMatrix;
384 transformBoundingBox(&bb, &mat, &boundary, 1);
385 // Check if mouse is within bb
386 if (movie->mouse_x < bb.xmin) return 0;
387 if (movie->mouse_x > bb.xmax) return 0;
388 if (movie->mouse_y < bb.ymin) return 0;
389 if (movie->mouse_y > bb.ymax) return 0;
390
391 e->character->getRegion(movie->gd, &e->renderMatrix,
392 &hit_table, button_hit_func);
393
394 if (hit_table.hit) {
395 h->bhit = e;
396 return 1;
397 } else {
398 return 0;
399 }
400}
401
402static int button_reset(void *opaque, Program *prg, DisplayListEntry *e)
403{
404 if (e->renderState != stateUp) {
405 e->owner->updateBoundingBox(e);
406 e->oldState = e->renderState;
407 e->renderState = stateUp;
408 ((Button *)e->character)->updateButtonState(e);
409 e->owner->updateBoundingBox(e);
410 }
411 return 0;
412}
413
414/* update the button states according to the current mouse state & return the list of actions */
415void
416DisplayList::updateButtons(FlashMovie *movie)
417{
418 DisplayListEntry *bhit;
419 ButtonHit h;
420
421 if (movie->mouse_active) {
422
423 h.bhit = NULL;
424 h.movie = movie;
425
426 exploreButtons(movie, &h, button_hit);
427
428 bhit = h.bhit;
429
430 /* set every button to not hit */
431 exploreButtons(movie, NULL, button_reset);
432
433 if (bhit) {
434 ButtonState state;
435
436 if (movie->button_pressed) {
437 state = stateDown;
438 } else {
439 state = stateOver;
440 }
441 if (state != bhit->renderState) {
442 bhit->owner->updateBoundingBox(bhit);
443 bhit->renderState = state;
444 ((Button *)bhit->character)->updateButtonState(bhit);
445 bhit->owner->updateBoundingBox(bhit);
446 movie->cur_focus = bhit;
447 if (movie->cursorOnOff)
448 movie->cursorOnOff(1,movie->cursorOnOffClientData);
449 }
450 } else {
451 if (movie->cursorOnOff)
452 movie->cursorOnOff(0,movie->cursorOnOffClientData);
453 }
454 }
455}
456
457typedef struct {
458 ActionRecord *action;// Action to do
459 Program *prg; // Context program
460} ButtonAction;
461
462static int button_action(void *opaque, Program *prg, DisplayListEntry *e)
463{
464 ButtonAction *h = (ButtonAction *)opaque;
465 static ActionRecord actionRefresh;
466 static ActionRecord soundFx;
467 Button *b;
468 ActionRecord **paction;
469 int n;
470
471 actionRefresh.action = ActionRefresh;
472 actionRefresh.next = 0;
473
474 soundFx.action = ActionPlaySound;
475 soundFx.next = &actionRefresh;
476
477 b = (Button *)e->character;
478
479 if (e->oldState != e->renderState) {
480
481 paction = &actionRefresh.next;
482
483 if (b->conditionList) {
484 *paction = b->getActionFromTransition(e->renderState, e->oldState);
485 } else if (e->renderState == stateDown) {
486 /* if the button is pressed and
487 no condition list is defined*/
488 *paction = b->actionRecords;
489 }
490
491 switch(e->renderState) {
492 case stateUp:
493 n = 0;
494 break;
495 case stateOver:
496 n = 1;
497 break;
498 default:
499 /* case stateDown: */
500 n = 2;
501 break;
502 }
503
504 if (b->sound[n]) {
505 soundFx.sound = b->sound[n];
506 h->action = &soundFx;
507 } else {
508 h->action = &actionRefresh;
509 }
510
511 e->oldState = e->renderState;
512
513 h->prg = prg;
514 return 2;
515 }
516 h->action = 0;// Nothing to do about this
517 return 0;
518}
519
520int computeActions(FlashMovie *movie, Program **prg, ActionRecord **ar)
521{
522 ButtonAction h;
523
524 h.action = NULL;
525 exploreButtons(movie, &h, button_action);
526 if (h.action) {
527 *prg = h.prg;
528 *ar = h.action;
529 return 1;
530 }
531 return 0;
532}
533
534#define FOCUS_ZOOM 1.5
535/* in pixels */
536#define FOCUS_SIZE_MIN 50
537#define FOCUS_TRANSLATE 15
538
539int
540DisplayList::render(GraphicDevice *gd, Matrix *render_matrix, Cxform *cxform)
541{
542 DisplayListEntry *e,*cur_focus;
543 int sprite = 0;
544 long n = 0;
545 Cxform cxf,*cxf1;
546 Rect bb,boundary;
547
548 cur_focus = NULL;
549
550 /*
551 if (isSprite == 0) {
552 if (this->bbox.xmin == LONG_MAX) return 0;
553 gd->updateClippingRegion(&this->bbox, render_matrix);
554 gd->clearCanvas();
555 }
556 */
557
558 for (e = list; e; e = e->next)
559 {
560#if PRINT
561 printf("Character %3d @ %3d\n", e->character ? e->character->getTagId() : 0, e->depth);
562#endif
563 if (e->character) {
564 Matrix mat;
565
566 if (render_matrix) {
567 mat = *render_matrix;
568 }
569
570 if (e->matrix) {
571 mat = mat * (*e->matrix);
572 }
573
574 /* fast clipping */
575 // If object boundaries are outside current clip region give up with rendering
576 e->character->getBoundingBox(&boundary,e);
577 if (boundary.xmin != LONG_MAX) {
578 Matrix tmat;
579
580 tmat = (*gd->adjust) * mat;
581 transformBoundingBox(&bb, &tmat, &boundary, 1);
582
583 bb.xmin = bb.xmin >> FRAC_BITS;
584 bb.ymin = bb.ymin >> FRAC_BITS;
585 bb.xmax = (bb.xmax + FRAC - 1) >> FRAC_BITS;
586 bb.ymax = (bb.ymax + FRAC - 1) >> FRAC_BITS;
587
588 if (bb.xmin >= gd->clip_rect.xmax ||
589 bb.xmax <= gd->clip_rect.xmin ||
590 bb.ymin >= gd->clip_rect.ymax ||
591 bb.ymax <= gd->clip_rect.ymin) {
592 continue;
593 }
594 }
595
596 if (cxform == NULL) {
597 cxf1 = e->cxform;
598 }
599 else if (e->cxform == NULL) {
600 cxf1 = cxform;
601 }
602 else {
603 cxf1 = &cxf;
604 cxf.ra = cxform->ra * e->cxform->ra;
605 cxf.ga = cxform->ga * e->cxform->ga;
606 cxf.ba = cxform->ba * e->cxform->ba;
607 cxf.aa = cxform->aa * e->cxform->aa;
608
609 cxf.rb = (long)(cxform->ra * e->cxform->rb + cxform->rb);
610 cxf.gb = (long)(cxform->ga * e->cxform->gb + cxform->gb);
611 cxf.bb = (long)(cxform->ba * e->cxform->bb + cxform->bb);
612 cxf.ab = (long)(cxform->aa * e->cxform->ab + cxform->ab);
613 }
614
615 if (e->character->isButton()) {
616 Button *b = (Button *) e->character;
617
618 e->renderMatrix = mat;
619
620 if (e->renderState != stateUp && movie->mouse_active == 0) {
621 cur_focus = e;
622 ((Button *)e->character)->updateButtonState(e);
623 }
624
625 if (b->execute(gd, &mat, cxf1, e->renderState)) {
626 sprite = 1;
627 }
628 } else {
629 if (e->character->execute(gd, &mat, cxf1)) {
630 sprite = 1;
631 }
632 }
633
634 n++;
635 }
636 }
637
638#if 0
639 {
640 /* display the bounding box (debug) */
641 Matrix tmat;
642 long x1,x2,y1,y2;
643 Color white;
644
645 white.red = 255;
646 white.green = white.blue = 0;
647 gd->setForegroundColor(white);
648
649 if (render_matrix) {
650 tmat = (*gd->adjust) * (*render_matrix);
651 } else {
652 tmat = *gd->adjust;
653 }
654 x1 = bbox.xmin;
655 y1 = bbox.ymin;
656 x2 = bbox.xmax;
657 y2 = bbox.ymax;
658 gd->drawLine(tmat.getX(x1,y1),tmat.getY(x1,y1),tmat.getX(x2,y1),tmat.getY(x2,y1),10*FRAC);
659 gd->drawLine(tmat.getX(x2,y1),tmat.getY(x2,y1),tmat.getX(x2,y2),tmat.getY(x2,y2),10*FRAC);
660 gd->drawLine(tmat.getX(x2,y2),tmat.getY(x2,y2),tmat.getX(x1,y2),tmat.getY(x1,y2),10*FRAC);
661 gd->drawLine(tmat.getX(x1,y2),tmat.getY(x1,y2),tmat.getX(x1,y1),tmat.getY(x1,y1),10*FRAC);
662 bbox.print();
663 }
664#endif
665
666 // Reset clipping zone
667 bbox.reset();
668
669 return sprite;
670}
671
672void
673DisplayList::getBoundary(Rect *bb)
674{
675 DisplayListEntry *e;
676 Rect boundary;
677
678 bb->reset();
679 for (e = list; e; e = e->next)
680 {
681 if (e->character) {
682 e->character->getBoundingBox(&boundary,e);
683 transformBoundingBox(bb, e->matrix, &boundary, 0);
684 }
685 }
686}
687
688extern "C" {
689
690void dump_buttons(FlashHandle flashHandle)
691{
692#if 0
693 Rect rect;
694 DisplayListEntry *e;
695 FlashMovie *movie;
696
697 movie = (FlashMovie *)flashHandle;
698
699 for (e = movie->first_button; e; e = e->next_button) {
700 computeBBox(movie,&rect,e);
701 printf("button: id=%d pos=%d %d %d %d\n",
702 e->character->getTagId(),
703 rect.xmin, rect.ymin, rect.xmax, rect.ymax);
704 }
705#endif
706}
707
708}
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 @@
1/////////////////////////////////////////////////////////////
2// Flash Plugin and Player
3// Copyright (C) 1998 Olivier Debon
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19///////////////////////////////////////////////////////////////
20#ifndef _DISPLAYLIST_H_
21#define _DISPLAYLIST_H_
22
23class Character;
24class Program;
25
26struct DisplayList;
27
28// Display List management
29struct DisplayListEntry {
30 Character *character;
31 long depth;
32 Matrix *matrix;
33 Cxform *cxform;
34 char *instanceName;
35
36 /* button state */
37 ButtonState renderState;
38 ButtonState oldState;
39 Character *buttonCharacter;
40 Matrix buttonMatrix;
41 Matrix renderMatrix; /* last render matrix */
42
43 DisplayListEntry*next;
44
45 DisplayList *owner;// Parent
46};
47
48struct DisplayList {
49 DisplayListEntry*list;
50 FlashMovie *movie;
51 Rect bbox; // Delta clipping region
52 int isSprite;
53public:
54 DisplayList(FlashMovie *movie);
55 ~DisplayList();
56 DisplayListEntry*getList();
57 void clearList();
58 void placeObject(GraphicDevice *gd,Character *character, long depth, Matrix *matrix = 0, Cxform *cxform = 0, char *name = 0);
59 Character *removeObject(GraphicDevice *gd, Character *character, long depth);
60
61 int render(GraphicDevice *gd, Matrix *m = 0, Cxform *cxform = 0);
62 void updateBoundingBox(DisplayListEntry *);
63 void updateButtons (FlashMovie *);
64 void getBoundary(Rect *bb);// Returns boundary of current displayed objects
65 int updateSprites();// Update sprites in the display list
66};
67
68typedef void (*DisplayListFunc)(DisplayListEntry *e, void *opaque);
69
70 void updateButtons(FlashMovie *m);
71 int computeActions(FlashMovie *m, Program **prog, ActionRecord **ar);
72 void renderFocus(FlashMovie *movie);
73
74typedef int (*ExploreButtonFunc)(void *opaque, Program *prg, DisplayListEntry *e);
75 int exploreButtons(FlashMovie *movie, void *opaque, ExploreButtonFunc func);
76 void updateBoundingBox(DisplayListEntry *e);
77 void transformBoundingBox(Rect *bb, Matrix *matrix, Rect *boundary, int reset);
78 void updateButtonState(DisplayListEntry *e, ButtonState state);
79
80#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 @@
1/////////////////////////////////////////////////////////////
2// Flash Plugin and Player
3// Copyright (C) 1998,1999 Olivier Debon
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19///////////////////////////////////////////////////////////////
20// Author : Olivier Debon <odebon@club-internet.fr>
21//
22
23#include "swf.h"
24#include "graphic16.h"
25#include "graphic24.h"
26#include "graphic32.h"
27
28#ifdef RCSID
29static char *rcsid = "$Id$";
30#endif
31
32// Interface with standard C
33extern "C" {
34
35FlashHandle
36FlashNew()
37{
38 FlashMovie *fh;
39
40 fh = new FlashMovie;
41
42 fh->main = new CInputScript;
43
44 return (FlashHandle)fh;
45}
46
47int
48FlashParse(FlashHandle flashHandle, int level, char *data, long size)
49{
50 FlashMovie *fh;
51 CInputScript *script;
52 int status = FLASH_PARSE_ERROR;
53
54 fh = (FlashMovie *)flashHandle;
55
56 for(script = fh->main; script != NULL; script = script->next) {
57 if (script->level == level) {
58 status = script->ParseData(fh, data, size);
59
60 if (status & FLASH_PARSE_START) {
61 fh->msPerFrame = 1000/fh->main->frameRate;
62 script->program->rewindMovie();
63 }
64 break;
65 }
66 }
67
68 return status;
69}
70
71void
72FlashGetInfo(FlashHandle flashHandle, struct FlashInfo *fi)
73{
74 FlashMovie *fh;
75
76 fh = (FlashMovie *)flashHandle;
77
78 fi->version = fh->main->m_fileVersion;
79 fi->frameRate = fh->main->frameRate;
80 fi->frameCount = fh->main->frameCount;
81 fi->frameWidth = fh->main->frameRect.xmax - fh->main->frameRect.xmin;
82 fi->frameHeight = fh->main->frameRect.ymax - fh->main->frameRect.ymin;
83}
84
85long FlashGraphicInit(FlashHandle flashHandle, FlashDisplay *fd)
86{
87 FlashMovie *fh;
88
89 fh = (FlashMovie *)flashHandle;
90
91 switch (fd->bpp) {
92 case 4:
93 fh->gd = new GraphicDevice32(fd);
94 break;
95 case 3:
96 fh->gd = new GraphicDevice24(fd);
97 break;
98 case 2:
99 fh->gd = new GraphicDevice16(fd);
100 break;
101 default:
102 fprintf(stderr, "Unsupported depth\n");
103 }
104
105 fh->gd->setMovieDimension(fh->main->frameRect.xmax - fh->main->frameRect.xmin,
106 fh->main->frameRect.ymax - fh->main->frameRect.ymin);
107
108 return 1;// Ok
109}
110
111void
112FlashSoundInit(FlashHandle flashHandle, char *device)
113{
114 FlashMovie *fh;
115
116 fh = (FlashMovie *)flashHandle;
117
118 fh->sm = new SoundMixer(device);
119}
120
121void
122FlashZoom(FlashHandle flashHandle, int zoom)
123{
124 FlashMovie *fh;
125
126 fh = (FlashMovie *)flashHandle;
127
128 fh->gd->setMovieZoom(zoom);
129}
130
131void
132FlashOffset(FlashHandle flashHandle, int x, int y)
133{
134 FlashMovie *fh;
135
136 fh = (FlashMovie *)flashHandle;
137
138 fh->gd->setMovieOffset(x,y);
139}
140
141long
142FlashExec(FlashHandle flashHandle, long flag,
143 FlashEvent *fe, struct timeval *wakeDate)
144{
145 FlashMovie *fh;
146 long wakeUp = 0;
147
148 fh = (FlashMovie *)flashHandle;
149
150 if (fh->main == NULL) return 0; // Not ready
151 if (fh->main->program == NULL) return 0; // Not ready
152 if (fh->main->program->nbFrames == 0) return 0; // Still not ready
153 if (fh->gd == 0) return 0;
154
155 switch (flag & FLASH_CMD_MASK) {
156 case FLASH_STOP:
157 fh->main->program->pauseMovie();
158 wakeUp = 0;
159 break;
160 case FLASH_CONT:
161 fh->main->program->continueMovie();
162 wakeUp = FLASH_STATUS_WAKEUP;
163 break;
164 case FLASH_REWIND:
165 fh->main->program->rewindMovie();
166 wakeUp = 0;
167 break;
168 case FLASH_STEP:
169 fh->main->program->nextStepMovie();
170 wakeUp = 0;
171 break;
172 }
173
174 if (flag & FLASH_WAKEUP) {
175 // Compute next wakeup time
176 gettimeofday(wakeDate,0);
177 wakeDate->tv_usec += fh->msPerFrame*1000;
178 if (wakeDate->tv_usec > 1000000) {
179 wakeDate->tv_usec -= 1000000;
180 wakeDate->tv_sec++;
181 }
182
183 // Play frame
184 wakeUp = fh->processMovie(fh->gd, fh->sm);
185 }
186
187 if (checkFlashTimer(&fh->scheduledTime)) {
188 if (fh->handleEvent(fh->gd, fh->sm, &fh->scheduledEvent)) {
189 wakeUp = 1;
190 }
191
192 setFlashTimer(&fh->scheduledTime, -1);
193 }
194
195 if (flag & FLASH_EVENT) {
196 wakeUp = fh->handleEvent(fh->gd, fh->sm, fe);
197 if (wakeUp) {
198 /* Wake up at once, except for mouse move (40 ms after) */
199 gettimeofday(wakeDate,0);
200 if (fe->type == FeMouseMove) {
201 wakeDate->tv_usec += 40*1000;
202 if (wakeDate->tv_usec > 1000000) {
203 wakeDate->tv_usec -= 1000000;
204 wakeDate->tv_sec++;
205 }
206 }
207 }
208 }
209
210 return wakeUp || (fh->scheduledTime.tv_sec != -1);
211}
212
213void FlashSetGetSwfMethod(FlashHandle flashHandle, void (*getSwf)(char *url, int level, void *clientData), void *clientData)
214{
215 FlashMovie *fh;
216
217 fh = (FlashMovie *)flashHandle;
218
219 fh->getSwf = getSwf;
220 fh->getSwfClientData = clientData;
221}
222
223
224void
225FlashSetCursorOnOffMethod(FlashHandle flashHandle, void (*cursorOnOff)(int , void *), void *clientData)
226{
227 FlashMovie *fh;
228
229 fh = (FlashMovie *)flashHandle;
230
231 fh->cursorOnOff = cursorOnOff;
232 fh->cursorOnOffClientData = clientData;
233}
234
235void
236FlashSetGetUrlMethod(FlashHandle flashHandle, void (*getUrl)(char *, char *, void *), void *clientData)
237{
238 FlashMovie *fh;
239
240 fh = (FlashMovie *)flashHandle;
241
242 fh->getUrl = getUrl;
243 fh->getUrlClientData = clientData;
244}
245
246void
247FlashClose(FlashHandle flashHandle)
248{
249 FlashMovie *fh;
250
251 fh = (FlashMovie *)flashHandle;
252
253 delete fh;
254}
255
256void
257FlashSettings(FlashHandle flashHandle, long settings)
258{
259 FlashMovie *fh;
260
261 fh = (FlashMovie *)flashHandle;
262
263 fh->main->program->modifySettings( settings );
264}
265
266int shape_size,shape_nb,shaperecord_size,shaperecord_nb,style_size,style_nb;
267
268void flash_dump(void)
269{
270 printf("flash: shape_size=%d (nb=%d)\n",shape_size,shape_nb);
271 printf("flash: shaperecord_size=%d (nb=%d)\n",shaperecord_size,shaperecord_nb);
272 printf("flash: style_size=%d (nb=%d)\n",style_size,style_nb);
273}
274
275}; /* 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 @@
1/*///////////////////////////////////////////////////////////
2// Flash Plugin and Player
3// Copyright (C) 1998 Olivier Debon
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19///////////////////////////////////////////////////////////// */
20#ifndef _FLASH_H_
21#define _FLASH_H_
22
23#define PLUGIN_NAME "Shockwave Flash"
24#define FLASH_VERSION_STRING "Version 0.4.10"
25
26/* Flags to pass to FlashExec */
27#define FLASH_WAKEUP 0x01
28#define FLASH_EVENT 0x02
29#define FLASH_CMD 0x04
30
31/* Mask to extract commands */
32#define FLASH_CMD_MASK 0xf0
33/* Commands */
34 #define FLASH_STOP 0x10/* Pause the movie */
35 #define FLASH_CONT 0x20/* Continue the movie after pause */
36 #define FLASH_REWIND 0x30/* Rewind the movie and pause */
37 #define FLASH_STEP 0x40/* Frame by frame operation */
38
39/* return codes of FlashExec */
40#define FLASH_STATUS_WAKEUP 0x01 /* FlashExec must be called again after a given time */
41
42struct FlashInfo {
43 long frameRate;
44 long frameCount;
45 long frameWidth;
46 long frameHeight;
47 long version;
48};
49
50/* Player settings */
51 #define PLAYER_LOOP(1<<0)
52 #define PLAYER_QUALITY(1<<1)
53 #define PLAYER_MENU(1<<2)
54
55/* Parser status */
56#define FLASH_PARSE_ERROR 0
57#define FLASH_PARSE_START 1
58#define FLASH_PARSE_NEED_DATA 2
59#define FLASH_PARSE_EOM 4
60#define FLASH_PARSE_WAKEUP 8
61#define FLASH_PARSE_OOM 16 /* Out Of Memory */
62
63typedef void *FlashHandle;
64
65#if defined(__cplusplus) || defined(c_plusplus)
66extern "C" {
67#endif
68
69enum FlashEventType {
70 FeNone,
71 FeMouseMove,
72 FeButtonPress,
73 FeButtonRelease,
74 FeRefresh,
75 FeKeyPress,
76 /* internal events */
77 FeKeyRelease,
78};
79
80enum FlashKey {
81 FeKeyUp = 1,
82 FeKeyDown,
83 FeKeyLeft,
84 FeKeyRight,
85 FeKeyEnter,
86 FeKeyNext
87};
88
89
90
91typedef struct FlashEvent {
92 enum FlashEventType type;
93 int x,y; /* Mouse coordinates,
94 relative to upper-left window corner */
95 enum FlashKey key;
96} FlashEvent;
97
98typedef struct FlashDisplay {
99 void *pixels;
100 int bpl; /* bytes per line */
101 int width;
102 int height;
103 int depth;
104 int bpp;
105 int flash_refresh;
106 /* Clipping region */
107 int clip_x, clip_y;
108 int clip_width, clip_height;
109} FlashDisplay;
110
111extern FlashHandle FlashNew();
112extern void FlashGetInfo(FlashHandle fh, struct FlashInfo *fi);
113extern long FlashGraphicInit(FlashHandle fh, FlashDisplay *fd);
114extern void FlashSoundInit(FlashHandle fh, char *device);
115extern int FlashParse(FlashHandle fh, int level, char *data, long size);
116extern long FlashExec(FlashHandle fh, long flag, FlashEvent *fe, struct timeval *wakeDate);
117extern void FlashClose(FlashHandle fh);
118extern void FlashSetGetUrlMethod(FlashHandle flashHandle, void (*getUrl)(char *, char *, void *), void *);
119extern void FlashSetGetSwfMethod(FlashHandle flashHandle, void (*getSwf)(char *url, int level, void *clientData), void *clientData);
120extern void FlashSetCursorOnOffMethod(FlashHandle flashHandle, void (*cursorOnOff)(int , void *), void *clientData);
121extern void FlashZoom(FlashHandle fh, int zoom);
122extern void FlashOffset(FlashHandle fh, int x, int y);
123extern void FlashSettings(FlashHandle fh, long settings);
124
125#if defined(__cplusplus) || defined(c_plusplus)
126};
127#endif
128
129#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 @@
1/////////////////////////////////////////////////////////////
2// Flash Plugin and Player
3// Copyright (C) 1998 Olivier Debon
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19///////////////////////////////////////////////////////////////
20// Author : Olivier Debon <odebon@club-internet.fr>
21//
22
23#include "swf.h"
24
25#ifdef RCSID
26static char *rcsid = "$Id$";
27#endif
28
29SwfFont::SwfFont(long id) : Character(FontType, id)
30{
31 glyphs = 0;
32 nbGlyphs = 0;
33 name = NULL;
34 setFontName("Unknown");
35 flags = (FontFlags)0;
36 lookUpTable = 0;
37}
38
39SwfFont::~SwfFont()
40{
41 if (lookUpTable) {
42 delete lookUpTable;
43 }
44 delete name;
45 delete [] glyphs;
46}
47
48void
49SwfFont::setFontFlags(FontFlags f)
50{
51 flags = f;
52}
53
54char *
55SwfFont::getName()
56{
57 return name;
58}
59
60FontFlags
61SwfFont::getFlags()
62{
63 return flags;
64}
65
66long
67SwfFont::getNbGlyphs()
68{
69 return nbGlyphs;
70}
71
72Shape *
73SwfFont::getGlyph(long index)
74{
75 if (index >= nbGlyphs) return 0;
76 return &glyphs[index];
77}
78
79long
80SwfFont::getGlyphCode(long index)
81{
82 if (lookUpTable == 0 || index >= nbGlyphs) return 0;
83 return lookUpTable[index];
84}
85
86void
87SwfFont::setFontName(char *str)
88{
89 delete name;
90 name = new char[strlen(str)+1];
91 strcpy(name,str);
92}
93
94void
95SwfFont::setFontLookUpTable(long *lut)
96{
97 lookUpTable = lut;
98}
99
100void
101SwfFont::setFontShapeTable(Shape *shapes, long n)
102{
103 glyphs = shapes;
104 nbGlyphs = n;
105}
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 @@
1/////////////////////////////////////////////////////////////
2// Flash Plugin and Player
3// Copyright (C) 1998 Olivier Debon
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19///////////////////////////////////////////////////////////////
20#ifndef _SWFFONT_H_
21#define _SWFFONT_H_
22
23class SwfFont : public Character {
24 Shape *glyphs;// Array
25 long nbGlyphs;
26 char *name;
27 FontFlags flags;
28 long *lookUpTable;// Array
29
30 // Font2
31 long ascent;
32 long descent;
33 long leading;
34
35public:
36 SwfFont(long id);
37 ~SwfFont();
38
39 void setFontShapeTable(Shape *shapes, long n);
40 void setFontName(char *str);
41 void setFontLookUpTable(long *lut);
42 void setFontFlags(FontFlags f);
43 long getGlyphCode(long index);
44 long getNbGlyphs();
45 Shape *getGlyph(long index);
46
47 char *getName();
48 FontFlags getFlags();
49
50#ifdef DUMP
51 void dump(BitStream *bs);
52 void dumpFontInfo(BitStream *bs);
53#endif
54};
55
56#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 @@
1////////////////////////////////////////////////////////////
2// Flash Plugin and Player
3// Copyright (C) 1998 Olivier Debon
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19///////////////////////////////////////////////////////////////
20// Author : Olivier Debon <odebon@club-internet.fr>
21//
22
23#include "swf.h"
24
25#ifdef RCSID
26static char *rcsid = "$Id$";
27#endif
28
29#define PRINT 0
30
31// Public
32
33GraphicDevice::GraphicDevice(FlashDisplay *fd)
34{
35 flashDisplay = fd;
36
37 bgInitialized = 0;
38
39 // Reset flash refresh flag
40 flashDisplay->flash_refresh = 0;
41
42 /* 16 bits, RGB565 */
43 redMask = 0xF800;
44 greenMask = 0x07E0;
45 blueMask = 0x001F;
46
47 /* should be the actual window size */
48 targetWidth = fd->width;
49 targetHeight = fd->height;
50 bpl = fd->bpl;
51
52#if PRINT
53 printf("Target Width = %d\n", targetWidth);
54 printf("Target Height = %d\n", targetHeight);
55#endif
56
57 zoom = FRAC;
58 movieWidth = targetWidth;
59 movieHeight = targetHeight;
60
61 viewPort.xmin = 0;
62 viewPort.xmax = targetWidth-1;
63 viewPort.ymin = 0;
64 viewPort.ymax = targetHeight-1;
65
66 canvasBuffer = (unsigned char *) fd->pixels;
67
68 adjust = new Matrix;
69 foregroundColor.red = 0;
70 foregroundColor.green = 0;
71 foregroundColor.blue = 0;
72 foregroundColor.alpha = ALPHA_OPAQUE;
73
74 backgroundColor.red = 0;
75 backgroundColor.green = 0;
76 backgroundColor.blue = 0;
77 backgroundColor.alpha = ALPHA_OPAQUE;
78
79 showMore = 0;
80
81 setClipping(0);// Reset
82 setClipping(1);
83
84 /* polygon rasterizer : handle memory errors ! */
85
86 height = targetHeight;
87 segs = (Segment **)malloc(height * sizeof(Segment *));
88 memset(segs, 0, height * sizeof(Segment *));
89 ymin = height;
90 ymax = -1;
91
92 seg_pool = (Segment *)malloc(NB_SEGMENT_MAX * sizeof(Segment));
93 seg_pool_cur = seg_pool;
94}
95
96GraphicDevice::~GraphicDevice()
97{
98 free(segs);
99 free(seg_pool);
100
101 if (adjust) {
102 delete adjust;
103 }
104}
105
106Color *
107GraphicDevice::getColormap(Color *old, long n, Cxform *cxform)
108{
109 Color *newCmp;
110
111 newCmp = new Color[n];
112 if (newCmp == NULL) return NULL;
113
114 if (cxform) {
115 for(long i = 0; i < n; i++)
116 {
117 newCmp[i] = cxform->getColor(old[i]);
118 newCmp[i].pixel = allocColor(newCmp[i]);
119 }
120 } else {
121 for(long i = 0; i < n; i++)
122 {
123 newCmp[i] = old[i];
124 newCmp[i].pixel = allocColor(old[i]);
125 }
126 }
127
128 return newCmp;
129}
130
131long
132GraphicDevice::getHeight()
133{
134 return targetHeight;
135}
136
137long
138GraphicDevice::getWidth()
139{
140 return targetWidth;
141}
142
143Color
144GraphicDevice::getForegroundColor()
145{
146 return foregroundColor;
147}
148
149void
150GraphicDevice::setForegroundColor(Color color)
151{
152 foregroundColor = color;
153}
154
155Color
156GraphicDevice::getBackgroundColor()
157{
158 return backgroundColor;
159}
160
161int
162GraphicDevice::setBackgroundColor(Color color)
163{
164 if (bgInitialized == 0) {
165 backgroundColor = color;
166 clearCanvas();
167 bgInitialized = 1;
168 return 1;
169 }
170 return 0;
171}
172
173void
174GraphicDevice::setMovieDimension(long width, long height)
175{
176 float xAdjust, yAdjust;
177
178 movieWidth = width;
179 movieHeight = height;
180
181 xAdjust = (float)targetWidth*zoom/(float)width;
182 yAdjust = (float)targetHeight*zoom/(float)height;
183
184 if (xAdjust < yAdjust) {
185 adjust->a = xAdjust;
186 adjust->d = xAdjust;
187 adjust->ty = ((targetHeight*zoom) - (long)(height * xAdjust))/2;
188 viewPort.ymin = adjust->ty/zoom;
189 viewPort.ymax = targetHeight-viewPort.ymin-1;
190 } else {
191 adjust->a = yAdjust;
192 adjust->d = yAdjust;
193 adjust->tx = ((targetWidth*zoom) - (long)(width * yAdjust))/2;
194 viewPort.xmin = adjust->tx/zoom;
195 viewPort.xmax = targetWidth-viewPort.xmin-1;
196 }
197
198 if (viewPort.xmin < 0) viewPort.xmin = 0;
199 if (viewPort.ymin < 0) viewPort.ymin = 0;
200 if (viewPort.xmax >= targetWidth) viewPort.xmax = targetWidth-1;
201 if (viewPort.ymax >= targetHeight) viewPort.ymax = targetHeight-1;
202}
203
204void
205GraphicDevice::setMovieZoom(int z)
206{
207 z *= FRAC;
208 if (z <= 0 || z > 100) return;
209 zoom = z;
210 setMovieDimension(movieWidth,movieHeight);
211}
212
213void
214GraphicDevice::setMovieOffset(long x, long y)
215{
216 adjust->tx = -zoom*x;
217 adjust->ty = -zoom*y;
218}
219
220long
221GraphicDevice::clip(long &y, long &start, long &end)
222{
223 long xmin,xend;
224
225 if (y < clip_rect.ymin ||
226 y >= clip_rect.ymax) return 1;
227 if (end <= start)
228 return 1;
229 xmin = clip_rect.xmin * FRAC;
230 xend = clip_rect.xmax * FRAC;
231
232 if (end <= xmin || start >= xend) return 1;
233
234 if (start < xmin) start = xmin;
235 if (end > xend) end = xend;
236
237 return 0;
238}
239
240void
241GraphicDevice::drawBox(long x1, long y1, long x2, long y2)
242{
243 int i;
244
245 for(i=0;i<FRAC*2;i++) {
246 drawLine(x1+i, y1+i, x2-i, y1+i, 0);
247 drawLine(x1+i, y2-i, x2-i, y2-i, 0);
248
249 drawLine(x1+i, y1+i+1, x1+i, y2-i-1, 0);
250 drawLine(x2-i, y1+i+1, x2-i, y2-i-1, 0);
251 }
252}
253
254/* polygon rasteriser */
255
256inline Segment *
257GraphicDevice::allocSeg()
258{
259 Segment *seg;
260
261 if ( (seg_pool_cur - seg_pool) >= NB_SEGMENT_MAX )
262 return NULL;
263 seg = seg_pool_cur++;
264
265 return seg;
266}
267
268/* add a segment to the current path */
269void
270GraphicDevice::addSegment(long x1, long y1, long x2, long y2,
271 FillStyleDef *f0,
272 FillStyleDef *f1,
273 int aa)
274{
275 Segment *seg,**segs;
276 long dX, X, Y, ymin, ymax, tmp;
277 FillStyleDef *ff;
278
279 if ( y1 == y2 ) {
280 return;
281 }
282
283 if (y1 < y2) {
284 ymin = y1;
285 ymax = y2;
286 ff = f0;
287 f0 = f1;
288 f1 = ff;
289 } else {
290 ymin = y2;
291 ymax = y1;
292 tmp = x1;
293 x1 = x2;
294 x2 = tmp;
295 }
296
297 if (ymax>>FRAC_BITS < clip_rect.ymin) {
298 return;
299 }
300 if (ymin>>FRAC_BITS > clip_rect.ymax) {
301 return;
302 }
303
304 X = x1 << SEGFRAC;
305 dX = ((x2 - x1)<<SEGFRAC)/(ymax-ymin);
306
307 if (ymin < 0) {
308 X += dX * (-ymin);
309 ymin = 0;
310 }
311
312 Y = (ymin + (FRAC-1)) & ~(FRAC-1);
313 if (Y > ymax) {
314 //printf("Elimine @ y = %d ymin = %d, ymax = %d\n", Y, ymin, seg->ymax);
315 return;
316 }
317 X += dX * (Y-ymin);
318
319 Y >>= FRAC_BITS;
320 if (Y >= clip_rect.ymax) {
321 return;
322 }
323
324 seg = allocSeg();
325 if (seg == NULL) {
326 return;
327 }
328
329 seg->next = 0;
330 seg->nextValid = 0;
331 seg->aa = aa;
332 seg->ymax = ymax;
333 seg->x1 = x1;
334 seg->x2 = x2;
335 seg->X = X;
336 seg->dX = dX;
337 seg->fs[0] = f0;
338 seg->fs[1] = f1;
339
340 if (Y < this->ymin) this->ymin = Y;
341 ymax = (seg->ymax + FRAC - 1) >> FRAC_BITS;
342 if (ymax >= this->height) ymax = this->height-1;
343 if (ymax > this->ymax) this->ymax = ymax;
344
345 segs = this->segs;
346
347 if (segs[Y] == 0) {
348 segs[Y] = seg;
349 } else {
350 Segment *s,*prev;
351
352 prev = 0;
353 for(s = segs[Y]; s; prev = s, s = s->next) {
354 if (s->X > seg->X) {
355 if (prev) {
356 prev->next = seg;
357 seg->next = s;
358 } else {
359 seg->next = segs[Y];
360 segs[Y] = seg;
361 }
362 break;
363 }
364 }
365 if (s == 0) {
366 prev->next = seg;
367 seg->next = s;
368 }
369 }
370}
371
372inline Segment *
373GraphicDevice::progressSegments(Segment * curSegs, long y)
374{
375 Segment *seg,*prev;
376
377 // Update current segments
378 seg = curSegs;
379 prev = 0;
380 while(seg)
381 {
382 if ((y*FRAC) > seg->ymax) {
383 // Remove this segment, no more valid
384 if (prev) {
385 prev->nextValid = seg->nextValid;
386 } else {
387 curSegs = seg->nextValid;
388 }
389 seg = seg->nextValid;
390 } else {
391 seg->X += seg->dX * FRAC;
392 prev = seg;
393 seg = seg->nextValid;
394 }
395 }
396 return curSegs;
397}
398
399inline Segment *
400GraphicDevice::newSegments(Segment *curSegs, Segment *newSegs)
401{
402 Segment *s,*seg,*prev;
403
404 s = curSegs;
405 prev = 0;
406
407 // Check for new segments
408 for (seg = newSegs; seg; seg=seg->next)
409 {
410 // Place it at the correct position according to X
411 if (curSegs == 0) {
412 curSegs = seg;
413 seg->nextValid = 0;
414 } else {
415 for(; s; prev = s, s = s->nextValid)
416 {
417 if ( s->X > seg->X ||
418 ( (s->X == seg->X) &&
419 ( (seg->x1 == s->x1 && seg->dX < s->dX) ||
420 (seg->x2 == s->x2 && seg->dX > s->dX)
421 ))) {
422 // Insert before s
423 if (prev) {
424 seg->nextValid = s;
425 prev->nextValid = seg;
426 } else {
427 seg->nextValid = curSegs;
428 curSegs = seg;
429 }
430 break;
431 }
432 }
433 // Append at the end
434 if (s == 0) {
435 prev->nextValid = seg;
436 seg->nextValid = 0;
437 }
438 }
439
440 s = seg;
441 }
442
443 return curSegs;
444}
445
446#if 0
447static void
448printSeg(Segment *seg)
449{
450 /*
451 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,
452 seg->X>>SEGFRAC,
453 seg->right ? seg->right->type: -1,
454 seg->left ? seg->left->color.red : -1,
455 seg->left ? seg->left->color.green : -1,
456 seg->left ? seg->left->color.blue : -1,
457 seg->right ? seg->right->color.red : -1,
458 seg->right ? seg->right->color.green : -1,
459 seg->right ? seg->right->color.blue : -1,
460 seg->x1, seg->x2, seg->ymin, seg->ymax);
461 */
462}
463#endif
464
465inline void
466GraphicDevice::renderScanLine(long y, Segment *curSegs)
467{
468 Segment *seg;
469 long width;
470 int fi = 1;
471 FillStyleDef *f;
472
473 width = targetWidth * FRAC;
474
475 if (curSegs && curSegs->fs[0] && curSegs->fs[1] == 0) {
476 fi = 0;
477 }
478 for(seg = curSegs; seg && seg->nextValid; seg = seg->nextValid)
479 {
480 if (seg->nextValid->X <0) continue;
481 if ((seg->X>>SEGFRAC) > width) break;
482 f = seg->fs[fi];
483 if (f) {
484 switch (f->type) {
485 case f_Solid:
486 if (seg->aa) {
487 fillLineAA(f, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC);
488 } else {
489 fillLine(f, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC);
490 }
491 break;
492 case f_TiledBitmap:
493 case f_clippedBitmap:
494 fillLineBitmap(f, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC);
495 break;
496 case f_LinearGradient:
497 fillLineLG(&f->gradient, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC);
498 break;
499 case f_RadialGradient:
500 fillLineRG(&f->gradient, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC);
501 break;
502 case f_None:
503 break;
504 }
505 }
506 }
507}
508
509/* draw the current path */
510void
511GraphicDevice::drawPolygon(void)
512{
513 long y;
514 Segment *curSegs,*seg;
515
516 // no segments ?
517 if (this->ymax == -1)
518 return;
519
520 // Foreach scanline
521 curSegs = 0;
522 for(y=this->ymin; y <= this->ymax; y++) {
523
524 // Make X values progess and remove unuseful segments
525 curSegs = progressSegments(curSegs, y);
526
527 // Add the new segment starting at the y position.
528 curSegs = newSegments(curSegs, this->segs[y]);
529
530 // Render the scanline
531 if (this->scan_line_func == NULL) {
532 renderScanLine(y, curSegs);
533 } else {
534 for(seg = curSegs; seg && seg->nextValid; seg = seg->nextValid) {
535 if (seg->nextValid->X >= seg->X) {
536 scan_line_func(this->scan_line_func_id, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC);
537 }
538 }
539 }
540 }
541
542 /* free the segments */
543 memset(this->segs + this->ymin, 0,
544 (this->ymax - this->ymin + 1) * sizeof(Segment *));
545
546 this->ymax = -1;
547 this->ymin = this->height;
548
549 this->seg_pool_cur = this->seg_pool;
550}
551
552void
553GraphicDevice::updateClippingRegion(Rect *rect)
554{
555 if (!clipping) return;
556
557 transformBoundingBox(&clip_rect, adjust, rect, 1);
558 clip_rect.xmin >>= FRAC_BITS;
559 clip_rect.xmax >>= FRAC_BITS;
560 clip_rect.ymin >>= FRAC_BITS;
561 clip_rect.ymax >>= FRAC_BITS;
562
563 clip_rect.xmin-=2;
564 clip_rect.ymin-=2;
565 clip_rect.xmax+=2;
566 clip_rect.ymax+=2;
567
568 if (clip_rect.xmin < viewPort.xmin) clip_rect.xmin = viewPort.xmin;
569 if (clip_rect.xmax < viewPort.xmin) clip_rect.xmax = viewPort.xmin;
570 if (clip_rect.ymin < viewPort.ymin) clip_rect.ymin = viewPort.ymin;
571 if (clip_rect.ymax < viewPort.ymin) clip_rect.ymax = viewPort.ymin;
572
573 if (clip_rect.xmax > viewPort.xmax) clip_rect.xmax = viewPort.xmax;
574 if (clip_rect.ymax > viewPort.ymax) clip_rect.ymax = viewPort.ymax;
575 if (clip_rect.xmin > viewPort.xmax) clip_rect.xmin = viewPort.xmax;
576 if (clip_rect.ymin > viewPort.ymax) clip_rect.ymin = viewPort.ymax;
577}
578
579void
580GraphicDevice::setClipping(int value)
581{
582 clipping = value;
583 if (clipping == 0) {
584 // Reset region
585 clip_rect.xmin = viewPort.xmin;
586 clip_rect.xmax = viewPort.xmax;
587 clip_rect.ymin = viewPort.ymin;
588 clip_rect.ymax = viewPort.ymax;
589 }
590}
591
592// Virtual
593void
594GraphicDevice::clearCanvas()
595{
596}
597
598long
599GraphicDevice::allocColor(Color color)
600{
601 return 0;
602}
603
604void
605GraphicDevice::fillLineBitmap(FillStyleDef *f, long y, long start, long end)
606{
607}
608
609void
610GraphicDevice::fillLineLG(Gradient *grad, long y, long start, long end)
611{
612}
613
614void
615GraphicDevice::fillLineRG(Gradient *grad, long y, long start, long end)
616{
617}
618
619void
620GraphicDevice::fillLine(FillStyleDef *f, long y, long start, long end)
621{
622}
623
624void
625GraphicDevice::fillLineAA(FillStyleDef *f, long y, long start, long end)
626{
627}
628
629void
630GraphicDevice::drawLine(long x1, long y1, long x2, long y2, long width)
631{
632}
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 @@
1/////////////////////////////////////////////////////////////
2// Flash Plugin and Player
3// Copyright (C) 1998 Olivier Debon
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19///////////////////////////////////////////////////////////////
20#ifndef _GRAPHIC_H_
21#define _GRAPHIC_H_
22
23#define ALPHA_OPAQUE 255
24
25enum FillType {
26 f_Solid = 0x00,
27 f_LinearGradient = 0x10,
28 f_RadialGradient = 0x12,
29 f_TiledBitmap = 0x40,
30 f_clippedBitmap = 0x41,
31 f_None = 0x80
32};
33
34struct Gradient {
35 int nbGradients;
36 unsigned char ratio[8];
37 Color color[8];
38 // For rendering
39 Color *ramp;
40 Matrix imat;
41 int has_alpha;
42};
43
44
45struct FillStyleDef {
46 FillType type;// See enum FillType
47
48 // Solid
49 Color color;
50
51 // Gradient
52 Gradient gradient;
53
54 // Bitmap
55 Bitmap *bitmap;
56 Matrix bitmap_matrix;
57 Color *cmap;
58 unsigned char *alpha_table;
59
60 // Gradient or Bitmap
61 Matrix matrix;
62
63 FillStyleDef() {
64 style_size += sizeof(FillStyleDef);
65 style_nb++;
66 }
67};
68
69struct Segment {
70 long x1,x2;
71 long ymax;
72 FillStyleDef *fs[2];// 0 is left 1 is right
73 int aa;
74 long dX;
75 long X;
76
77 struct Segment *next;
78 struct Segment *nextValid;
79};
80
81/* fractional bits (we don't use twips here... too expensive) */
82#define FRAC_BITS 5
83#define FRAC (1 << FRAC_BITS)
84#define NB_SEGMENT_MAX (2048*4)
85 #define SEGFRAC 8
86
87class GraphicDevice {
88 int targetWidth;
89 int targetHeight;
90 Rect viewPort;
91 int movieWidth;
92 int movieHeight;
93 int zoom;
94 unsigned long redMask;
95 unsigned long greenMask;
96 unsigned long blueMask;
97 int clipping;
98
99public:
100 FlashDisplay *flashDisplay;
101 int bgInitialized;
102 Color backgroundColor;
103 Color foregroundColor;
104
105public:
106 void *scan_line_func_id;
107 ScanLineFunc scan_line_func;
108 Rect clip_rect;
109
110private:
111 Segment **segs;
112 int ymin,ymax;
113 int height;
114 Segment *seg_pool;
115 Segment *seg_pool_cur;
116
117 Segment * allocSeg();
118 Segment * progressSegments(Segment * curSegs, long y);
119 Segment * newSegments(Segment *curSegs, Segment *newSegs);
120 void renderScanLine(long y, Segment *curSegs);
121
122protected:
123 long clip(long &y, long &start, long &end);
124
125public:
126 Matrix *adjust;// Matrix to fit window (shrink or expand)
127
128 long showMore;// Used for debugging
129
130 // For Direct Graphics
131 unsigned char *canvasBuffer;// A pointer to canvas'memory
132 long bpl;// Bytes per line
133 long bpp;// Bytes per pixel
134 long pad;// Scanline pad in byte
135
136 GraphicDevice(FlashDisplay *fd);
137 virtual ~GraphicDevice();
138
139 int setBackgroundColor(Color);
140 void setForegroundColor(Color);
141 Color getBackgroundColor();
142 Color getForegroundColor();
143 void setMovieDimension(long width, long height);
144 void setMovieZoom(int zoom);
145 void setMovieOffset(long x, long y);
146 long getWidth();
147 long getHeight();
148 Color *getColormap(Color *old, long n, Cxform *cxform);
149
150 void drawBox(long x1, long y1, long x2, long y2);
151
152 void addSegment(long x1, long y1, long x2, long y2,
153 FillStyleDef *f0,
154 FillStyleDef *f1,
155 int aa);
156
157 void drawPolygon(void);
158
159 void updateClippingRegion(Rect *);
160 void setClipping(int);
161
162 // Virtual functions
163 virtual void clearCanvas();
164 virtual long allocColor(Color color);
165 virtual void fillLineBitmap(FillStyleDef *f, long y, long start, long end);
166 virtual void fillLineLG(Gradient *grad, long y, long start, long end);
167 virtual void fillLineRG(Gradient *grad, long y, long start, long end);
168 virtual void fillLine(FillStyleDef *f, long y, long start, long end);
169 virtual void fillLineAA(FillStyleDef *f, long y, long start, long end);
170 virtual void drawLine(long x1, long y1, long x2, long y2, long width);
171
172};
173
174#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 @@
1////////////////////////////////////////////////////////////
2// Flash Plugin and Player
3// Copyright (C) 1998 Olivier Debon
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19///////////////////////////////////////////////////////////////
20// Author : Olivier Debon <odebon@club-internet.fr>
21//
22
23#include "swf.h"
24
25#include "graphic16.h"
26
27extern unsigned char SQRT[];
28
29#define FULL_AA
30
31#define PRINT 0
32
33typedef unsigned short TYPE;
34
35GraphicDevice16::GraphicDevice16(FlashDisplay *fd) : GraphicDevice(fd)
36{
37}
38
39long
40GraphicDevice16::allocColor(Color color)
41{
42 return (color.red >> 3)<<11 | (color.green>>2)<<5 | (color.blue>>3);
43}
44
45void
46GraphicDevice16::clearCanvas()
47{
48 TYPE pixel;
49 TYPE *point,*p;
50 long h, w,n;
51
52 if (!bgInitialized) return;
53
54 pixel = allocColor(backgroundColor);
55
56 point = (TYPE *)(canvasBuffer + clip_rect.ymin * bpl) + clip_rect.xmin;
57 w = clip_rect.xmax - clip_rect.xmin;
58 h = clip_rect.ymax - clip_rect.ymin;
59
60 while (h--) {
61 p = point;
62 n = w;
63 while (n--) {
64 *p++ = pixel;
65 }
66
67 point = (TYPE *)((char *)point + bpl);
68 }
69
70 flashDisplay->flash_refresh = 1;
71 flashDisplay->clip_x = clip_rect.xmin;
72 flashDisplay->clip_y = clip_rect.ymin;
73 flashDisplay->clip_width = clip_rect.xmax-clip_rect.xmin;
74 flashDisplay->clip_height = clip_rect.ymax-clip_rect.ymin;
75}
76
77#define RED_MASK 0xF800
78#define GREEN_MASK 0x07E0
79#define BLUE_MASK 0x001F
80
81/* alpha = 0 : select c1, alpha = 255 select c2 */
82static inline unsigned long
83mix_alpha(unsigned long c1,
84 unsigned long c2, int alpha)
85{
86 long r1,r2,r;
87 long g1,g2,g;
88 long b1,b2,b;
89
90 r1 = c1 & RED_MASK;
91 r2 = c2 & RED_MASK;
92 r = (((r2-r1)*alpha + r1 * 256) >> 8) & RED_MASK;
93
94 g1 = c1 & GREEN_MASK;
95 g2 = c2 & GREEN_MASK;
96 g = (((g2-g1)*alpha + g1 * 256) >> 8) & GREEN_MASK;
97
98 b1 = c1 & BLUE_MASK;
99 b2 = c2 & BLUE_MASK;
100 b = (((b2-b1)*alpha + b1 * 256) >> 8) & BLUE_MASK;
101
102 return (r|g|b);
103}
104
105void
106GraphicDevice16::fillLineAA(FillStyleDef *f, long y, long start, long end)
107{
108 register long n;
109 TYPE *line;
110 TYPE *point,pixel;
111 unsigned int alpha, start_alpha,end_alpha;
112
113 if (clip(y,start,end)) return;
114
115 line = (TYPE *)(canvasBuffer + bpl*y);
116
117 alpha = f->color.alpha;
118 pixel = f->color.pixel;
119
120 if (alpha == ALPHA_OPAQUE) {
121
122 start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
123 end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
124
125 start >>= FRAC_BITS;
126 end >>= FRAC_BITS;
127
128 point = &line[start];
129
130 if (start == end) {
131 *point = mix_alpha(*point, pixel, start_alpha + end_alpha - 255);
132 } else {
133 n = end-start;
134 if (start_alpha < 255) {
135 *point = mix_alpha(*point, pixel, start_alpha);
136 point++;
137 n--;
138 }
139 while (n > 0) {
140 *point = pixel;
141 point++;
142 n--;
143 }
144 if (end_alpha > 0) {
145 *point = mix_alpha(*point, pixel, end_alpha);
146 }
147 }
148 } else {
149
150 start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
151 end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
152
153 start >>= FRAC_BITS;
154 end >>= FRAC_BITS;
155
156 point = &line[start];
157
158 if (start == end) {
159 *point = mix_alpha(*point, pixel,
160 ((start_alpha + end_alpha - 255) * alpha) >> 8);
161 } else {
162 n = end-start;
163 if (start_alpha < 255) {
164 *point = mix_alpha(*point, pixel, (start_alpha * alpha) >> 8);
165 point++;
166 n--;
167 }
168 while (n > 0) {
169 *point = mix_alpha(*point, pixel, alpha);
170 point++;
171 n--;
172 }
173 if (end_alpha > 0) {
174 *point = mix_alpha(*point, pixel, (end_alpha * alpha) >> 8);
175 }
176 }
177 }
178}
179
180void
181GraphicDevice16::fillLine(FillStyleDef *f, long y, long start, long end)
182{
183 register long n;
184 TYPE *line,*point;
185 TYPE pixel;
186 unsigned int alpha;
187
188 if (clip(y,start,end)) return;
189
190 start >>= FRAC_BITS;
191 end >>= FRAC_BITS;
192
193 line = (TYPE *)(canvasBuffer + bpl*y);
194 point = &line[start];
195 n = end-start;
196 pixel = f->color.pixel;
197 alpha = f->color.alpha;
198 if (alpha == ALPHA_OPAQUE) {
199 while (n--) {
200 *point = pixel;
201 point++;
202 }
203 } else {
204 while (n--) {
205 *point = mix_alpha(*point, pixel, alpha);
206 point++;
207 }
208 }
209}
210
211void
212GraphicDevice16::fillLineBitmap(FillStyleDef *f, long y, long start, long end)
213{
214 int n;
215 long x1,y1,dx,dy;
216 Matrix *m = &f->bitmap_matrix;
217 Bitmap *b = f->bitmap;
218 unsigned char *pixels;
219 TYPE *p;
220 Color *cmap;
221 long pixbpl;
222 TYPE pixel;
223 int offset;
224 unsigned char *alpha_table;
225
226 /* safety test) */
227 if (!b) return;
228
229 if (clip(y,start,end)) return;
230
231 start /= FRAC;
232 end /= FRAC;
233 n = end - start;
234 p = (TYPE *) (this->canvasBuffer + this->bpl*y + start * 2);
235
236 /* the coordinates in the image are normalized to 16 bits */
237 x1 = (long) (m->a * start + m->b * y + m->tx);
238 y1 = (long) (m->c * start + m->d * y + m->ty);
239 dx = (long) (m->a);
240 dy = (long) (m->c);
241
242 pixels = b->pixels;
243 pixbpl = b->bpl;
244 cmap = f->cmap;
245
246 if (b->alpha_buf == NULL) {
247 while (n) {
248 if (x1 >= 0 && y1 >= 0 &&
249 (x1 >> 16) < b->width && (y1 >> 16) < b->height) {
250
251 pixel = cmap[pixels[(y1 >> 16) * pixbpl + (x1 >> 16)]].pixel;
252 *p = pixel;
253 }
254 x1 += dx;
255 y1 += dy;
256 p++;
257 n--;
258 }
259 } else if (f->alpha_table) {
260 alpha_table = f->alpha_table;
261 while (n) {
262 if (x1 >= 0 && y1 >= 0 &&
263 (x1 >> 16) < b->width && (y1 >> 16) < b->height) {
264
265 offset = (y1 >> 16) * pixbpl + (x1 >> 16);
266 pixel = cmap[pixels[offset]].pixel;
267 *p = mix_alpha(*p, pixel, alpha_table[b->alpha_buf[offset]]);
268 }
269 x1 += dx;
270 y1 += dy;
271 p++;
272 n--;
273 }
274 } else {
275 while (n) {
276 if (x1 >= 0 && y1 >= 0 &&
277 (x1 >> 16) < b->width && (y1 >> 16) < b->height) {
278
279 offset = (y1 >> 16) * pixbpl + (x1 >> 16);
280 pixel = cmap[pixels[offset]].pixel;
281 *p = mix_alpha(*p, pixel, b->alpha_buf[offset]);
282 }
283 x1 += dx;
284 y1 += dy;
285 p++;
286 n--;
287 }
288 }
289}
290
291void
292GraphicDevice16::fillLineLG(Gradient *grad, long y, long start, long end)
293{
294 long dr,r,v,r2;
295 register long n;
296 TYPE *line;
297 TYPE *point;
298 Color *cp,*ramp;
299 Matrix *m = &grad->imat;
300 unsigned int start_alpha,end_alpha;
301
302 if (clip(y,start,end)) return;
303
304 start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
305 end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
306
307 start /= FRAC;
308 end /= FRAC;
309
310 n = end-start;
311
312 r = (long) (m->a * start + m->b * y + m->tx);
313 dr = (long) (m->a);
314
315 ramp = grad->ramp;
316
317 line = (TYPE *)(canvasBuffer + bpl*y);
318 point = &line[start];
319
320 r2 = r + n * dr;
321 if ( ((r | r2) & ~255) == 0 ) {
322 if (!grad->has_alpha) {
323#ifdef FULL_AA
324 if (start_alpha < 255) {
325 v = r>>16;
326 *point = mix_alpha(*point, (TYPE)ramp[v].pixel, start_alpha);
327 point++;
328 r += dr;
329 n--;
330 }
331#endif /* FULL_AA */
332 while (n>0) {
333 v = r>>16;
334 *point = (TYPE)ramp[v].pixel;
335 point++;
336 r += dr;
337 n--;
338 }
339#ifdef FULL_AA
340 if (end_alpha > 0) {
341 v = r>>16;
342 *point = mix_alpha(*point, (TYPE)ramp[v].pixel, end_alpha);
343 }
344#endif /* FULL_AA */
345 } else {
346 while (n--) {
347 v = r>>16;
348 cp = &ramp[v];
349 *point = mix_alpha(*point, cp->pixel, cp->alpha);
350 point++;
351 r += dr;
352 }
353 }
354 } else {
355 if (!grad->has_alpha) {
356#ifdef FULL_AA
357 if (start_alpha < 255) {
358 v = r>>16;
359 if (v < 0) v = 0;
360 else if (v > 255) v = 255;
361 *point = mix_alpha(*point, (TYPE)ramp[v].pixel, start_alpha);
362 point++;
363 r += dr;
364 n--;
365 }
366#endif /* FULL_AA */
367 while (n>0) {
368 v = r>>16;
369 if (v < 0) v = 0;
370 else if (v > 255) v = 255;
371 *point = (TYPE)ramp[v].pixel;
372 point++;
373 r += dr;
374 n--;
375 }
376#ifdef FULL_AA
377 if (end_alpha > 0) {
378 v = r>>16;
379 if (v < 0) v = 0;
380 else if (v > 255) v = 255;
381 *point = mix_alpha(*point, (TYPE)ramp[v].pixel, end_alpha);
382 }
383#endif /* FULL_AA */
384 } else {
385 while (n--) {
386 v = r>>16;
387 if (v < 0) v = 0;
388 else if (v > 255) v = 255;
389 cp = &ramp[v];
390 *point = mix_alpha(*point, cp->pixel, cp->alpha);
391 point++;
392 r += dr;
393 }
394 }
395 }
396}
397
398void
399GraphicDevice16::fillLineRG(Gradient *grad, long y, long start, long end)
400{
401 long X,dx,r,Y,dy;
402 long dist2;
403 register long n;
404 Color *cp,*ramp;
405 TYPE *line;
406 TYPE *point;
407 Matrix *m = &grad->imat;
408 unsigned int start_alpha,end_alpha;
409
410 if (clip(y,start,end)) return;
411
412 start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
413 end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
414
415 start /= FRAC;
416 end /= FRAC;
417
418 n = end-start;
419
420 X = (long) (m->a * start + m->b * y + m->tx);
421 Y = (long) (m->c * start + m->d * y + m->ty);
422 dx = (long) (m->a);
423 dy = (long) (m->c);
424
425 ramp = grad->ramp;
426
427 line = (TYPE *)(canvasBuffer + bpl*y);
428 point = &line[start];
429
430 if (!grad->has_alpha) {
431#ifdef FULL_AA
432 if (start == end) {
433 dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
434 if ((unsigned long)dist2 >= 65536) {
435 r = 255;
436 } else {
437 r = SQRT[dist2];
438 }
439 *point = mix_alpha(*point, (TYPE)ramp[r].pixel, start_alpha + end_alpha - 255);
440 } else {
441 if (start_alpha < 255) {
442 dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
443 if ((unsigned long)dist2 >= 65536) {
444 r = 255;
445 } else {
446 r = SQRT[dist2];
447 }
448 *point = mix_alpha(*point, (TYPE)ramp[r].pixel, start_alpha);
449 point++;
450 X += dx;
451 Y += dy;
452 n--;
453 }
454#endif /* FULL_AA */
455 while (n>0) {
456 dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
457 if ((unsigned long)dist2 >= 65536) {
458 r = 255;
459 } else {
460 r= SQRT[dist2];
461 }
462 *point = (TYPE)ramp[r].pixel;
463 point++;
464 X += dx;
465 Y += dy;
466 n--;
467 }
468#ifdef FULL_AA
469 if (end_alpha > 0) {
470 dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
471 if ((unsigned long)dist2 >= 65536) {
472 r = 255;
473 } else {
474 r= SQRT[dist2];
475 }
476 *point = mix_alpha(*point, (TYPE)ramp[r].pixel, end_alpha);
477 }
478 }
479#endif /* FULL_AA */
480
481 } else {
482 while (n--) {
483 dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
484 if ((unsigned long)dist2 >= 65536) {
485 r = 255;
486 } else {
487 r= SQRT[dist2];
488 }
489 cp = &ramp[r];
490 *point = mix_alpha(*point, cp->pixel, cp->alpha);
491 point++;
492 X += dx;
493 Y += dy;
494 }
495 }
496}
497
498void
499GraphicDevice16::drawLine(long x1, long y1, long x2, long y2, long width)
500{
501 int n,adr,dx,dy,sx,color;
502 register int a;
503 register TYPE *pp;
504 int alpha;
505
506 x1 = (x1) >> FRAC_BITS;
507 y1 = (y1) >> FRAC_BITS;
508 x2 = (x2) >> FRAC_BITS;
509 y2 = (y2) >> FRAC_BITS;
510
511 if (y1 > y2 || (y1 == y2 && x1 > x2)) {
512 long tmp;
513
514 tmp=x1;
515 x1=x2;
516 x2=tmp;
517
518 tmp=y1;
519 y1=y2;
520 y2=tmp;
521 }
522
523 if (y1 == y2 && (y1 < clip_rect.ymin || y1 > clip_rect.ymax)) return;
524 if (x1 == x2 && (x1 < clip_rect.xmin || x1 > clip_rect.xmax)) return;
525 if (x1 == x2 && y1 == y2) return;// Bad !!!
526
527 if (y1 < clip_rect.ymin && y1 != y2) {
528 x1 += (x2-x1)*(clip_rect.ymin-y1)/(y2-y1);
529 y1 = clip_rect.ymin;
530 }
531
532 if (y2 > clip_rect.ymax && y1 != y2) {
533 x2 -= (x2-x1)*(y2-clip_rect.ymax)/(y2-y1);
534 y2 = clip_rect.ymax;
535 }
536
537 if (x1 < x2) {
538 if (x1 < clip_rect.xmin && x1 != x2) {
539 y1 += (y2-y1)*(clip_rect.xmin-x1)/(x2-x1);
540 x1 = clip_rect.xmin;
541 }
542
543 if (x2 > clip_rect.xmax && x1 != x2) {
544 y2 -= (y2-y1)*(x2-clip_rect.xmax)/(x2-x1);
545 x2 = clip_rect.xmax;
546 }
547 }
548
549 if (x1 > x2) {
550 if (x2 < clip_rect.xmin && x2 != x1) {
551 y2 -= (y2-y1)*(clip_rect.xmin-x2)/(x1-x2);
552 x2 = clip_rect.xmin;
553 }
554
555 if (x1 > clip_rect.xmax && x2 != x1) {
556 y1 += (y2-y1)*(x1-clip_rect.xmax)/(x1-x2);
557 x1 = clip_rect.xmax;
558 }
559 }
560
561 // Check again
562 if (x1 == x2 && y1 == y2) return;
563 if (x1 < clip_rect.xmin || x2 < clip_rect.xmin) return;
564 if (y1 < clip_rect.ymin || y2 < clip_rect.ymin) return;
565 if (x1 > clip_rect.xmax || x2 > clip_rect.xmax) return;
566 if (y1 > clip_rect.ymax || y2 > clip_rect.ymax) return;
567
568 sx=bpl >> 1;
569 adr=(y1 * sx + x1);
570 pp = (TYPE *)canvasBuffer + adr;
571
572 dx = x2 - x1;
573 dy = y2 - y1;
574
575 color = allocColor(foregroundColor);
576 alpha = foregroundColor.alpha;
577
578 if (alpha == ALPHA_OPAQUE) {
579
580 #define PUTPIXEL() \
581 { \
582 *pp=color; \
583 }
584
585#define DRAWLINE(dx,dy,inc_1,inc_2) \
586 n=dx;\
587 a=2*dy-dx;\
588 dy=2*dy;\
589 dx=2*dx-dy;\
590 do {\
591 PUTPIXEL();\
592 if (a>0) { pp+=(inc_1); a-=dx; }\
593 else { pp+=(inc_2); a+=dy; }\
594 } while (--n >= 0);
595
596/* fin macro */
597
598 if (dx == 0 && dy == 0) {
599 PUTPIXEL();
600 } else if (dx > 0) {
601 if (dx >= dy) {
602 DRAWLINE(dx, dy, sx + 1, 1);
603 } else {
604 DRAWLINE(dy, dx, sx + 1, sx);
605 }
606 } else {
607 dx = -dx;
608 if (dx >= dy) {
609 DRAWLINE(dx, dy, sx - 1, -1);
610 } else {
611 DRAWLINE(dy, dx, sx - 1, sx);
612 }
613 }
614
615
616#undef DRAWLINE
617#undef PUTPIXEL
618 } else {
619 #define PUTPIXEL() \
620 { \
621 *pp=mix_alpha(*pp,color,alpha); \
622 }
623
624#define DRAWLINE(dx,dy,inc_1,inc_2) \
625 n=dx;\
626 a=2*dy-dx;\
627 dy=2*dy;\
628 dx=2*dx-dy;\
629 do {\
630 PUTPIXEL();\
631 if (a>0) { pp+=(inc_1); a-=dx; }\
632 else { pp+=(inc_2); a+=dy; }\
633 } while (--n >= 0);
634
635/* fin macro */
636
637 if (dx == 0 && dy == 0) {
638 PUTPIXEL();
639 } else if (dx > 0) {
640 if (dx >= dy) {
641 DRAWLINE(dx, dy, sx + 1, 1);
642 } else {
643 DRAWLINE(dy, dx, sx + 1, sx);
644 }
645 } else {
646 dx = -dx;
647 if (dx >= dy) {
648 DRAWLINE(dx, dy, sx - 1, -1);
649 } else {
650 DRAWLINE(dy, dx, sx - 1, sx);
651 }
652 }
653
654
655#undef DRAWLINE
656#undef PUTPIXEL
657 }
658}
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 @@
1////////////////////////////////////////////////////////////
2// Flash Plugin and Player
3// Copyright (C) 1998 Olivier Debon
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19///////////////////////////////////////////////////////////////
20// Author : Olivier Debon <odebon@club-internet.fr>
21//
22
23#include "swf.h"
24
25class GraphicDevice16: public GraphicDevice {
26private:
27 long GraphicDevice16::allocColor(Color color);
28
29public:
30 GraphicDevice16(FlashDisplay *fd);
31
32 void clearCanvas();
33 void fillLineAA(FillStyleDef *f, long y, long start, long end);
34 void fillLine(FillStyleDef *f, long y, long start, long end);
35 void fillLineBitmap(FillStyleDef *f, long y, long start, long end);
36 void fillLineLG(Gradient *grad, long y, long start, long end);
37 void fillLineRG(Gradient *grad, long y, long start, long end);
38 void drawLine(long x1, long y1, long x2, long y2, long width);
39};
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 @@
1////////////////////////////////////////////////////////////
2// Flash Plugin and Player
3// Copyright (C) 1998 Olivier Debon
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19///////////////////////////////////////////////////////////////
20// Author : Olivier Debon <odebon@club-internet.fr>
21//
22
23#include "swf.h"
24
25#include "graphic24.h"
26
27extern unsigned char SQRT[];
28
29#define FULL_AA
30
31#define PRINT 0
32
33typedef unsigned char TYPE;
34#define BPP 3
35
36GraphicDevice24::GraphicDevice24(FlashDisplay *fd) : GraphicDevice(fd)
37{
38}
39
40long
41GraphicDevice24::allocColor(Color color)
42{
43 return 0;
44}
45
46void
47GraphicDevice24::clearCanvas()
48{
49 TYPE *point,*p;
50 long h, w,n;
51
52 if (!bgInitialized) return;
53
54 point = (TYPE *)(canvasBuffer + clip_rect.ymin * bpl) + clip_rect.xmin*BPP;
55 w = clip_rect.xmax - clip_rect.xmin;
56 h = clip_rect.ymax - clip_rect.ymin;
57
58 while (h--) {
59 p = point;
60 n = w;
61 while (n--) {
62 *p++ = backgroundColor.blue;
63 *p++ = backgroundColor.green;
64 *p++ = backgroundColor.red;
65 }
66
67 point = (TYPE *)((char *)point + bpl);
68 }
69
70 flashDisplay->flash_refresh = 1;
71 flashDisplay->clip_x = clip_rect.xmin;
72 flashDisplay->clip_y = clip_rect.ymin;
73 flashDisplay->clip_width = clip_rect.xmax-clip_rect.xmin;
74 flashDisplay->clip_height = clip_rect.ymax-clip_rect.ymin;
75}
76
77/* alpha = 0 : select c1, alpha = 255 select c2 */
78static inline void mix_alpha(TYPE *c1, Color c2, int alpha)
79{
80 *c1 = (((c2.blue- (*c1))*alpha + (*c1) * 256) >> 8);
81 c1++;
82 *c1 = (((c2.green- (*c1))*alpha + (*c1) * 256) >> 8);
83 c1++;
84 *c1 = (((c2.red- (*c1))*alpha + (*c1) * 256) >> 8);
85}
86
87void
88GraphicDevice24::fillLineAA(FillStyleDef *f, long y, long start, long end)
89{
90 register long n;
91 TYPE *line;
92 TYPE *point;
93 Color pixel;
94 unsigned int alpha, start_alpha,end_alpha;
95
96 if (clip(y,start,end)) return;
97
98 line = (TYPE *)(canvasBuffer + bpl*y);
99
100 alpha = f->color.alpha;
101 pixel = f->color;
102
103 if (alpha == ALPHA_OPAQUE) {
104
105 start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
106 end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
107
108 start >>= FRAC_BITS;
109 end >>= FRAC_BITS;
110
111 point = &line[start*BPP];
112
113 if (start == end) {
114 mix_alpha(point, pixel, start_alpha + end_alpha - 255);
115 } else {
116 n = end-start;
117 if (start_alpha < 255) {
118 mix_alpha(point, pixel, start_alpha);
119 point += BPP;
120 n--;
121 }
122 while (n > 0) {
123 *point++ = pixel.blue;
124 *point++ = pixel.green;
125 *point++ = pixel.red;
126 n--;
127 }
128 if (end_alpha > 0) {
129 mix_alpha(point, pixel, end_alpha);
130 }
131 }
132 } else {
133
134 start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
135 end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
136
137 start >>= FRAC_BITS;
138 end >>= FRAC_BITS;
139
140 point = &line[start*BPP];
141
142 if (start == end) {
143 mix_alpha(point, pixel, ((start_alpha + end_alpha - 255) * alpha) >> 8);
144 } else {
145 n = end-start;
146 if (start_alpha < 255) {
147 mix_alpha(point, pixel, (start_alpha * alpha) >> 8);
148 point+=BPP;
149 n--;
150 }
151 while (n > 0) {
152 mix_alpha(point, pixel, alpha);
153 point+=BPP;
154 n--;
155 }
156 if (end_alpha > 0) {
157 mix_alpha(point, pixel, (end_alpha * alpha) >> 8);
158 }
159 }
160 }
161}
162
163void
164GraphicDevice24::fillLine(FillStyleDef *f, long y, long start, long end)
165{
166 register long n;
167 TYPE *line,*point;
168 Color pixel;
169 unsigned int alpha;
170
171 if (clip(y,start,end)) return;
172
173 start >>= FRAC_BITS;
174 end >>= FRAC_BITS;
175
176 line = (TYPE *)(canvasBuffer + bpl*y);
177 point = &line[start*BPP];
178 n = end-start;
179 alpha = f->color.alpha;
180 pixel = f->color;
181 if (alpha == ALPHA_OPAQUE) {
182 while (n--) {
183 *point++ = pixel.blue;
184 *point++ = pixel.green;
185 *point++ = pixel.red;
186 }
187 } else {
188 while (n--) {
189 mix_alpha(point, pixel, alpha);
190 point+=BPP;
191 }
192 }
193}
194
195void
196GraphicDevice24::fillLineBitmap(FillStyleDef *f, long y, long start, long end)
197{
198 int n;
199 long x1,y1,dx,dy;
200 Matrix *m = &f->bitmap_matrix;
201 Bitmap *b = f->bitmap;
202 unsigned char *pixels;
203 TYPE *p;
204 Color *cmap;
205 long pixbpl;
206 Color pixel;
207 int offset;
208 unsigned char *alpha_table;
209
210 /* safety test) */
211 if (!b) return;
212
213 if (clip(y,start,end)) return;
214
215 start /= FRAC;
216 end /= FRAC;
217 n = end - start;
218 p = (TYPE *) (canvasBuffer + bpl*y + start*BPP);
219
220 x1 = (long) (m->a * start + m->b * y + m->tx);
221 y1 = (long) (m->c * start + m->d * y + m->ty);
222 dx = (long) (m->a);
223 dy = (long) (m->c);
224
225 pixels = b->pixels;
226 pixbpl = b->bpl;
227 cmap = f->cmap;
228
229 if (b->alpha_buf == NULL) {
230 while (n) {
231 if (x1 >= 0 && y1 >= 0 &&
232 (x1 >> 16) < b->width && (y1 >> 16) < b->height) {
233
234 pixel = cmap[pixels[(y1 >> 16) * pixbpl + (x1 >> 16)]];
235 *p++ = pixel.blue;
236 *p++ = pixel.green;
237 *p++ = pixel.red;
238 } else {
239 p+=BPP;
240 }
241 x1 += dx;
242 y1 += dy;
243 n--;
244 }
245 } else if (f->alpha_table) {
246 alpha_table = f->alpha_table;
247 while (n) {
248 if (x1 >= 0 && y1 >= 0 &&
249 (x1 >> 16) < b->width && (y1 >> 16) < b->height) {
250
251 offset = (y1 >> 16) * pixbpl + (x1 >> 16);
252 mix_alpha(p, cmap[pixels[offset]], alpha_table[b->alpha_buf[offset]]);
253 }
254 p+=BPP;
255 x1 += dx;
256 y1 += dy;
257 n--;
258 }
259 } else {
260 while (n) {
261 if (x1 >= 0 && y1 >= 0 &&
262 (x1 >> 16) < b->width && (y1 >> 16) < b->height) {
263
264 offset = (y1 >> 16) * pixbpl + (x1 >> 16);
265 mix_alpha(p, cmap[pixels[offset]], b->alpha_buf[offset]);
266 }
267 p+=BPP;
268 x1 += dx;
269 y1 += dy;
270 n--;
271 }
272 }
273}
274
275void
276GraphicDevice24::fillLineLG(Gradient *grad, long y, long start, long end)
277{
278 long dr,r,v,r2;
279 register long n;
280 TYPE *line;
281 TYPE *point;
282 Color *cp,*ramp;
283 Matrix *m = &grad->imat;
284 unsigned int start_alpha,end_alpha;
285
286 if (clip(y,start,end)) return;
287
288 start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
289 end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
290
291 start /= FRAC;
292 end /= FRAC;
293
294 n = end-start;
295
296 r = (long) (m->a * start + m->b * y + m->tx);
297 dr = (long) (m->a);
298
299 ramp = grad->ramp;
300
301 line = (TYPE *)(canvasBuffer + bpl*y);
302 point = &line[start*BPP];
303
304 r2 = r + n * dr;
305 if ( ((r | r2) & ~255) == 0 ) {
306 if (!grad->has_alpha) {
307#ifdef FULL_AA
308 if (start_alpha < 255) {
309 v = r>>16;
310 mix_alpha(point, ramp[v], start_alpha);
311 point+=BPP;
312 r += dr;
313 n--;
314 }
315#endif /* FULL_AA */
316 while (n>0) {
317 v = r>>16;
318 *point++ = ramp[v].blue;
319 *point++ = ramp[v].green;
320 *point++ = ramp[v].red;
321 r += dr;
322 n--;
323 }
324#ifdef FULL_AA
325 if (end_alpha > 0) {
326 v = r>>16;
327 mix_alpha(point, ramp[v], end_alpha);
328 }
329#endif /* FULL_AA */
330 } else {
331 while (n--) {
332 v = r>>16;
333 cp = &ramp[v];
334 mix_alpha(point, *cp, cp->alpha);
335 point+=BPP;
336 r += dr;
337 }
338 }
339 } else {
340 if (!grad->has_alpha) {
341#ifdef FULL_AA
342 if (start_alpha < 255) {
343 v = r>>16;
344 if (v < 0) v = 0;
345 else if (v > 255) v = 255;
346 mix_alpha(point, ramp[v], start_alpha);
347 point+=BPP;
348 r += dr;
349 n--;
350 }
351#endif /* FULL_AA */
352 while (n>0) {
353 v = r>>16;
354 if (v < 0) v = 0;
355 else if (v > 255) v = 255;
356 *point++ = ramp[v].blue;
357 *point++ = ramp[v].green;
358 *point++ = ramp[v].red;
359 r += dr;
360 n--;
361 }
362#ifdef FULL_AA
363 if (end_alpha > 0) {
364 v = r>>16;
365 if (v < 0) v = 0;
366 else if (v > 255) v = 255;
367 mix_alpha(point, ramp[v], end_alpha);
368 }
369#endif /* FULL_AA */
370 } else {
371 while (n--) {
372 v = r>>16;
373 if (v < 0) v = 0;
374 else if (v > 255) v = 255;
375 cp = &ramp[v];
376 mix_alpha(point, *cp, cp->alpha);
377 point+=BPP;
378 r += dr;
379 }
380 }
381 }
382}
383
384void
385GraphicDevice24::fillLineRG(Gradient *grad, long y, long start, long end)
386{
387 long X,dx,r,Y,dy;
388 long dist2;
389 register long n;
390 Color *cp,*ramp;
391 TYPE *line;
392 TYPE *point;
393 Matrix *m = &grad->imat;
394 unsigned int start_alpha,end_alpha;
395
396 if (clip(y,start,end)) return;
397
398 start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
399 end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
400
401 start /= FRAC;
402 end /= FRAC;
403
404 n = end-start;
405
406 X = (long) (m->a * start + m->b * y + m->tx);
407 Y = (long) (m->c * start + m->d * y + m->ty);
408 dx = (long) (m->a);
409 dy = (long) (m->c);
410
411 ramp = grad->ramp;
412
413 line = (TYPE *)(canvasBuffer + bpl*y);
414 point = &line[start*BPP];
415
416 if (!grad->has_alpha) {
417#ifdef FULL_AA
418 if (start == end) {
419 dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
420 if ((unsigned long)dist2 >= 65536) {
421 r = 255;
422 } else {
423 r= SQRT[dist2];
424 }
425 mix_alpha(point, ramp[r], start_alpha + end_alpha - 255);
426 } else {
427 if (start_alpha < 255) {
428 dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
429 if ((unsigned long)dist2 >= 65536) {
430 r = 255;
431 } else {
432 r= SQRT[dist2];
433 }
434 mix_alpha(point, ramp[r], start_alpha);
435 point+=BPP;
436 X += dx;
437 Y += dy;
438 n--;
439 }
440#endif /* FULL_AA */
441 while (n>0) {
442 dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
443 if ((unsigned long)dist2 >= 65536) {
444 r = 255;
445 } else {
446 r= SQRT[dist2];
447 }
448 *point++ = ramp[r].blue;
449 *point++ = ramp[r].green;
450 *point++ = ramp[r].red;
451 X += dx;
452 Y += dy;
453 n--;
454 }
455#ifdef FULL_AA
456 if (end_alpha > 0) {
457 dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
458 if ((unsigned long)dist2 >= 65536) {
459 r = 255;
460 } else {
461 r= SQRT[dist2];
462 }
463 mix_alpha(point, ramp[r], end_alpha);
464 }
465 }
466#endif /* FULL_AA */
467
468 } else {
469 while (n--) {
470 dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
471 if ((unsigned long)dist2 >= 65536) {
472 r = 255;
473 } else {
474 r= SQRT[dist2];
475 }
476 cp = &ramp[r];
477 mix_alpha(point, *cp, cp->alpha);
478 point+=BPP;
479 X += dx;
480 Y += dy;
481 }
482 }
483}
484
485void
486GraphicDevice24::drawLine(long x1, long y1, long x2, long y2, long width)
487{
488 int n,adr,dx,dy,sx;
489 Color color;
490 register int a;
491 register TYPE *pp;
492 int alpha;
493
494 x1 = (x1) >> FRAC_BITS;
495 y1 = (y1) >> FRAC_BITS;
496 x2 = (x2) >> FRAC_BITS;
497 y2 = (y2) >> FRAC_BITS;
498
499 if (y1 > y2 || (y1 == y2 && x1 > x2)) {
500 long tmp;
501
502 tmp=x1;
503 x1=x2;
504 x2=tmp;
505
506 tmp=y1;
507 y1=y2;
508 y2=tmp;
509 }
510
511 if (y1 == y2 && (y1 < clip_rect.ymin || y1 > clip_rect.ymax)) return;
512 if (x1 == x2 && (x1 < clip_rect.xmin || x1 > clip_rect.xmax)) return;
513 if (x1 == x2 && y1 == y2) return;// Bad !!!
514
515 if (y1 < clip_rect.ymin && y1 != y2) {
516 x1 += (x2-x1)*(clip_rect.ymin-y1)/(y2-y1);
517 y1 = clip_rect.ymin;
518 }
519
520 if (y2 > clip_rect.ymax && y1 != y2) {
521 x2 -= (x2-x1)*(y2-clip_rect.ymax)/(y2-y1);
522 y2 = clip_rect.ymax;
523 }
524
525 if (x1 < x2) {
526 if (x1 < clip_rect.xmin && x1 != x2) {
527 y1 += (y2-y1)*(clip_rect.xmin-x1)/(x2-x1);
528 x1 = clip_rect.xmin;
529 }
530
531 if (x2 > clip_rect.xmax && x1 != x2) {
532 y2 -= (y2-y1)*(x2-clip_rect.xmax)/(x2-x1);
533 x2 = clip_rect.xmax;
534 }
535 }
536
537 if (x1 > x2) {
538 if (x2 < clip_rect.xmin && x2 != x1) {
539 y2 -= (y2-y1)*(clip_rect.xmin-x2)/(x1-x2);
540 x2 = clip_rect.xmin;
541 }
542
543 if (x1 > clip_rect.xmax && x2 != x1) {
544 y1 += (y2-y1)*(x1-clip_rect.xmax)/(x1-x2);
545 x1 = clip_rect.xmax;
546 }
547 }
548
549 // Check again
550 if (x1 == x2 && y1 == y2) return;
551 if (x1 < clip_rect.xmin || x2 < clip_rect.xmin) return;
552 if (y1 < clip_rect.ymin || y2 < clip_rect.ymin) return;
553 if (x1 > clip_rect.xmax || x2 > clip_rect.xmax) return;
554 if (y1 > clip_rect.ymax || y2 > clip_rect.ymax) return;
555
556 sx=bpl >> 1;
557 adr=(y1 * sx + x1);
558 pp = (TYPE *)canvasBuffer + adr;
559
560 dx = x2 - x1;
561 dy = y2 - y1;
562
563 color = foregroundColor;
564 alpha = foregroundColor.alpha;
565
566 if (alpha == ALPHA_OPAQUE) {
567
568 #define PUTPIXEL() \
569 { \
570 *pp++=color.red; \
571 *pp++=color.green; \
572 *pp++=color.blue; \
573 }
574
575#define DRAWLINE(dx,dy,inc_1,inc_2) \
576 n=dx;\
577 a=2*dy-dx;\
578 dy=2*dy;\
579 dx=2*dx-dy;\
580 do {\
581 PUTPIXEL();\
582 if (a>0) { pp+=(inc_1); a-=dx; }\
583 else { pp+=(inc_2); a+=dy; }\
584 } while (--n >= 0);
585
586/* fin macro */
587
588 if (dx == 0 && dy == 0) {
589 PUTPIXEL();
590 } else if (dx > 0) {
591 if (dx >= dy) {
592 DRAWLINE(dx, dy, sx + 1, 1);
593 } else {
594 DRAWLINE(dy, dx, sx + 1, sx);
595 }
596 } else {
597 dx = -dx;
598 if (dx >= dy) {
599 DRAWLINE(dx, dy, sx - 1, -1);
600 } else {
601 DRAWLINE(dy, dx, sx - 1, sx);
602 }
603 }
604
605
606#undef DRAWLINE
607#undef PUTPIXEL
608 } else {
609 #define PUTPIXEL() \
610 { \
611 mix_alpha(pp,color,alpha); \
612 }
613
614#define DRAWLINE(dx,dy,inc_1,inc_2) \
615 n=dx;\
616 a=2*dy-dx;\
617 dy=2*dy;\
618 dx=2*dx-dy;\
619 do {\
620 PUTPIXEL();\
621 if (a>0) { pp+=(inc_1*BPP); a-=dx; }\
622 else { pp+=(inc_2*BPP); a+=dy; }\
623 } while (--n >= 0);
624
625/* fin macro */
626
627 if (dx == 0 && dy == 0) {
628 PUTPIXEL();
629 } else if (dx > 0) {
630 if (dx >= dy) {
631 DRAWLINE(dx, dy, sx + 1, 1);
632 } else {
633 DRAWLINE(dy, dx, sx + 1, sx);
634 }
635 } else {
636 dx = -dx;
637 if (dx >= dy) {
638 DRAWLINE(dx, dy, sx - 1, -1);
639 } else {
640 DRAWLINE(dy, dx, sx - 1, sx);
641 }
642 }
643
644
645#undef DRAWLINE
646#undef PUTPIXEL
647 }
648}
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 @@
1////////////////////////////////////////////////////////////
2// Flash Plugin and Player
3// Copyright (C) 1998 Olivier Debon
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19///////////////////////////////////////////////////////////////
20// Author : Olivier Debon <odebon@club-internet.fr>
21//
22
23#include "swf.h"
24
25class GraphicDevice24: public GraphicDevice {
26private:
27 long GraphicDevice24::allocColor(Color color);
28
29public:
30 GraphicDevice24(FlashDisplay *fd);
31
32 void clearCanvas();
33 void fillLineAA(FillStyleDef *f, long y, long start, long end);
34 void fillLine(FillStyleDef *f, long y, long start, long end);
35 void fillLineBitmap(FillStyleDef *f, long y, long start, long end);
36 void fillLineLG(Gradient *grad, long y, long start, long end);
37 void fillLineRG(Gradient *grad, long y, long start, long end);
38 void drawLine(long x1, long y1, long x2, long y2, long width);
39};
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 @@
1////////////////////////////////////////////////////////////
2// Flash Plugin and Player
3// Copyright (C) 1998 Olivier Debon
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19///////////////////////////////////////////////////////////////
20// Author : Olivier Debon <odebon@club-internet.fr>
21//
22
23#include "swf.h"
24
25#include "graphic32.h"
26
27extern unsigned char SQRT[];
28
29#define FULL_AA
30
31#define PRINT 0
32
33typedef unsigned long TYPE;
34
35GraphicDevice32::GraphicDevice32(FlashDisplay *fd) : GraphicDevice(fd)
36{
37}
38
39long
40GraphicDevice32::allocColor(Color color)
41{
42 return (color.red)<<16 | (color.green)<<8 | (color.blue);
43}
44
45void
46GraphicDevice32::clearCanvas()
47{
48 TYPE pixel;
49 TYPE *point,*p;
50 long h, w,n;
51
52 if (!bgInitialized) return;
53
54 pixel = allocColor(backgroundColor);
55
56 point = (TYPE *)(canvasBuffer + clip_rect.ymin * bpl) + clip_rect.xmin;
57 w = clip_rect.xmax - clip_rect.xmin;
58 h = clip_rect.ymax - clip_rect.ymin;
59
60 while (h--) {
61 p = point;
62 n = w;
63 while (n--) {
64 *p++ = pixel;
65 }
66
67 point = (TYPE *)((char *)point + bpl);
68 }
69
70 flashDisplay->flash_refresh = 1;
71 flashDisplay->clip_x = clip_rect.xmin;
72 flashDisplay->clip_y = clip_rect.ymin;
73 flashDisplay->clip_width = clip_rect.xmax-clip_rect.xmin;
74 flashDisplay->clip_height = clip_rect.ymax-clip_rect.ymin;
75}
76
77#define RED_MASK 0xFF0000
78#define GREEN_MASK 0x00FF00
79#define BLUE_MASK 0x0000FF
80
81/* alpha = 0 : select c1, alpha = 255 select c2 */
82static inline unsigned long
83mix_alpha(unsigned long c1, unsigned long c2, int alpha)
84{
85 long r1,r2,r;
86 long g1,g2,g;
87 long b1,b2,b;
88
89 r1 = c1 & RED_MASK;
90 r2 = c2 & RED_MASK;
91 r = (((r2-r1)*alpha + r1 * 256) >> 8) & RED_MASK;
92
93 g1 = c1 & GREEN_MASK;
94 g2 = c2 & GREEN_MASK;
95 g = (((g2-g1)*alpha + g1 * 256) >> 8) & GREEN_MASK;
96
97 b1 = c1 & BLUE_MASK;
98 b2 = c2 & BLUE_MASK;
99 b = (((b2-b1)*alpha + b1 * 256) >> 8) & BLUE_MASK;
100
101 return (r|g|b);
102}
103
104void
105GraphicDevice32::fillLineAA(FillStyleDef *f, long y, long start, long end)
106{
107 register long n;
108 TYPE *line;
109 TYPE *point,pixel;
110 unsigned int alpha, start_alpha,end_alpha;
111
112 if (clip(y,start,end)) return;
113
114 line = (TYPE *)(canvasBuffer + bpl*y);
115
116 alpha = f->color.alpha;
117 pixel = f->color.pixel;
118
119 if (alpha == ALPHA_OPAQUE) {
120
121 start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
122 end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
123
124 start >>= FRAC_BITS;
125 end >>= FRAC_BITS;
126
127 point = &line[start];
128
129 if (start == end) {
130 *point = mix_alpha(*point, pixel, start_alpha + end_alpha - 255);
131 } else {
132 n = end-start;
133 if (start_alpha < 255) {
134 *point = mix_alpha(*point, pixel, start_alpha);
135 point++;
136 n--;
137 }
138 while (n > 0) {
139 *point = pixel;
140 point++;
141 n--;
142 }
143 if (end_alpha > 0) {
144 *point = mix_alpha(*point, pixel, end_alpha);
145 }
146 }
147 } else {
148
149 start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
150 end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
151
152 start >>= FRAC_BITS;
153 end >>= FRAC_BITS;
154
155 point = &line[start];
156
157 if (start == end) {
158 *point = mix_alpha(*point, pixel,
159 ((start_alpha + end_alpha - 255) * alpha) >> 8);
160 } else {
161 n = end-start;
162 if (start_alpha < 255) {
163 *point = mix_alpha(*point, pixel, (start_alpha * alpha) >> 8);
164 point++;
165 n--;
166 }
167 while (n > 0) {
168 *point = mix_alpha(*point, pixel, alpha);
169 point++;
170 n--;
171 }
172 if (end_alpha > 0) {
173 *point = mix_alpha(*point, pixel, (end_alpha * alpha) >> 8);
174 }
175 }
176 }
177}
178
179void
180GraphicDevice32::fillLine(FillStyleDef *f, long y, long start, long end)
181{
182 register long n;
183 TYPE *line,*point;
184 TYPE pixel;
185 unsigned int alpha;
186
187 if (clip(y,start,end)) return;
188
189 start >>= FRAC_BITS;
190 end >>= FRAC_BITS;
191
192 line = (TYPE *)(canvasBuffer + bpl*y);
193 point = &line[start];
194 n = end-start;
195 pixel = f->color.pixel;
196 alpha = f->color.alpha;
197 if (alpha == ALPHA_OPAQUE) {
198 while (n--) {
199 *point = pixel;
200 point++;
201 }
202 } else {
203 while (n--) {
204 *point = mix_alpha(*point, pixel, alpha);
205 point++;
206 }
207 }
208}
209
210void
211GraphicDevice32::fillLineBitmap(FillStyleDef *f, long y, long start, long end)
212{
213 int n;
214 long x1,y1,dx,dy;
215 Matrix *m = &f->bitmap_matrix;
216 Bitmap *b = f->bitmap;
217 unsigned char *pixels;
218 TYPE *p;
219 Color *cmap;
220 long pixbpl;
221 TYPE pixel;
222 int offset;
223 unsigned char *alpha_table;
224
225 /* safety test) */
226 if (!b) return;
227
228 if (clip(y,start,end)) return;
229
230 start /= FRAC;
231 end /= FRAC;
232 n = end - start;
233 p = (TYPE *) (this->canvasBuffer + this->bpl*y + start * sizeof(TYPE));
234
235 /* the coordinates in the image are normalized to 16 bits */
236 x1 = (long) (m->a * start + m->b * y + m->tx);
237 y1 = (long) (m->c * start + m->d * y + m->ty);
238 dx = (long) (m->a);
239 dy = (long) (m->c);
240
241 pixels = b->pixels;
242 pixbpl = b->bpl;
243 cmap = f->cmap;
244
245 if (b->alpha_buf == NULL) {
246 while (n) {
247 if (x1 >= 0 && y1 >= 0 &&
248 (x1 >> 16) < b->width && (y1 >> 16) < b->height) {
249
250 pixel = cmap[pixels[(y1 >> 16) * pixbpl + (x1 >> 16)]].pixel;
251 *p = pixel;
252 }
253 x1 += dx;
254 y1 += dy;
255 p++;
256 n--;
257 }
258 } else if (f->alpha_table) {
259 alpha_table = f->alpha_table;
260 while (n) {
261 if (x1 >= 0 && y1 >= 0 &&
262 (x1 >> 16) < b->width && (y1 >> 16) < b->height) {
263
264 offset = (y1 >> 16) * pixbpl + (x1 >> 16);
265 pixel = cmap[pixels[offset]].pixel;
266 *p = mix_alpha(*p, pixel, alpha_table[b->alpha_buf[offset]]);
267 }
268 x1 += dx;
269 y1 += dy;
270 p++;
271 n--;
272 }
273 } else {
274 while (n) {
275 if (x1 >= 0 && y1 >= 0 &&
276 (x1 >> 16) < b->width && (y1 >> 16) < b->height) {
277
278 offset = (y1 >> 16) * pixbpl + (x1 >> 16);
279 pixel = cmap[pixels[offset]].pixel;
280 *p = mix_alpha(*p, pixel, b->alpha_buf[offset]);
281 }
282 x1 += dx;
283 y1 += dy;
284 p++;
285 n--;
286 }
287 }
288}
289
290void
291GraphicDevice32::fillLineLG(Gradient *grad, long y, long start, long end)
292{
293 long dr,r,v,r2;
294 register long n;
295 TYPE *line;
296 TYPE *point;
297 Color *cp,*ramp;
298 Matrix *m = &grad->imat;
299 unsigned int start_alpha,end_alpha;
300
301 if (clip(y,start,end)) return;
302
303 start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
304 end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
305
306 start /= FRAC;
307 end /= FRAC;
308
309 n = end-start;
310
311 r = (long) (m->a * start + m->b * y + m->tx);
312 dr = (long) (m->a);
313
314 ramp = grad->ramp;
315
316 line = (TYPE *)(canvasBuffer + bpl*y);
317 point = &line[start];
318
319 r2 = r + n * dr;
320 if ( ((r | r2) & ~255) == 0 ) {
321 if (!grad->has_alpha) {
322#ifdef FULL_AA
323 if (start_alpha < 255) {
324 v = r>>16;
325 *point = mix_alpha(*point, (TYPE)ramp[v].pixel, start_alpha);
326 point++;
327 r += dr;
328 n--;
329 }
330#endif /* FULL_AA */
331 while (n>0) {
332 v = r>>16;
333 *point = (TYPE)ramp[v].pixel;
334 point++;
335 r += dr;
336 n--;
337 }
338#ifdef FULL_AA
339 if (end_alpha > 0) {
340 v = r>>16;
341 *point = mix_alpha(*point, (TYPE)ramp[v].pixel, end_alpha);
342 }
343#endif /* FULL_AA */
344 } else {
345 while (n--) {
346 v = r>>16;
347 cp = &ramp[v];
348 *point = mix_alpha(*point, cp->pixel, cp->alpha);
349 point++;
350 r += dr;
351 }
352 }
353 } else {
354 if (!grad->has_alpha) {
355#ifdef FULL_AA
356 if (start_alpha < 255) {
357 v = r>>16;
358 if (v < 0) v = 0;
359 else if (v > 255) v = 255;
360 *point = mix_alpha(*point, (TYPE)ramp[v].pixel, start_alpha);
361 point++;
362 r += dr;
363 n--;
364 }
365#endif /* FULL_AA */
366 while (n>0) {
367 v = r>>16;
368 if (v < 0) v = 0;
369 else if (v > 255) v = 255;
370 *point = (TYPE)ramp[v].pixel;
371 point++;
372 r += dr;
373 n--;
374 }
375#ifdef FULL_AA
376 if (end_alpha > 0) {
377 v = r>>16;
378 if (v < 0) v = 0;
379 else if (v > 255) v = 255;
380 *point = mix_alpha(*point, (TYPE)ramp[v].pixel, end_alpha);
381 }
382#endif /* FULL_AA */
383 } else {
384 while (n--) {
385 v = r>>16;
386 if (v < 0) v = 0;
387 else if (v > 255) v = 255;
388 cp = &ramp[v];
389 *point = mix_alpha(*point, cp->pixel, cp->alpha);
390 point++;
391 r += dr;
392 }
393 }
394 }
395}
396
397void
398GraphicDevice32::fillLineRG(Gradient *grad, long y, long start, long end)
399{
400 long X,dx,r,Y,dy;
401 long dist2;
402 register long n;
403 Color *cp,*ramp;
404 TYPE *line;
405 TYPE *point;
406 Matrix *m = &grad->imat;
407 unsigned int start_alpha,end_alpha;
408
409 if (clip(y,start,end)) return;
410
411 start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
412 end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
413
414 start /= FRAC;
415 end /= FRAC;
416
417 n = end-start;
418
419 X = (long) (m->a * start + m->b * y + m->tx);
420 Y = (long) (m->c * start + m->d * y + m->ty);
421 dx = (long) (m->a);
422 dy = (long) (m->c);
423
424 ramp = grad->ramp;
425
426 line = (TYPE *)(canvasBuffer + bpl*y);
427 point = &line[start];
428
429 if (!grad->has_alpha) {
430#ifdef FULL_AA
431 if (start == end) {
432 dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
433 if ((unsigned long)dist2 >= 65536) {
434 r = 255;
435 } else {
436 r = SQRT[dist2];
437 }
438 *point = mix_alpha(*point, (TYPE)ramp[r].pixel, start_alpha + end_alpha - 255);
439 } else {
440 if (start_alpha < 255) {
441 dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
442 if ((unsigned long)dist2 >= 65536) {
443 r = 255;
444 } else {
445 r = SQRT[dist2];
446 }
447 *point = mix_alpha(*point, (TYPE)ramp[r].pixel, start_alpha);
448 point++;
449 X += dx;
450 Y += dy;
451 n--;
452 }
453#endif /* FULL_AA */
454 while (n>0) {
455 dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
456 if ((unsigned long)dist2 >= 65536) {
457 r = 255;
458 } else {
459 r= SQRT[dist2];
460 }
461 *point = (TYPE)ramp[r].pixel;
462 point++;
463 X += dx;
464 Y += dy;
465 n--;
466 }
467#ifdef FULL_AA
468 if (end_alpha > 0) {
469 dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
470 if ((unsigned long)dist2 >= 65536) {
471 r = 255;
472 } else {
473 r= SQRT[dist2];
474 }
475 *point = mix_alpha(*point, (TYPE)ramp[r].pixel, end_alpha);
476 }
477 }
478#endif /* FULL_AA */
479
480 } else {
481 while (n--) {
482 dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
483 if ((unsigned long)dist2 >= 65536) {
484 r = 255;
485 } else {
486 r= SQRT[dist2];
487 }
488 cp = &ramp[r];
489 *point = mix_alpha(*point, cp->pixel, cp->alpha);
490 point++;
491 X += dx;
492 Y += dy;
493 }
494 }
495}
496
497void
498GraphicDevice32::drawLine(long x1, long y1, long x2, long y2, long width)
499{
500 int n,adr,dx,dy,sx,color;
501 register int a;
502 register TYPE *pp;
503 int alpha;
504
505 x1 = (x1) >> FRAC_BITS;
506 y1 = (y1) >> FRAC_BITS;
507 x2 = (x2) >> FRAC_BITS;
508 y2 = (y2) >> FRAC_BITS;
509
510 if (y1 > y2 || (y1 == y2 && x1 > x2)) {
511 long tmp;
512
513 tmp=x1;
514 x1=x2;
515 x2=tmp;
516
517 tmp=y1;
518 y1=y2;
519 y2=tmp;
520 }
521
522 if (y1 == y2 && (y1 < clip_rect.ymin || y1 > clip_rect.ymax)) return;
523 if (x1 == x2 && (x1 < clip_rect.xmin || x1 > clip_rect.xmax)) return;
524 if (x1 == x2 && y1 == y2) return;// Bad !!!
525
526 if (y1 < clip_rect.ymin && y1 != y2) {
527 x1 += (x2-x1)*(clip_rect.ymin-y1)/(y2-y1);
528 y1 = clip_rect.ymin;
529 }
530
531 if (y2 > clip_rect.ymax && y1 != y2) {
532 x2 -= (x2-x1)*(y2-clip_rect.ymax)/(y2-y1);
533 y2 = clip_rect.ymax;
534 }
535
536 if (x1 < x2) {
537 if (x1 < clip_rect.xmin && x1 != x2) {
538 y1 += (y2-y1)*(clip_rect.xmin-x1)/(x2-x1);
539 x1 = clip_rect.xmin;
540 }
541
542 if (x2 > clip_rect.xmax && x1 != x2) {
543 y2 -= (y2-y1)*(x2-clip_rect.xmax)/(x2-x1);
544 x2 = clip_rect.xmax;
545 }
546 }
547
548 if (x1 > x2) {
549 if (x2 < clip_rect.xmin && x2 != x1) {
550 y2 -= (y2-y1)*(clip_rect.xmin-x2)/(x1-x2);
551 x2 = clip_rect.xmin;
552 }
553
554 if (x1 > clip_rect.xmax && x2 != x1) {
555 y1 += (y2-y1)*(x1-clip_rect.xmax)/(x1-x2);
556 x1 = clip_rect.xmax;
557 }
558 }
559
560 // Check again
561 if (x1 == x2 && y1 == y2) return;
562 if (x1 < clip_rect.xmin || x2 < clip_rect.xmin) return;
563 if (y1 < clip_rect.ymin || y2 < clip_rect.ymin) return;
564 if (x1 > clip_rect.xmax || x2 > clip_rect.xmax) return;
565 if (y1 > clip_rect.ymax || y2 > clip_rect.ymax) return;
566
567 sx=bpl >> 1;
568 adr=(y1 * sx + x1);
569 pp = (TYPE *)canvasBuffer + adr;
570
571 dx = x2 - x1;
572 dy = y2 - y1;
573
574 color = allocColor(foregroundColor);
575 alpha = foregroundColor.alpha;
576
577 if (alpha == ALPHA_OPAQUE) {
578
579 #define PUTPIXEL() \
580 { \
581 *pp=color; \
582 }
583
584#define DRAWLINE(dx,dy,inc_1,inc_2) \
585 n=dx;\
586 a=2*dy-dx;\
587 dy=2*dy;\
588 dx=2*dx-dy;\
589 do {\
590 PUTPIXEL();\
591 if (a>0) { pp+=(inc_1); a-=dx; }\
592 else { pp+=(inc_2); a+=dy; }\
593 } while (--n >= 0);
594
595/* fin macro */
596
597 if (dx == 0 && dy == 0) {
598 PUTPIXEL();
599 } else if (dx > 0) {
600 if (dx >= dy) {
601 DRAWLINE(dx, dy, sx + 1, 1);
602 } else {
603 DRAWLINE(dy, dx, sx + 1, sx);
604 }
605 } else {
606 dx = -dx;
607 if (dx >= dy) {
608 DRAWLINE(dx, dy, sx - 1, -1);
609 } else {
610 DRAWLINE(dy, dx, sx - 1, sx);
611 }
612 }
613
614
615#undef DRAWLINE
616#undef PUTPIXEL
617 } else {
618 #define PUTPIXEL() \
619 { \
620 *pp=mix_alpha(*pp,color,alpha); \
621 }
622
623#define DRAWLINE(dx,dy,inc_1,inc_2) \
624 n=dx;\
625 a=2*dy-dx;\
626 dy=2*dy;\
627 dx=2*dx-dy;\
628 do {\
629 PUTPIXEL();\
630 if (a>0) { pp+=(inc_1); a-=dx; }\
631 else { pp+=(inc_2); a+=dy; }\
632 } while (--n >= 0);
633
634/* fin macro */
635
636 if (dx == 0 && dy == 0) {
637 PUTPIXEL();
638 } else if (dx > 0) {
639 if (dx >= dy) {
640 DRAWLINE(dx, dy, sx + 1, 1);
641 } else {
642 DRAWLINE(dy, dx, sx + 1, sx);
643 }
644 } else {
645 dx = -dx;
646 if (dx >= dy) {
647 DRAWLINE(dx, dy, sx - 1, -1);
648 } else {
649 DRAWLINE(dy, dx, sx - 1, sx);
650 }
651 }
652
653
654#undef DRAWLINE
655#undef PUTPIXEL
656 }
657}
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 @@
1////////////////////////////////////////////////////////////
2// Flash Plugin and Player
3// Copyright (C) 1998 Olivier Debon
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19///////////////////////////////////////////////////////////////
20// Author : Olivier Debon <odebon@club-internet.fr>
21//
22
23#include "swf.h"
24
25class GraphicDevice32: public GraphicDevice {
26private:
27 long GraphicDevice32::allocColor(Color color);
28
29public:
30 GraphicDevice32(FlashDisplay *fd);
31
32 void clearCanvas();
33 void fillLineAA(FillStyleDef *f, long y, long start, long end);
34 void fillLine(FillStyleDef *f, long y, long start, long end);
35 void fillLineBitmap(FillStyleDef *f, long y, long start, long end);
36 void fillLineLG(Gradient *grad, long y, long start, long end);
37 void fillLineRG(Gradient *grad, long y, long start, long end);
38 void drawLine(long x1, long y1, long x2, long y2, long width);
39};
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 @@
1/* jconfig.h. Generated automatically by configure. */
2/* jconfig.cfg --- source file edited by configure script */
3/* see jconfig.doc for explanations */
4
5#define HAVE_PROTOTYPES
6#define HAVE_UNSIGNED_CHAR
7#define HAVE_UNSIGNED_SHORT
8#undef void
9#undef const
10#undef CHAR_IS_UNSIGNED
11#define HAVE_STDDEF_H
12#define HAVE_STDLIB_H
13#undef NEED_BSD_STRINGS
14#undef NEED_SYS_TYPES_H
15#undef NEED_FAR_POINTERS
16#undef NEED_SHORT_EXTERNAL_NAMES
17/* Define this if you get warnings about undefined structures. */
18#undef INCOMPLETE_TYPES_BROKEN
19
20#ifdef JPEG_INTERNALS
21
22#undef RIGHT_SHIFT_IS_UNSIGNED
23#define INLINE __inline__
24/* These are for configuring the JPEG memory manager. */
25#undef DEFAULT_MAX_MEM
26#undef NO_MKTEMP
27
28#endif /* JPEG_INTERNALS */
29
30#ifdef JPEG_CJPEG_DJPEG
31
32 #define BMP_SUPPORTED /* BMP image file format */
33 #define GIF_SUPPORTED /* GIF image file format */
34 #define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
35 #undef RLE_SUPPORTED /* Utah RLE image file format */
36 #define TARGA_SUPPORTED /* Targa image file format */
37
38#undef TWO_FILE_COMMANDLINE
39#undef NEED_SIGNAL_CATCHER
40#undef DONT_USE_B_MODE
41
42/* Define this if you want percent-done progress reports from cjpeg/djpeg. */
43#undef PROGRESS_REPORT
44
45#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 @@
1/*
2 * jerror.h
3 *
4 * Copyright (C) 1994-1997, Thomas G. Lane.
5 * This file is part of the Independent JPEG Group's software.
6 * For conditions of distribution and use, see the accompanying README file.
7 *
8 * This file defines the error and message codes for the JPEG library.
9 * Edit this file to add new codes, or to translate the message strings to
10 * some other language.
11 * A set of error-reporting macros are defined too. Some applications using
12 * the JPEG library may wish to include this file to get the error codes
13 * and/or the macros.
14 */
15
16/*
17 * To define the enum list of message codes, include this file without
18 * defining macro JMESSAGE. To create a message string table, include it
19 * again with a suitable JMESSAGE definition (see jerror.c for an example).
20 */
21#ifndef JMESSAGE
22#ifndef JERROR_H
23/* First time through, define the enum list */
24#define JMAKE_ENUM_LIST
25#else
26/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */
27#define JMESSAGE(code,string)
28#endif /* JERROR_H */
29#endif /* JMESSAGE */
30
31#ifdef JMAKE_ENUM_LIST
32
33typedef enum {
34
35 #define JMESSAGE(code,string)code ,
36
37#endif /* JMAKE_ENUM_LIST */
38
39JMESSAGE(JMSG_NOMESSAGE, "Bogus message code %d") /* Must be first entry! */
40
41/* For maintenance convenience, list is alphabetical by message code name */
42JMESSAGE(JERR_ARITH_NOTIMPL,
43 "Sorry, there are legal restrictions on arithmetic coding")
44JMESSAGE(JERR_BAD_ALIGN_TYPE, "ALIGN_TYPE is wrong, please fix")
45JMESSAGE(JERR_BAD_ALLOC_CHUNK, "MAX_ALLOC_CHUNK is wrong, please fix")
46JMESSAGE(JERR_BAD_BUFFER_MODE, "Bogus buffer control mode")
47JMESSAGE(JERR_BAD_COMPONENT_ID, "Invalid component ID %d in SOS")
48JMESSAGE(JERR_BAD_DCT_COEF, "DCT coefficient out of range")
49JMESSAGE(JERR_BAD_DCTSIZE, "IDCT output block size %d not supported")
50JMESSAGE(JERR_BAD_HUFF_TABLE, "Bogus Huffman table definition")
51JMESSAGE(JERR_BAD_IN_COLORSPACE, "Bogus input colorspace")
52JMESSAGE(JERR_BAD_J_COLORSPACE, "Bogus JPEG colorspace")
53JMESSAGE(JERR_BAD_LENGTH, "Bogus marker length")
54JMESSAGE(JERR_BAD_LIB_VERSION,
55 "Wrong JPEG library version: library is %d, caller expects %d")
56JMESSAGE(JERR_BAD_MCU_SIZE, "Sampling factors too large for interleaved scan")
57JMESSAGE(JERR_BAD_POOL_ID, "Invalid memory pool code %d")
58JMESSAGE(JERR_BAD_PRECISION, "Unsupported JPEG data precision %d")
59JMESSAGE(JERR_BAD_PROGRESSION,
60 "Invalid progressive parameters Ss=%d Se=%d Ah=%d Al=%d")
61JMESSAGE(JERR_BAD_PROG_SCRIPT,
62 "Invalid progressive parameters at scan script entry %d")
63JMESSAGE(JERR_BAD_SAMPLING, "Bogus sampling factors")
64JMESSAGE(JERR_BAD_SCAN_SCRIPT, "Invalid scan script at entry %d")
65JMESSAGE(JERR_BAD_STATE, "Improper call to JPEG library in state %d")
66JMESSAGE(JERR_BAD_STRUCT_SIZE,
67 "JPEG parameter struct mismatch: library thinks size is %u, caller expects %u")
68JMESSAGE(JERR_BAD_VIRTUAL_ACCESS, "Bogus virtual array access")
69JMESSAGE(JERR_BUFFER_SIZE, "Buffer passed to JPEG library is too small")
70JMESSAGE(JERR_CANT_SUSPEND, "Suspension not allowed here")
71JMESSAGE(JERR_CCIR601_NOTIMPL, "CCIR601 sampling not implemented yet")
72JMESSAGE(JERR_COMPONENT_COUNT, "Too many color components: %d, max %d")
73JMESSAGE(JERR_CONVERSION_NOTIMPL, "Unsupported color conversion request")
74JMESSAGE(JERR_DAC_INDEX, "Bogus DAC index %d")
75JMESSAGE(JERR_DAC_VALUE, "Bogus DAC value 0x%x")
76JMESSAGE(JERR_DHT_INDEX, "Bogus DHT index %d")
77JMESSAGE(JERR_DQT_INDEX, "Bogus DQT index %d")
78JMESSAGE(JERR_EMPTY_IMAGE, "Empty JPEG image (DNL not supported)")
79JMESSAGE(JERR_EMS_READ, "Read from EMS failed")
80JMESSAGE(JERR_EMS_WRITE, "Write to EMS failed")
81JMESSAGE(JERR_EOI_EXPECTED, "Didn't expect more than one scan")
82JMESSAGE(JERR_FILE_READ, "Input file read error")
83JMESSAGE(JERR_FILE_WRITE, "Output file write error --- out of disk space?")
84JMESSAGE(JERR_FRACT_SAMPLE_NOTIMPL, "Fractional sampling not implemented yet")
85JMESSAGE(JERR_HUFF_CLEN_OVERFLOW, "Huffman code size table overflow")
86JMESSAGE(JERR_HUFF_MISSING_CODE, "Missing Huffman code table entry")
87JMESSAGE(JERR_IMAGE_TOO_BIG, "Maximum supported image dimension is %u pixels")
88JMESSAGE(JERR_INPUT_EMPTY, "Empty input file")
89JMESSAGE(JERR_INPUT_EOF, "Premature end of input file")
90JMESSAGE(JERR_MISMATCHED_QUANT_TABLE,
91 "Cannot transcode due to multiple use of quantization table %d")
92JMESSAGE(JERR_MISSING_DATA, "Scan script does not transmit all data")
93JMESSAGE(JERR_MODE_CHANGE, "Invalid color quantization mode change")
94JMESSAGE(JERR_NOTIMPL, "Not implemented yet")
95JMESSAGE(JERR_NOT_COMPILED, "Requested feature was omitted at compile time")
96JMESSAGE(JERR_NO_BACKING_STORE, "Backing store not supported")
97JMESSAGE(JERR_NO_HUFF_TABLE, "Huffman table 0x%02x was not defined")
98JMESSAGE(JERR_NO_IMAGE, "JPEG datastream contains no image")
99JMESSAGE(JERR_NO_QUANT_TABLE, "Quantization table 0x%02x was not defined")
100JMESSAGE(JERR_NO_SOI, "Not a JPEG file: starts with 0x%02x 0x%02x")
101JMESSAGE(JERR_OUT_OF_MEMORY, "Insufficient memory (case %d)")
102JMESSAGE(JERR_QUANT_COMPONENTS,
103 "Cannot quantize more than %d color components")
104JMESSAGE(JERR_QUANT_FEW_COLORS, "Cannot quantize to fewer than %d colors")
105JMESSAGE(JERR_QUANT_MANY_COLORS, "Cannot quantize to more than %d colors")
106JMESSAGE(JERR_SOF_DUPLICATE, "Invalid JPEG file structure: two SOF markers")
107JMESSAGE(JERR_SOF_NO_SOS, "Invalid JPEG file structure: missing SOS marker")
108JMESSAGE(JERR_SOF_UNSUPPORTED, "Unsupported JPEG process: SOF type 0x%02x")
109JMESSAGE(JERR_SOI_DUPLICATE, "Invalid JPEG file structure: two SOI markers")
110JMESSAGE(JERR_SOS_NO_SOF, "Invalid JPEG file structure: SOS before SOF")
111JMESSAGE(JERR_TFILE_CREATE, "Failed to create temporary file %s")
112JMESSAGE(JERR_TFILE_READ, "Read failed on temporary file")
113JMESSAGE(JERR_TFILE_SEEK, "Seek failed on temporary file")
114JMESSAGE(JERR_TFILE_WRITE,
115 "Write failed on temporary file --- out of disk space?")
116JMESSAGE(JERR_TOO_LITTLE_DATA, "Application transferred too few scanlines")
117JMESSAGE(JERR_UNKNOWN_MARKER, "Unsupported marker type 0x%02x")
118JMESSAGE(JERR_VIRTUAL_BUG, "Virtual array controller messed up")
119JMESSAGE(JERR_WIDTH_OVERFLOW, "Image too wide for this implementation")
120JMESSAGE(JERR_XMS_READ, "Read from XMS failed")
121JMESSAGE(JERR_XMS_WRITE, "Write to XMS failed")
122JMESSAGE(JMSG_COPYRIGHT, JCOPYRIGHT)
123JMESSAGE(JMSG_VERSION, JVERSION)
124JMESSAGE(JTRC_16BIT_TABLES,
125 "Caution: quantization tables are too coarse for baseline JPEG")
126JMESSAGE(JTRC_ADOBE,
127 "Adobe APP14 marker: version %d, flags 0x%04x 0x%04x, transform %d")
128JMESSAGE(JTRC_APP0, "Unknown APP0 marker (not JFIF), length %u")
129JMESSAGE(JTRC_APP14, "Unknown APP14 marker (not Adobe), length %u")
130JMESSAGE(JTRC_DAC, "Define Arithmetic Table 0x%02x: 0x%02x")
131JMESSAGE(JTRC_DHT, "Define Huffman Table 0x%02x")
132JMESSAGE(JTRC_DQT, "Define Quantization Table %d precision %d")
133JMESSAGE(JTRC_DRI, "Define Restart Interval %u")
134JMESSAGE(JTRC_EMS_CLOSE, "Freed EMS handle %u")
135JMESSAGE(JTRC_EMS_OPEN, "Obtained EMS handle %u")
136JMESSAGE(JTRC_EOI, "End Of Image")
137JMESSAGE(JTRC_HUFFBITS, " %3d %3d %3d %3d %3d %3d %3d %3d")
138JMESSAGE(JTRC_JFIF, "JFIF APP0 marker: version %d.%02d, density %dx%d %d")
139JMESSAGE(JTRC_JFIF_BADTHUMBNAILSIZE,
140 "Warning: thumbnail image size does not match data length %u")
141JMESSAGE(JTRC_JFIF_EXTENSION,
142 "JFIF extension marker: type 0x%02x, length %u")
143JMESSAGE(JTRC_JFIF_THUMBNAIL, " with %d x %d thumbnail image")
144JMESSAGE(JTRC_MISC_MARKER, "Miscellaneous marker 0x%02x, length %u")
145JMESSAGE(JTRC_PARMLESS_MARKER, "Unexpected marker 0x%02x")
146JMESSAGE(JTRC_QUANTVALS, " %4u %4u %4u %4u %4u %4u %4u %4u")
147JMESSAGE(JTRC_QUANT_3_NCOLORS, "Quantizing to %d = %d*%d*%d colors")
148JMESSAGE(JTRC_QUANT_NCOLORS, "Quantizing to %d colors")
149JMESSAGE(JTRC_QUANT_SELECTED, "Selected %d colors for quantization")
150JMESSAGE(JTRC_RECOVERY_ACTION, "At marker 0x%02x, recovery action %d")
151JMESSAGE(JTRC_RST, "RST%d")
152JMESSAGE(JTRC_SMOOTH_NOTIMPL,
153 "Smoothing not supported with nonstandard sampling ratios")
154JMESSAGE(JTRC_SOF, "Start Of Frame 0x%02x: width=%u, height=%u, components=%d")
155JMESSAGE(JTRC_SOF_COMPONENT, " Component %d: %dhx%dv q=%d")
156JMESSAGE(JTRC_SOI, "Start of Image")
157JMESSAGE(JTRC_SOS, "Start Of Scan: %d components")
158JMESSAGE(JTRC_SOS_COMPONENT, " Component %d: dc=%d ac=%d")
159JMESSAGE(JTRC_SOS_PARAMS, " Ss=%d, Se=%d, Ah=%d, Al=%d")
160JMESSAGE(JTRC_TFILE_CLOSE, "Closed temporary file %s")
161JMESSAGE(JTRC_TFILE_OPEN, "Opened temporary file %s")
162JMESSAGE(JTRC_THUMB_JPEG,
163 "JFIF extension marker: JPEG-compressed thumbnail image, length %u")
164JMESSAGE(JTRC_THUMB_PALETTE,
165 "JFIF extension marker: palette thumbnail image, length %u")
166JMESSAGE(JTRC_THUMB_RGB,
167 "JFIF extension marker: RGB thumbnail image, length %u")
168JMESSAGE(JTRC_UNKNOWN_IDS,
169 "Unrecognized component IDs %d %d %d, assuming YCbCr")
170JMESSAGE(JTRC_XMS_CLOSE, "Freed XMS handle %u")
171JMESSAGE(JTRC_XMS_OPEN, "Obtained XMS handle %u")
172JMESSAGE(JWRN_ADOBE_XFORM, "Unknown Adobe color transform code %d")
173JMESSAGE(JWRN_BOGUS_PROGRESSION,
174 "Inconsistent progression sequence for component %d coefficient %d")
175JMESSAGE(JWRN_EXTRANEOUS_DATA,
176 "Corrupt JPEG data: %u extraneous bytes before marker 0x%02x")
177JMESSAGE(JWRN_HIT_MARKER, "Corrupt JPEG data: premature end of data segment")
178JMESSAGE(JWRN_HUFF_BAD_CODE, "Corrupt JPEG data: bad Huffman code")
179JMESSAGE(JWRN_JFIF_MAJOR, "Warning: unknown JFIF revision number %d.%02d")
180JMESSAGE(JWRN_JPEG_EOF, "Premature end of JPEG file")
181JMESSAGE(JWRN_MUST_RESYNC,
182 "Corrupt JPEG data: found marker 0x%02x instead of RST%d")
183JMESSAGE(JWRN_NOT_SEQUENTIAL, "Invalid SOS parameters for sequential JPEG")
184JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines")
185
186#ifdef JMAKE_ENUM_LIST
187
188 JMSG_LASTMSGCODE
189} J_MESSAGE_CODE;
190
191#undef JMAKE_ENUM_LIST
192#endif /* JMAKE_ENUM_LIST */
193
194/* Zap JMESSAGE macro so that future re-inclusions do nothing by default */
195#undef JMESSAGE
196
197
198#ifndef JERROR_H
199#define JERROR_H
200
201/* Macros to simplify using the error and trace message stuff */
202/* The first parameter is either type of cinfo pointer */
203
204/* Fatal errors (print message and exit) */
205#define ERREXIT(cinfo,code) \
206 ((cinfo)->err->msg_code = (code), \
207 (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
208#define ERREXIT1(cinfo,code,p1) \
209 ((cinfo)->err->msg_code = (code), \
210 (cinfo)->err->msg_parm.i[0] = (p1), \
211 (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
212#define ERREXIT2(cinfo,code,p1,p2) \
213 ((cinfo)->err->msg_code = (code), \
214 (cinfo)->err->msg_parm.i[0] = (p1), \
215 (cinfo)->err->msg_parm.i[1] = (p2), \
216 (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
217#define ERREXIT3(cinfo,code,p1,p2,p3) \
218 ((cinfo)->err->msg_code = (code), \
219 (cinfo)->err->msg_parm.i[0] = (p1), \
220 (cinfo)->err->msg_parm.i[1] = (p2), \
221 (cinfo)->err->msg_parm.i[2] = (p3), \
222 (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
223#define ERREXIT4(cinfo,code,p1,p2,p3,p4) \
224 ((cinfo)->err->msg_code = (code), \
225 (cinfo)->err->msg_parm.i[0] = (p1), \
226 (cinfo)->err->msg_parm.i[1] = (p2), \
227 (cinfo)->err->msg_parm.i[2] = (p3), \
228 (cinfo)->err->msg_parm.i[3] = (p4), \
229 (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
230#define ERREXITS(cinfo,code,str) \
231 ((cinfo)->err->msg_code = (code), \
232 strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \
233 (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
234
235 #define MAKESTMT(stuff) do { stuff } while (0)
236
237/* Nonfatal errors (we can keep going, but the data is probably corrupt) */
238#define WARNMS(cinfo,code) \
239 ((cinfo)->err->msg_code = (code), \
240 (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
241#define WARNMS1(cinfo,code,p1) \
242 ((cinfo)->err->msg_code = (code), \
243 (cinfo)->err->msg_parm.i[0] = (p1), \
244 (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
245#define WARNMS2(cinfo,code,p1,p2) \
246 ((cinfo)->err->msg_code = (code), \
247 (cinfo)->err->msg_parm.i[0] = (p1), \
248 (cinfo)->err->msg_parm.i[1] = (p2), \
249 (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
250
251/* Informational/debugging messages */
252#define TRACEMS(cinfo,lvl,code) \
253 ((cinfo)->err->msg_code = (code), \
254 (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
255#define TRACEMS1(cinfo,lvl,code,p1) \
256 ((cinfo)->err->msg_code = (code), \
257 (cinfo)->err->msg_parm.i[0] = (p1), \
258 (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
259#define TRACEMS2(cinfo,lvl,code,p1,p2) \
260 ((cinfo)->err->msg_code = (code), \
261 (cinfo)->err->msg_parm.i[0] = (p1), \
262 (cinfo)->err->msg_parm.i[1] = (p2), \
263 (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
264#define TRACEMS3(cinfo,lvl,code,p1,p2,p3) \
265 MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
266 _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); \
267 (cinfo)->err->msg_code = (code); \
268 (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
269#define TRACEMS4(cinfo,lvl,code,p1,p2,p3,p4) \
270 MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
271 _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
272 (cinfo)->err->msg_code = (code); \
273 (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
274#define TRACEMS5(cinfo,lvl,code,p1,p2,p3,p4,p5) \
275 MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
276 _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
277 _mp[4] = (p5); \
278 (cinfo)->err->msg_code = (code); \
279 (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
280#define TRACEMS8(cinfo,lvl,code,p1,p2,p3,p4,p5,p6,p7,p8) \
281 MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
282 _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
283 _mp[4] = (p5); _mp[5] = (p6); _mp[6] = (p7); _mp[7] = (p8); \
284 (cinfo)->err->msg_code = (code); \
285 (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
286#define TRACEMSS(cinfo,lvl,code,str) \
287 ((cinfo)->err->msg_code = (code), \
288 strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \
289 (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
290
291#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 @@
1/*
2 * jmorecfg.h
3 *
4 * Copyright (C) 1991-1997, Thomas G. Lane.
5 * This file is part of the Independent JPEG Group's software.
6 * For conditions of distribution and use, see the accompanying README file.
7 *
8 * This file contains additional configuration options that customize the
9 * JPEG software for special applications or support machine-dependent
10 * optimizations. Most users will not need to touch this file.
11 */
12
13
14/*
15 * Define BITS_IN_JSAMPLE as either
16 * 8 for 8-bit sample values (the usual setting)
17 * 12 for 12-bit sample values
18 * Only 8 and 12 are legal data precisions for lossy JPEG according to the
19 * JPEG standard, and the IJG code does not support anything else!
20 * We do not support run-time selection of data precision, sorry.
21 */
22
23 #define BITS_IN_JSAMPLE 8/* use 8 or 12 */
24
25
26/*
27 * Maximum number of components (color channels) allowed in JPEG image.
28 * To meet the letter of the JPEG spec, set this to 255. However, darn
29 * few applications need more than 4 channels (maybe 5 for CMYK + alpha
30 * mask). We recommend 10 as a reasonable compromise; use 4 if you are
31 * really short on memory. (Each allowed component costs a hundred or so
32 * bytes of storage, whether actually used in an image or not.)
33 */
34
35 #define MAX_COMPONENTS 10/* maximum number of image components */
36
37
38/*
39 * Basic data types.
40 * You may need to change these if you have a machine with unusual data
41 * type sizes; for example, "char" not 8 bits, "short" not 16 bits,
42 * or "long" not 32 bits. We don't care whether "int" is 16 or 32 bits,
43 * but it had better be at least 16.
44 */
45
46/* Representation of a single sample (pixel element value).
47 * We frequently allocate large arrays of these, so it's important to keep
48 * them small. But if you have memory to burn and access to char or short
49 * arrays is very slow on your hardware, you might want to change these.
50 */
51
52#if BITS_IN_JSAMPLE == 8
53/* JSAMPLE should be the smallest type that will hold the values 0..255.
54 * You can use a signed char by having GETJSAMPLE mask it with 0xFF.
55 */
56
57#ifdef HAVE_UNSIGNED_CHAR
58
59typedef unsigned char JSAMPLE;
60#define GETJSAMPLE(value) ((int) (value))
61
62#else /* not HAVE_UNSIGNED_CHAR */
63
64typedef char JSAMPLE;
65#ifdef CHAR_IS_UNSIGNED
66#define GETJSAMPLE(value) ((int) (value))
67#else
68#define GETJSAMPLE(value) ((int) (value) & 0xFF)
69#endif /* CHAR_IS_UNSIGNED */
70
71#endif /* HAVE_UNSIGNED_CHAR */
72
73 #define MAXJSAMPLE255
74 #define CENTERJSAMPLE128
75
76#endif /* BITS_IN_JSAMPLE == 8 */
77
78
79#if BITS_IN_JSAMPLE == 12
80/* JSAMPLE should be the smallest type that will hold the values 0..4095.
81 * On nearly all machines "short" will do nicely.
82 */
83
84typedef short JSAMPLE;
85#define GETJSAMPLE(value) ((int) (value))
86
87 #define MAXJSAMPLE4095
88 #define CENTERJSAMPLE2048
89
90#endif /* BITS_IN_JSAMPLE == 12 */
91
92
93/* Representation of a DCT frequency coefficient.
94 * This should be a signed value of at least 16 bits; "short" is usually OK.
95 * Again, we allocate large arrays of these, but you can change to int
96 * if you have memory to burn and "short" is really slow.
97 */
98
99typedef short JCOEF;
100
101
102/* Compressed datastreams are represented as arrays of JOCTET.
103 * These must be EXACTLY 8 bits wide, at least once they are written to
104 * external storage. Note that when using the stdio data source/destination
105 * managers, this is also the data type passed to fread/fwrite.
106 */
107
108#ifdef HAVE_UNSIGNED_CHAR
109
110typedef unsigned char JOCTET;
111#define GETJOCTET(value) (value)
112
113#else /* not HAVE_UNSIGNED_CHAR */
114
115typedef char JOCTET;
116#ifdef CHAR_IS_UNSIGNED
117#define GETJOCTET(value) (value)
118#else
119#define GETJOCTET(value) ((value) & 0xFF)
120#endif /* CHAR_IS_UNSIGNED */
121
122#endif /* HAVE_UNSIGNED_CHAR */
123
124
125/* These typedefs are used for various table entries and so forth.
126 * They must be at least as wide as specified; but making them too big
127 * won't cost a huge amount of memory, so we don't provide special
128 * extraction code like we did for JSAMPLE. (In other words, these
129 * typedefs live at a different point on the speed/space tradeoff curve.)
130 */
131
132/* UINT8 must hold at least the values 0..255. */
133
134#ifdef HAVE_UNSIGNED_CHAR
135typedef unsigned char UINT8;
136#else /* not HAVE_UNSIGNED_CHAR */
137#ifdef CHAR_IS_UNSIGNED
138typedef char UINT8;
139#else /* not CHAR_IS_UNSIGNED */
140typedef short UINT8;
141#endif /* CHAR_IS_UNSIGNED */
142#endif /* HAVE_UNSIGNED_CHAR */
143
144/* UINT16 must hold at least the values 0..65535. */
145
146#ifdef HAVE_UNSIGNED_SHORT
147typedef unsigned short UINT16;
148#else /* not HAVE_UNSIGNED_SHORT */
149typedef unsigned int UINT16;
150#endif /* HAVE_UNSIGNED_SHORT */
151
152/* INT16 must hold at least the values -32768..32767. */
153
154 #ifndef XMD_H /* X11/xmd.h correctly defines INT16 */
155typedef short INT16;
156#endif
157
158/* INT32 must hold at least signed 32-bit values. */
159
160 #ifndef XMD_H /* X11/xmd.h correctly defines INT32 */
161typedef long INT32;
162#endif
163
164/* Datatype used for image dimensions. The JPEG standard only supports
165 * images up to 64K*64K due to 16-bit fields in SOF markers. Therefore
166 * "unsigned int" is sufficient on all machines. However, if you need to
167 * handle larger images and you don't mind deviating from the spec, you
168 * can change this datatype.
169 */
170
171typedef unsigned int JDIMENSION;
172
173#define JPEG_MAX_DIMENSION 65500L /* a tad under 64K to prevent overflows */
174
175
176/* These macros are used in all function definitions and extern declarations.
177 * You could modify them if you need to change function linkage conventions;
178 * in particular, you'll need to do that to make the library a Windows DLL.
179 * Another application is to make all functions global for use with debuggers
180 * or code profilers that require it.
181 */
182
183/* a function called through method pointers: */
184 #define METHODDEF(type) static type
185/* a function used only in its module: */
186 #define LOCAL(type) static type
187/* a function referenced thru EXTERNs: */
188 #define GLOBAL(type) type
189/* a reference to a GLOBAL function: */
190 #define EXTERN(type) extern type
191
192
193/* This macro is used to declare a "method", that is, a function pointer.
194 * We want to supply prototype parameters if the compiler can cope.
195 * Note that the arglist parameter must be parenthesized!
196 * Again, you can customize this if you need special linkage keywords.
197 */
198
199#ifdef HAVE_PROTOTYPES
200#define JMETHOD(type,methodname,arglist) type (*methodname) arglist
201#else
202#define JMETHOD(type,methodname,arglist) type (*methodname) ()
203#endif
204
205
206/* Here is the pseudo-keyword for declaring pointers that must be "far"
207 * on 80x86 machines. Most of the specialized coding for 80x86 is handled
208 * by just saying "FAR *" where such a pointer is needed. In a few places
209 * explicit coding is needed; see uses of the NEED_FAR_POINTERS symbol.
210 */
211
212#ifdef NEED_FAR_POINTERS
213#define FAR far
214#else
215#define FAR
216#endif
217
218
219/*
220 * On a few systems, type boolean and/or its values FALSE, TRUE may appear
221 * in standard header files. Or you may have conflicts with application-
222 * specific header files that you want to include together with these files.
223 * Defining HAVE_BOOLEAN before including jpeglib.h should make it work.
224 */
225
226#ifndef HAVE_BOOLEAN
227typedef int boolean;
228#endif
229 #ifndef FALSE /* in case these macros already exist */
230 #define FALSE 0 /* values of boolean */
231#endif
232#ifndef TRUE
233 #define TRUE1
234#endif
235
236
237/*
238 * The remaining options affect code selection within the JPEG library,
239 * but they don't need to be visible to most applications using the library.
240 * To minimize application namespace pollution, the symbols won't be
241 * defined unless JPEG_INTERNALS or JPEG_INTERNAL_OPTIONS has been defined.
242 */
243
244#ifdef JPEG_INTERNALS
245#define JPEG_INTERNAL_OPTIONS
246#endif
247
248#ifdef JPEG_INTERNAL_OPTIONS
249
250
251/*
252 * These defines indicate whether to include various optional functions.
253 * Undefining some of these symbols will produce a smaller but less capable
254 * library. Note that you can leave certain source files out of the
255 * compilation/linking process if you've #undef'd the corresponding symbols.
256 * (You may HAVE to do that if your compiler doesn't like null source files.)
257 */
258
259/* Arithmetic coding is unsupported for legal reasons. Complaints to IBM. */
260
261/* Capability options common to encoder and decoder: */
262
263 #define DCT_ISLOW_SUPPORTED/* slow but accurate integer algorithm */
264 #define DCT_IFAST_SUPPORTED/* faster, less accurate integer method */
265 #define DCT_FLOAT_SUPPORTED/* floating-point: accurate, fast on fast HW */
266
267/* Encoder capability options: */
268
269#undef C_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */
270#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
271 #define C_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/
272 #define ENTROPY_OPT_SUPPORTED /* Optimization of entropy coding parms? */
273/* Note: if you selected 12-bit data precision, it is dangerous to turn off
274 * ENTROPY_OPT_SUPPORTED. The standard Huffman tables are only good for 8-bit
275 * precision, so jchuff.c normally uses entropy optimization to compute
276 * usable tables for higher precision. If you don't want to do optimization,
277 * you'll have to supply different default Huffman tables.
278 * The exact same statements apply for progressive JPEG: the default tables
279 * don't work for progressive mode. (This may get fixed, however.)
280 */
281#define INPUT_SMOOTHING_SUPPORTED /* Input image smoothing option? */
282
283/* Decoder capability options: */
284
285#undef D_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */
286#define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
287 #define D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/
288 #define SAVE_MARKERS_SUPPORTED /* jpeg_save_markers() needed? */
289#define BLOCK_SMOOTHING_SUPPORTED /* Block smoothing? (Progressive only) */
290 #define IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? */
291#undef UPSAMPLE_SCALING_SUPPORTED /* Output rescaling at upsample stage? */
292#define UPSAMPLE_MERGING_SUPPORTED /* Fast path for sloppy upsampling? */
293 #define QUANT_1PASS_SUPPORTED /* 1-pass color quantization? */
294 #define QUANT_2PASS_SUPPORTED /* 2-pass color quantization? */
295
296/* more capability options later, no doubt */
297
298
299/*
300 * Ordering of RGB data in scanlines passed to or from the application.
301 * If your application wants to deal with data in the order B,G,R, just
302 * change these macros. You can also deal with formats such as R,G,B,X
303 * (one extra byte per pixel) by changing RGB_PIXELSIZE. Note that changing
304 * the offsets will also change the order in which colormap data is organized.
305 * RESTRICTIONS:
306 * 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats.
307 * 2. These macros only affect RGB<=>YCbCr color conversion, so they are not
308 * useful if you are using JPEG color spaces other than YCbCr or grayscale.
309 * 3. The color quantizer modules will not behave desirably if RGB_PIXELSIZE
310 * is not 3 (they don't understand about dummy color components!). So you
311 * can't use color quantization if you change that value.
312 */
313
314 #define RGB_RED 0/* Offset of Red in an RGB scanline element */
315 #define RGB_GREEN 1/* Offset of Green */
316 #define RGB_BLUE 2/* Offset of Blue */
317 #define RGB_PIXELSIZE 3/* JSAMPLEs per RGB scanline element */
318
319
320/* Definitions for speed-related optimizations. */
321
322
323/* If your compiler supports inline functions, define INLINE
324 * as the inline keyword; otherwise define it as empty.
325 */
326
327#ifndef INLINE
328 #ifdef __GNUC__ /* for instance, GNU C knows about inline */
329#define INLINE __inline__
330#endif
331#ifndef INLINE
332 #define INLINE /* default is to define it as empty */
333#endif
334#endif
335
336
337/* On some machines (notably 68000 series) "int" is 32 bits, but multiplying
338 * two 16-bit shorts is faster than multiplying two ints. Define MULTIPLIER
339 * as short on such a machine. MULTIPLIER must be at least 16 bits wide.
340 */
341
342#ifndef MULTIPLIER
343 #define MULTIPLIER int /* type for fastest integer multiply */
344#endif
345
346
347/* FAST_FLOAT should be either float or double, whichever is done faster
348 * by your compiler. (Note that this type is only used in the floating point
349 * DCT routines, so it only matters if you've defined DCT_FLOAT_SUPPORTED.)
350 * Typically, float is faster in ANSI C compilers, while double is faster in
351 * pre-ANSI compilers (because they insist on converting to double anyway).
352 * The code below therefore chooses float if we have ANSI-style prototypes.
353 */
354
355#ifndef FAST_FLOAT
356#ifdef HAVE_PROTOTYPES
357#define FAST_FLOAT float
358#else
359#define FAST_FLOAT double
360#endif
361#endif
362
363#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 @@
1/*
2 * jpeglib.h
3 *
4 * Copyright (C) 1991-1998, Thomas G. Lane.
5 * This file is part of the Independent JPEG Group's software.
6 * For conditions of distribution and use, see the accompanying README file.
7 *
8 * This file defines the application interface for the JPEG library.
9 * Most applications using the library need only include this file,
10 * and perhaps jerror.h if they want to know the exact error codes.
11 */
12
13#ifndef JPEGLIB_H
14#define JPEGLIB_H
15
16/*
17 * First we include the configuration files that record how this
18 * installation of the JPEG library is set up. jconfig.h can be
19 * generated automatically for many systems. jmorecfg.h contains
20 * manual configuration options that most people need not worry about.
21 */
22
23 #ifndef JCONFIG_INCLUDED/* in case jinclude.h already did */
24 #include "jconfig.h" /* widely used configuration options */
25#endif
26 #include "jmorecfg.h" /* seldom changed options */
27
28
29/* Version ID for the JPEG library.
30 * Might be useful for tests like "#if JPEG_LIB_VERSION >= 60".
31 */
32
33 #define JPEG_LIB_VERSION 62/* Version 6b */
34
35
36/* Various constants determining the sizes of things.
37 * All of these are specified by the JPEG standard, so don't change them
38 * if you want to be compatible.
39 */
40
41 #define DCTSIZE 8/* The basic DCT block is 8x8 samples */
42 #define DCTSIZE2 64/* DCTSIZE squared; # of elements in a block */
43 #define NUM_QUANT_TBLS 4/* Quantization tables are numbered 0..3 */
44 #define NUM_HUFF_TBLS 4/* Huffman tables are numbered 0..3 */
45 #define NUM_ARITH_TBLS 16/* Arith-coding tables are numbered 0..15 */
46 #define MAX_COMPS_IN_SCAN 4/* JPEG limit on # of components in one scan */
47 #define MAX_SAMP_FACTOR 4/* JPEG limit on sampling factors */
48/* Unfortunately, some bozo at Adobe saw no reason to be bound by the standard;
49 * the PostScript DCT filter can emit files with many more than 10 blocks/MCU.
50 * If you happen to run across such a file, you can up D_MAX_BLOCKS_IN_MCU
51 * to handle it. We even let you do this from the jconfig.h file. However,
52 * we strongly discourage changing C_MAX_BLOCKS_IN_MCU; just because Adobe
53 * sometimes emits noncompliant files doesn't mean you should too.
54 */
55#define C_MAX_BLOCKS_IN_MCU 10 /* compressor's limit on blocks per MCU */
56#ifndef D_MAX_BLOCKS_IN_MCU
57#define D_MAX_BLOCKS_IN_MCU 10 /* decompressor's limit on blocks per MCU */
58#endif
59
60
61/* Data structures for images (arrays of samples and of DCT coefficients).
62 * On 80x86 machines, the image arrays are too big for near pointers,
63 * but the pointer arrays can fit in near memory.
64 */
65
66 typedef JSAMPLE FAR *JSAMPROW;/* ptr to one image row of pixel samples. */
67 typedef JSAMPROW *JSAMPARRAY;/* ptr to some rows (a 2-D sample array) */
68 typedef JSAMPARRAY *JSAMPIMAGE;/* a 3-D sample array: top index is color */
69
70 typedef JCOEF JBLOCK[DCTSIZE2];/* one block of coefficients */
71 typedef JBLOCK FAR *JBLOCKROW;/* pointer to one row of coefficient blocks */
72 typedef JBLOCKROW *JBLOCKARRAY; /* a 2-D array of coefficient blocks */
73 typedef JBLOCKARRAY *JBLOCKIMAGE;/* a 3-D array of coefficient blocks */
74
75 typedef JCOEF FAR *JCOEFPTR;/* useful in a couple of places */
76
77
78/* Types for JPEG compression parameters and working tables. */
79
80
81/* DCT coefficient quantization tables. */
82
83typedef struct {
84 /* This array gives the coefficient quantizers in natural array order
85 * (not the zigzag order in which they are stored in a JPEG DQT marker).
86 * CAUTION: IJG versions prior to v6a kept this array in zigzag order.
87 */
88 UINT16 quantval[DCTSIZE2];/* quantization step for each coefficient */
89 /* This field is used only during compression. It's initialized FALSE when
90 * the table is created, and set TRUE when it's been output to the file.
91 * You could suppress output of a table by setting this to TRUE.
92 * (See jpeg_suppress_tables for an example.)
93 */
94 boolean sent_table; /* TRUE when table has been output */
95} JQUANT_TBL;
96
97
98/* Huffman coding tables. */
99
100typedef struct {
101 /* These two fields directly represent the contents of a JPEG DHT marker */
102 UINT8 bits[17]; /* bits[k] = # of symbols with codes of */
103 /* length k bits; bits[0] is unused */
104 UINT8 huffval[256]; /* The symbols, in order of incr code length */
105 /* This field is used only during compression. It's initialized FALSE when
106 * the table is created, and set TRUE when it's been output to the file.
107 * You could suppress output of a table by setting this to TRUE.
108 * (See jpeg_suppress_tables for an example.)
109 */
110 boolean sent_table; /* TRUE when table has been output */
111} JHUFF_TBL;
112
113
114/* Basic info about one component (color channel). */
115
116typedef struct {
117 /* These values are fixed over the whole image. */
118 /* For compression, they must be supplied by parameter setup; */
119 /* for decompression, they are read from the SOF marker. */
120 int component_id; /* identifier for this component (0..255) */
121 int component_index; /* its index in SOF or cinfo->comp_info[] */
122 int h_samp_factor; /* horizontal sampling factor (1..4) */
123 int v_samp_factor; /* vertical sampling factor (1..4) */
124 int quant_tbl_no; /* quantization table selector (0..3) */
125 /* These values may vary between scans. */
126 /* For compression, they must be supplied by parameter setup; */
127 /* for decompression, they are read from the SOS marker. */
128 /* The decompressor output side may not use these variables. */
129 int dc_tbl_no; /* DC entropy table selector (0..3) */
130 int ac_tbl_no; /* AC entropy table selector (0..3) */
131
132 /* Remaining fields should be treated as private by applications. */
133
134 /* These values are computed during compression or decompression startup: */
135 /* Component's size in DCT blocks.
136 * Any dummy blocks added to complete an MCU are not counted; therefore
137 * these values do not depend on whether a scan is interleaved or not.
138 */
139 JDIMENSION width_in_blocks;
140 JDIMENSION height_in_blocks;
141 /* Size of a DCT block in samples. Always DCTSIZE for compression.
142 * For decompression this is the size of the output from one DCT block,
143 * reflecting any scaling we choose to apply during the IDCT step.
144 * Values of 1,2,4,8 are likely to be supported. Note that different
145 * components may receive different IDCT scalings.
146 */
147 int DCT_scaled_size;
148 /* The downsampled dimensions are the component's actual, unpadded number
149 * of samples at the main buffer (preprocessing/compression interface), thus
150 * downsampled_width = ceil(image_width * Hi/Hmax)
151 * and similarly for height. For decompression, IDCT scaling is included, so
152 * downsampled_width = ceil(image_width * Hi/Hmax * DCT_scaled_size/DCTSIZE)
153 */
154 JDIMENSION downsampled_width; /* actual width in samples */
155 JDIMENSION downsampled_height; /* actual height in samples */
156 /* This flag is used only for decompression. In cases where some of the
157 * components will be ignored (eg grayscale output from YCbCr image),
158 * we can skip most computations for the unused components.
159 */
160 boolean component_needed;/* do we need the value of this component? */
161
162 /* These values are computed before starting a scan of the component. */
163 /* The decompressor output side may not use these variables. */
164 int MCU_width; /* number of blocks per MCU, horizontally */
165 int MCU_height; /* number of blocks per MCU, vertically */
166 int MCU_blocks; /* MCU_width * MCU_height */
167 int MCU_sample_width; /* MCU width in samples, MCU_width*DCT_scaled_size */
168 int last_col_width; /* # of non-dummy blocks across in last MCU */
169 int last_row_height; /* # of non-dummy blocks down in last MCU */
170
171 /* Saved quantization table for component; NULL if none yet saved.
172 * See jdinput.c comments about the need for this information.
173 * This field is currently used only for decompression.
174 */
175 JQUANT_TBL * quant_table;
176
177 /* Private per-component storage for DCT or IDCT subsystem. */
178 void * dct_table;
179} jpeg_component_info;
180
181
182/* The script for encoding a multiple-scan file is an array of these: */
183
184typedef struct {
185 int comps_in_scan; /* number of components encoded in this scan */
186 int component_index[MAX_COMPS_IN_SCAN]; /* their SOF/comp_info[] indexes */
187 int Ss, Se; /* progressive JPEG spectral selection parms */
188 int Ah, Al; /* progressive JPEG successive approx. parms */
189} jpeg_scan_info;
190
191/* The decompressor can save APPn and COM markers in a list of these: */
192
193typedef struct jpeg_marker_struct FAR * jpeg_saved_marker_ptr;
194
195struct jpeg_marker_struct {
196 jpeg_saved_marker_ptr next;/* next in list, or NULL */
197 UINT8 marker; /* marker code: JPEG_COM, or JPEG_APP0+n */
198 unsigned int original_length;/* # bytes of data in the file */
199 unsigned int data_length;/* # bytes of data saved at data[] */
200 JOCTET FAR * data; /* the data contained in the marker */
201 /* the marker length word is not counted in data_length or original_length */
202};
203
204/* Known color spaces. */
205
206typedef enum {
207 JCS_UNKNOWN, /* error/unspecified */
208 JCS_GRAYSCALE, /* monochrome */
209 JCS_RGB, /* red/green/blue */
210 JCS_YCbCr, /* Y/Cb/Cr (also known as YUV) */
211 JCS_CMYK, /* C/M/Y/K */
212 JCS_YCCK /* Y/Cb/Cr/K */
213} J_COLOR_SPACE;
214
215/* DCT/IDCT algorithm options. */
216
217typedef enum {
218 JDCT_ISLOW, /* slow but accurate integer algorithm */
219 JDCT_IFAST, /* faster, less accurate integer method */
220 JDCT_FLOAT /* floating-point: accurate, fast on fast HW */
221} J_DCT_METHOD;
222
223 #ifndef JDCT_DEFAULT /* may be overridden in jconfig.h */
224#define JDCT_DEFAULT JDCT_ISLOW
225#endif
226 #ifndef JDCT_FASTEST /* may be overridden in jconfig.h */
227#define JDCT_FASTEST JDCT_IFAST
228#endif
229
230/* Dithering options for decompression. */
231
232typedef enum {
233 JDITHER_NONE, /* no dithering */
234 JDITHER_ORDERED,/* simple ordered dither */
235 JDITHER_FS /* Floyd-Steinberg error diffusion dither */
236} J_DITHER_MODE;
237
238
239/* Common fields between JPEG compression and decompression master structs. */
240
241#define jpeg_common_fields \
242 struct jpeg_error_mgr * err;/* Error handler module */\
243 struct jpeg_memory_mgr * mem;/* Memory manager module */\
244 struct jpeg_progress_mgr * progress; /* Progress monitor, or NULL if none */\
245 void * client_data; /* Available for use by application */\
246 boolean is_decompressor;/* So common code can tell which is which */\
247 int global_state /* For checking call sequence validity */
248
249/* Routines that are to be used by both halves of the library are declared
250 * to receive a pointer to this structure. There are no actual instances of
251 * jpeg_common_struct, only of jpeg_compress_struct and jpeg_decompress_struct.
252 */
253struct jpeg_common_struct {
254 jpeg_common_fields; /* Fields common to both master struct types */
255 /* Additional fields follow in an actual jpeg_compress_struct or
256 * jpeg_decompress_struct. All three structs must agree on these
257 * initial fields! (This would be a lot cleaner in C++.)
258 */
259};
260
261typedef struct jpeg_common_struct * j_common_ptr;
262typedef struct jpeg_compress_struct * j_compress_ptr;
263typedef struct jpeg_decompress_struct * j_decompress_ptr;
264
265
266/* Master record for a compression instance */
267
268struct jpeg_compress_struct {
269 jpeg_common_fields; /* Fields shared with jpeg_decompress_struct */
270
271 /* Destination for compressed data */
272 struct jpeg_destination_mgr * dest;
273
274 /* Description of source image --- these fields must be filled in by
275 * outer application before starting compression. in_color_space must
276 * be correct before you can even call jpeg_set_defaults().
277 */
278
279 JDIMENSION image_width;/* input image width */
280 JDIMENSION image_height;/* input image height */
281 int input_components; /* # of color components in input image */
282 J_COLOR_SPACE in_color_space;/* colorspace of input image */
283
284 double input_gamma; /* image gamma of input image */
285
286 /* Compression parameters --- these fields must be set before calling
287 * jpeg_start_compress(). We recommend calling jpeg_set_defaults() to
288 * initialize everything to reasonable defaults, then changing anything
289 * the application specifically wants to change. That way you won't get
290 * burnt when new parameters are added. Also note that there are several
291 * helper routines to simplify changing parameters.
292 */
293
294 int data_precision; /* bits of precision in image data */
295
296 int num_components; /* # of color components in JPEG image */
297 J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */
298
299 jpeg_component_info * comp_info;
300 /* comp_info[i] describes component that appears i'th in SOF */
301
302 JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS];
303 /* ptrs to coefficient quantization tables, or NULL if not defined */
304
305 JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS];
306 JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS];
307 /* ptrs to Huffman coding tables, or NULL if not defined */
308
309 UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */
310 UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */
311 UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */
312
313 int num_scans; /* # of entries in scan_info array */
314 const jpeg_scan_info * scan_info; /* script for multi-scan file, or NULL */
315 /* The default value of scan_info is NULL, which causes a single-scan
316 * sequential JPEG file to be emitted. To create a multi-scan file,
317 * set num_scans and scan_info to point to an array of scan definitions.
318 */
319
320 boolean raw_data_in; /* TRUE=caller supplies downsampled data */
321 boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */
322 boolean optimize_coding;/* TRUE=optimize entropy encoding parms */
323 boolean CCIR601_sampling;/* TRUE=first samples are cosited */
324 int smoothing_factor; /* 1..100, or 0 for no input smoothing */
325 J_DCT_METHOD dct_method;/* DCT algorithm selector */
326
327 /* The restart interval can be specified in absolute MCUs by setting
328 * restart_interval, or in MCU rows by setting restart_in_rows
329 * (in which case the correct restart_interval will be figured
330 * for each scan).
331 */
332 unsigned int restart_interval; /* MCUs per restart, or 0 for no restart */
333 int restart_in_rows; /* if > 0, MCU rows per restart interval */
334
335 /* Parameters controlling emission of special markers. */
336
337 boolean write_JFIF_header;/* should a JFIF marker be written? */
338 UINT8 JFIF_major_version;/* What to write for the JFIF version number */
339 UINT8 JFIF_minor_version;
340 /* These three values are not used by the JPEG code, merely copied */
341 /* into the JFIF APP0 marker. density_unit can be 0 for unknown, */
342 /* 1 for dots/inch, or 2 for dots/cm. Note that the pixel aspect */
343 /* ratio is defined by X_density/Y_density even when density_unit=0. */
344 UINT8 density_unit; /* JFIF code for pixel size units */
345 UINT16 X_density; /* Horizontal pixel density */
346 UINT16 Y_density; /* Vertical pixel density */
347 boolean write_Adobe_marker;/* should an Adobe marker be written? */
348
349 /* State variable: index of next scanline to be written to
350 * jpeg_write_scanlines(). Application may use this to control its
351 * processing loop, e.g., "while (next_scanline < image_height)".
352 */
353
354 JDIMENSION next_scanline;/* 0 .. image_height-1 */
355
356 /* Remaining fields are known throughout compressor, but generally
357 * should not be touched by a surrounding application.
358 */
359
360 /*
361 * These fields are computed during compression startup
362 */
363 boolean progressive_mode;/* TRUE if scan script uses progressive mode */
364 int max_h_samp_factor;/* largest h_samp_factor */
365 int max_v_samp_factor;/* largest v_samp_factor */
366
367 JDIMENSION total_iMCU_rows;/* # of iMCU rows to be input to coef ctlr */
368 /* The coefficient controller receives data in units of MCU rows as defined
369 * for fully interleaved scans (whether the JPEG file is interleaved or not).
370 * There are v_samp_factor * DCTSIZE sample rows of each component in an
371 * "iMCU" (interleaved MCU) row.
372 */
373
374 /*
375 * These fields are valid during any one scan.
376 * They describe the components and MCUs actually appearing in the scan.
377 */
378 int comps_in_scan; /* # of JPEG components in this scan */
379 jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN];
380 /* *cur_comp_info[i] describes component that appears i'th in SOS */
381
382 JDIMENSION MCUs_per_row;/* # of MCUs across the image */
383 JDIMENSION MCU_rows_in_scan;/* # of MCU rows in the image */
384
385 int blocks_in_MCU; /* # of DCT blocks per MCU */
386 int MCU_membership[C_MAX_BLOCKS_IN_MCU];
387 /* MCU_membership[i] is index in cur_comp_info of component owning */
388 /* i'th block in an MCU */
389
390 int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */
391
392 /*
393 * Links to compression subobjects (methods and private variables of modules)
394 */
395 struct jpeg_comp_master * master;
396 struct jpeg_c_main_controller * main;
397 struct jpeg_c_prep_controller * prep;
398 struct jpeg_c_coef_controller * coef;
399 struct jpeg_marker_writer * marker;
400 struct jpeg_color_converter * cconvert;
401 struct jpeg_downsampler * downsample;
402 struct jpeg_forward_dct * fdct;
403 struct jpeg_entropy_encoder * entropy;
404 jpeg_scan_info * script_space; /* workspace for jpeg_simple_progression */
405 int script_space_size;
406};
407
408
409/* Master record for a decompression instance */
410
411struct jpeg_decompress_struct {
412 jpeg_common_fields; /* Fields shared with jpeg_compress_struct */
413
414 /* Source of compressed data */
415 struct jpeg_source_mgr * src;
416
417 /* Basic description of image --- filled in by jpeg_read_header(). */
418 /* Application may inspect these values to decide how to process image. */
419
420 JDIMENSION image_width;/* nominal image width (from SOF marker) */
421 JDIMENSION image_height;/* nominal image height */
422 int num_components; /* # of color components in JPEG image */
423 J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */
424
425 /* Decompression processing parameters --- these fields must be set before
426 * calling jpeg_start_decompress(). Note that jpeg_read_header() initializes
427 * them to default values.
428 */
429
430 J_COLOR_SPACE out_color_space; /* colorspace for output */
431
432 unsigned int scale_num, scale_denom; /* fraction by which to scale image */
433
434 double output_gamma; /* image gamma wanted in output */
435
436 boolean buffered_image;/* TRUE=multiple output passes */
437 boolean raw_data_out; /* TRUE=downsampled data wanted */
438
439 J_DCT_METHOD dct_method;/* IDCT algorithm selector */
440 boolean do_fancy_upsampling;/* TRUE=apply fancy upsampling */
441 boolean do_block_smoothing;/* TRUE=apply interblock smoothing */
442
443 boolean quantize_colors;/* TRUE=colormapped output wanted */
444 /* the following are ignored if not quantize_colors: */
445 J_DITHER_MODE dither_mode;/* type of color dithering to use */
446 boolean two_pass_quantize;/* TRUE=use two-pass color quantization */
447 int desired_number_of_colors;/* max # colors to use in created colormap */
448 /* these are significant only in buffered-image mode: */
449 boolean enable_1pass_quant;/* enable future use of 1-pass quantizer */
450 boolean enable_external_quant;/* enable future use of external colormap */
451 boolean enable_2pass_quant;/* enable future use of 2-pass quantizer */
452
453 /* Description of actual output image that will be returned to application.
454 * These fields are computed by jpeg_start_decompress().
455 * You can also use jpeg_calc_output_dimensions() to determine these values
456 * in advance of calling jpeg_start_decompress().
457 */
458
459 JDIMENSION output_width;/* scaled image width */
460 JDIMENSION output_height;/* scaled image height */
461 int out_color_components;/* # of color components in out_color_space */
462 int output_components;/* # of color components returned */
463 /* output_components is 1 (a colormap index) when quantizing colors;
464 * otherwise it equals out_color_components.
465 */
466 int rec_outbuf_height;/* min recommended height of scanline buffer */
467 /* If the buffer passed to jpeg_read_scanlines() is less than this many rows
468 * high, space and time will be wasted due to unnecessary data copying.
469 * Usually rec_outbuf_height will be 1 or 2, at most 4.
470 */
471
472 /* When quantizing colors, the output colormap is described by these fields.
473 * The application can supply a colormap by setting colormap non-NULL before
474 * calling jpeg_start_decompress; otherwise a colormap is created during
475 * jpeg_start_decompress or jpeg_start_output.
476 * The map has out_color_components rows and actual_number_of_colors columns.
477 */
478 int actual_number_of_colors;/* number of entries in use */
479 JSAMPARRAY colormap; /* The color map as a 2-D pixel array */
480
481 /* State variables: these variables indicate the progress of decompression.
482 * The application may examine these but must not modify them.
483 */
484
485 /* Row index of next scanline to be read from jpeg_read_scanlines().
486 * Application may use this to control its processing loop, e.g.,
487 * "while (output_scanline < output_height)".
488 */
489 JDIMENSION output_scanline;/* 0 .. output_height-1 */
490
491 /* Current input scan number and number of iMCU rows completed in scan.
492 * These indicate the progress of the decompressor input side.
493 */
494 int input_scan_number;/* Number of SOS markers seen so far */
495 JDIMENSION input_iMCU_row;/* Number of iMCU rows completed */
496
497 /* The "output scan number" is the notional scan being displayed by the
498 * output side. The decompressor will not allow output scan/row number
499 * to get ahead of input scan/row, but it can fall arbitrarily far behind.
500 */
501 int output_scan_number;/* Nominal scan number being displayed */
502 JDIMENSION output_iMCU_row;/* Number of iMCU rows read */
503
504 /* Current progression status. coef_bits[c][i] indicates the precision
505 * with which component c's DCT coefficient i (in zigzag order) is known.
506 * It is -1 when no data has yet been received, otherwise it is the point
507 * transform (shift) value for the most recent scan of the coefficient
508 * (thus, 0 at completion of the progression).
509 * This pointer is NULL when reading a non-progressive file.
510 */
511 int (*coef_bits)[DCTSIZE2];/* -1 or current Al value for each coef */
512
513 /* Internal JPEG parameters --- the application usually need not look at
514 * these fields. Note that the decompressor output side may not use
515 * any parameters that can change between scans.
516 */
517
518 /* Quantization and Huffman tables are carried forward across input
519 * datastreams when processing abbreviated JPEG datastreams.
520 */
521
522 JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS];
523 /* ptrs to coefficient quantization tables, or NULL if not defined */
524
525 JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS];
526 JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS];
527 /* ptrs to Huffman coding tables, or NULL if not defined */
528
529 /* These parameters are never carried across datastreams, since they
530 * are given in SOF/SOS markers or defined to be reset by SOI.
531 */
532
533 int data_precision; /* bits of precision in image data */
534
535 jpeg_component_info * comp_info;
536 /* comp_info[i] describes component that appears i'th in SOF */
537
538 boolean progressive_mode;/* TRUE if SOFn specifies progressive mode */
539 boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */
540
541 UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */
542 UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */
543 UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */
544
545 unsigned int restart_interval; /* MCUs per restart interval, or 0 for no restart */
546
547 /* These fields record data obtained from optional markers recognized by
548 * the JPEG library.
549 */
550 boolean saw_JFIF_marker;/* TRUE iff a JFIF APP0 marker was found */
551 /* Data copied from JFIF marker; only valid if saw_JFIF_marker is TRUE: */
552 UINT8 JFIF_major_version;/* JFIF version number */
553 UINT8 JFIF_minor_version;
554 UINT8 density_unit; /* JFIF code for pixel size units */
555 UINT16 X_density; /* Horizontal pixel density */
556 UINT16 Y_density; /* Vertical pixel density */
557 boolean saw_Adobe_marker;/* TRUE iff an Adobe APP14 marker was found */
558 UINT8 Adobe_transform;/* Color transform code from Adobe marker */
559
560 boolean CCIR601_sampling;/* TRUE=first samples are cosited */
561
562 /* Aside from the specific data retained from APPn markers known to the
563 * library, the uninterpreted contents of any or all APPn and COM markers
564 * can be saved in a list for examination by the application.
565 */
566 jpeg_saved_marker_ptr marker_list; /* Head of list of saved markers */
567
568 /* Remaining fields are known throughout decompressor, but generally
569 * should not be touched by a surrounding application.
570 */
571
572 /*
573 * These fields are computed during decompression startup
574 */
575 int max_h_samp_factor;/* largest h_samp_factor */
576 int max_v_samp_factor;/* largest v_samp_factor */
577
578 int min_DCT_scaled_size;/* smallest DCT_scaled_size of any component */
579
580 JDIMENSION total_iMCU_rows;/* # of iMCU rows in image */
581 /* The coefficient controller's input and output progress is measured in
582 * units of "iMCU" (interleaved MCU) rows. These are the same as MCU rows
583 * in fully interleaved JPEG scans, but are used whether the scan is
584 * interleaved or not. We define an iMCU row as v_samp_factor DCT block
585 * rows of each component. Therefore, the IDCT output contains
586 * v_samp_factor*DCT_scaled_size sample rows of a component per iMCU row.
587 */
588
589 JSAMPLE * sample_range_limit; /* table for fast range-limiting */
590
591 /*
592 * These fields are valid during any one scan.
593 * They describe the components and MCUs actually appearing in the scan.
594 * Note that the decompressor output side must not use these fields.
595 */
596 int comps_in_scan; /* # of JPEG components in this scan */
597 jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN];
598 /* *cur_comp_info[i] describes component that appears i'th in SOS */
599
600 JDIMENSION MCUs_per_row;/* # of MCUs across the image */
601 JDIMENSION MCU_rows_in_scan;/* # of MCU rows in the image */
602
603 int blocks_in_MCU; /* # of DCT blocks per MCU */
604 int MCU_membership[D_MAX_BLOCKS_IN_MCU];
605 /* MCU_membership[i] is index in cur_comp_info of component owning */
606 /* i'th block in an MCU */
607
608 int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */
609
610 /* This field is shared between entropy decoder and marker parser.
611 * It is either zero or the code of a JPEG marker that has been
612 * read from the data source, but has not yet been processed.
613 */
614 int unread_marker;
615
616 /*
617 * Links to decompression subobjects (methods, private variables of modules)
618 */
619 struct jpeg_decomp_master * master;
620 struct jpeg_d_main_controller * main;
621 struct jpeg_d_coef_controller * coef;
622 struct jpeg_d_post_controller * post;
623 struct jpeg_input_controller * inputctl;
624 struct jpeg_marker_reader * marker;
625 struct jpeg_entropy_decoder * entropy;
626 struct jpeg_inverse_dct * idct;
627 struct jpeg_upsampler * upsample;
628 struct jpeg_color_deconverter * cconvert;
629 struct jpeg_color_quantizer * cquantize;
630};
631
632
633/* "Object" declarations for JPEG modules that may be supplied or called
634 * directly by the surrounding application.
635 * As with all objects in the JPEG library, these structs only define the
636 * publicly visible methods and state variables of a module. Additional
637 * private fields may exist after the public ones.
638 */
639
640
641/* Error handler object */
642
643struct jpeg_error_mgr {
644 /* Error exit handler: does not return to caller */
645 JMETHOD(void, error_exit, (j_common_ptr cinfo));
646 /* Conditionally emit a trace or warning message */
647 JMETHOD(void, emit_message, (j_common_ptr cinfo, int msg_level));
648 /* Routine that actually outputs a trace or error message */
649 JMETHOD(void, output_message, (j_common_ptr cinfo));
650 /* Format a message string for the most recent JPEG error or message */
651 JMETHOD(void, format_message, (j_common_ptr cinfo, char * buffer));
652 #define JMSG_LENGTH_MAX 200/* recommended size of format_message buffer */
653 /* Reset error state variables at start of a new image */
654 JMETHOD(void, reset_error_mgr, (j_common_ptr cinfo));
655
656 /* The message ID code and any parameters are saved here.
657 * A message can have one string parameter or up to 8 int parameters.
658 */
659 int msg_code;
660#define JMSG_STR_PARM_MAX 80
661 union {
662 int i[8];
663 char s[JMSG_STR_PARM_MAX];
664 } msg_parm;
665
666 /* Standard state variables for error facility */
667
668 int trace_level; /* max msg_level that will be displayed */
669
670 /* For recoverable corrupt-data errors, we emit a warning message,
671 * but keep going unless emit_message chooses to abort. emit_message
672 * should count warnings in num_warnings. The surrounding application
673 * can check for bad data by seeing if num_warnings is nonzero at the
674 * end of processing.
675 */
676 long num_warnings; /* number of corrupt-data warnings */
677
678 /* These fields point to the table(s) of error message strings.
679 * An application can change the table pointer to switch to a different
680 * message list (typically, to change the language in which errors are
681 * reported). Some applications may wish to add additional error codes
682 * that will be handled by the JPEG library error mechanism; the second
683 * table pointer is used for this purpose.
684 *
685 * First table includes all errors generated by JPEG library itself.
686 * Error code 0 is reserved for a "no such error string" message.
687 */
688 const char * const * jpeg_message_table; /* Library errors */
689 int last_jpeg_message; /* Table contains strings 0..last_jpeg_message */
690 /* Second table can be added by application (see cjpeg/djpeg for example).
691 * It contains strings numbered first_addon_message..last_addon_message.
692 */
693 const char * const * addon_message_table; /* Non-library errors */
694 int first_addon_message;/* code for first string in addon table */
695 int last_addon_message;/* code for last string in addon table */
696};
697
698
699/* Progress monitor object */
700
701struct jpeg_progress_mgr {
702 JMETHOD(void, progress_monitor, (j_common_ptr cinfo));
703
704 long pass_counter; /* work units completed in this pass */
705 long pass_limit; /* total number of work units in this pass */
706 int completed_passes; /* passes completed so far */
707 int total_passes; /* total number of passes expected */
708};
709
710
711/* Data destination object for compression */
712
713struct jpeg_destination_mgr {
714 JOCTET * next_output_byte;/* => next byte to write in buffer */
715 size_t free_in_buffer;/* # of byte spaces remaining in buffer */
716
717 JMETHOD(void, init_destination, (j_compress_ptr cinfo));
718 JMETHOD(boolean, empty_output_buffer, (j_compress_ptr cinfo));
719 JMETHOD(void, term_destination, (j_compress_ptr cinfo));
720};
721
722
723/* Data source object for decompression */
724
725struct jpeg_source_mgr {
726 const JOCTET * next_input_byte; /* => next byte to read from buffer */
727 size_t bytes_in_buffer;/* # of bytes remaining in buffer */
728
729 JMETHOD(void, init_source, (j_decompress_ptr cinfo));
730 JMETHOD(boolean, fill_input_buffer, (j_decompress_ptr cinfo));
731 JMETHOD(void, skip_input_data, (j_decompress_ptr cinfo, long num_bytes));
732 JMETHOD(boolean, resync_to_restart, (j_decompress_ptr cinfo, int desired));
733 JMETHOD(void, term_source, (j_decompress_ptr cinfo));
734};
735
736
737/* Memory manager object.
738 * Allocates "small" objects (a few K total), "large" objects (tens of K),
739 * and "really big" objects (virtual arrays with backing store if needed).
740 * The memory manager does not allow individual objects to be freed; rather,
741 * each created object is assigned to a pool, and whole pools can be freed
742 * at once. This is faster and more convenient than remembering exactly what
743 * to free, especially where malloc()/free() are not too speedy.
744 * NB: alloc routines never return NULL. They exit to error_exit if not
745 * successful.
746 */
747
748 #define JPOOL_PERMANENT 0/* lasts until master record is destroyed */
749 #define JPOOL_IMAGE 1/* lasts until done with image/datastream */
750 #define JPOOL_NUMPOOLS2
751
752typedef struct jvirt_sarray_control * jvirt_sarray_ptr;
753typedef struct jvirt_barray_control * jvirt_barray_ptr;
754
755
756struct jpeg_memory_mgr {
757 /* Method pointers */
758 JMETHOD(void *, alloc_small, (j_common_ptr cinfo, int pool_id,
759 size_t sizeofobject));
760 JMETHOD(void FAR *, alloc_large, (j_common_ptr cinfo, int pool_id,
761 size_t sizeofobject));
762 JMETHOD(JSAMPARRAY, alloc_sarray, (j_common_ptr cinfo, int pool_id,
763 JDIMENSION samplesperrow,
764 JDIMENSION numrows));
765 JMETHOD(JBLOCKARRAY, alloc_barray, (j_common_ptr cinfo, int pool_id,
766 JDIMENSION blocksperrow,
767 JDIMENSION numrows));
768 JMETHOD(jvirt_sarray_ptr, request_virt_sarray, (j_common_ptr cinfo,
769 int pool_id,
770 boolean pre_zero,
771 JDIMENSION samplesperrow,
772 JDIMENSION numrows,
773 JDIMENSION maxaccess));
774 JMETHOD(jvirt_barray_ptr, request_virt_barray, (j_common_ptr cinfo,
775 int pool_id,
776 boolean pre_zero,
777 JDIMENSION blocksperrow,
778 JDIMENSION numrows,
779 JDIMENSION maxaccess));
780 JMETHOD(void, realize_virt_arrays, (j_common_ptr cinfo));
781 JMETHOD(JSAMPARRAY, access_virt_sarray, (j_common_ptr cinfo,
782 jvirt_sarray_ptr ptr,
783 JDIMENSION start_row,
784 JDIMENSION num_rows,
785 boolean writable));
786 JMETHOD(JBLOCKARRAY, access_virt_barray, (j_common_ptr cinfo,
787 jvirt_barray_ptr ptr,
788 JDIMENSION start_row,
789 JDIMENSION num_rows,
790 boolean writable));
791 JMETHOD(void, free_pool, (j_common_ptr cinfo, int pool_id));
792 JMETHOD(void, self_destruct, (j_common_ptr cinfo));
793
794 /* Limit on memory allocation for this JPEG object. (Note that this is
795 * merely advisory, not a guaranteed maximum; it only affects the space
796 * used for virtual-array buffers.) May be changed by outer application
797 * after creating the JPEG object.
798 */
799 long max_memory_to_use;
800
801 /* Maximum allocation request accepted by alloc_large. */
802 long max_alloc_chunk;
803};
804
805
806/* Routine signature for application-supplied marker processing methods.
807 * Need not pass marker code since it is stored in cinfo->unread_marker.
808 */
809typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo));
810
811
812/* Declarations for routines called by application.
813 * The JPP macro hides prototype parameters from compilers that can't cope.
814 * Note JPP requires double parentheses.
815 */
816
817#ifdef HAVE_PROTOTYPES
818 #define JPP(arglist)arglist
819#else
820 #define JPP(arglist)()
821#endif
822
823
824/* Short forms of external names for systems with brain-damaged linkers.
825 * We shorten external names to be unique in the first six letters, which
826 * is good enough for all known systems.
827 * (If your compiler itself needs names to be unique in less than 15
828 * characters, you are out of luck. Get a better compiler.)
829 */
830
831#ifdef NEED_SHORT_EXTERNAL_NAMES
832 #define jpeg_std_error jStdError
833 #define jpeg_CreateCompressjCreaCompress
834 #define jpeg_CreateDecompressjCreaDecompress
835 #define jpeg_destroy_compressjDestCompress
836 #define jpeg_destroy_decompressjDestDecompress
837 #define jpeg_stdio_dest jStdDest
838 #define jpeg_stdio_src jStdSrc
839 #define jpeg_set_defaultsjSetDefaults
840 #define jpeg_set_colorspacejSetColorspace
841 #define jpeg_default_colorspacejDefColorspace
842 #define jpeg_set_qualityjSetQuality
843 #define jpeg_set_linear_qualityjSetLQuality
844 #define jpeg_add_quant_tablejAddQuantTable
845 #define jpeg_quality_scalingjQualityScaling
846 #define jpeg_simple_progressionjSimProgress
847 #define jpeg_suppress_tablesjSuppressTables
848 #define jpeg_alloc_quant_tablejAlcQTable
849 #define jpeg_alloc_huff_tablejAlcHTable
850 #define jpeg_start_compressjStrtCompress
851 #define jpeg_write_scanlinesjWrtScanlines
852 #define jpeg_finish_compressjFinCompress
853 #define jpeg_write_raw_datajWrtRawData
854 #define jpeg_write_markerjWrtMarker
855 #define jpeg_write_m_headerjWrtMHeader
856 #define jpeg_write_m_bytejWrtMByte
857 #define jpeg_write_tablesjWrtTables
858 #define jpeg_read_headerjReadHeader
859 #define jpeg_start_decompressjStrtDecompress
860 #define jpeg_read_scanlinesjReadScanlines
861 #define jpeg_finish_decompressjFinDecompress
862 #define jpeg_read_raw_datajReadRawData
863 #define jpeg_has_multiple_scansjHasMultScn
864 #define jpeg_start_outputjStrtOutput
865 #define jpeg_finish_outputjFinOutput
866 #define jpeg_input_completejInComplete
867 #define jpeg_new_colormapjNewCMap
868 #define jpeg_consume_inputjConsumeInput
869 #define jpeg_calc_output_dimensionsjCalcDimensions
870 #define jpeg_save_markersjSaveMarkers
871 #define jpeg_set_marker_processorjSetMarker
872 #define jpeg_read_coefficientsjReadCoefs
873 #define jpeg_write_coefficientsjWrtCoefs
874 #define jpeg_copy_critical_parametersjCopyCrit
875 #define jpeg_abort_compressjAbrtCompress
876 #define jpeg_abort_decompressjAbrtDecompress
877 #define jpeg_abort jAbort
878 #define jpeg_destroy jDestroy
879 #define jpeg_resync_to_restartjResyncRestart
880#endif /* NEED_SHORT_EXTERNAL_NAMES */
881
882
883/* Default error-management setup */
884EXTERN(struct jpeg_error_mgr *) jpeg_std_error
885 JPP((struct jpeg_error_mgr * err));
886
887/* Initialization of JPEG compression objects.
888 * jpeg_create_compress() and jpeg_create_decompress() are the exported
889 * names that applications should call. These expand to calls on
890 * jpeg_CreateCompress and jpeg_CreateDecompress with additional information
891 * passed for version mismatch checking.
892 * NB: you must set up the error-manager BEFORE calling jpeg_create_xxx.
893 */
894#define jpeg_create_compress(cinfo) \
895 jpeg_CreateCompress((cinfo), JPEG_LIB_VERSION, \
896 (size_t) sizeof(struct jpeg_compress_struct))
897#define jpeg_create_decompress(cinfo) \
898 jpeg_CreateDecompress((cinfo), JPEG_LIB_VERSION, \
899 (size_t) sizeof(struct jpeg_decompress_struct))
900EXTERN(void) jpeg_CreateCompress JPP((j_compress_ptr cinfo,
901 int version, size_t structsize));
902EXTERN(void) jpeg_CreateDecompress JPP((j_decompress_ptr cinfo,
903 int version, size_t structsize));
904/* Destruction of JPEG compression objects */
905EXTERN(void) jpeg_destroy_compress JPP((j_compress_ptr cinfo));
906EXTERN(void) jpeg_destroy_decompress JPP((j_decompress_ptr cinfo));
907
908/* Standard data source and destination managers: stdio streams. */
909/* Caller is responsible for opening the file before and closing after. */
910EXTERN(void) jpeg_stdio_dest JPP((j_compress_ptr cinfo, FILE * outfile));
911EXTERN(void) jpeg_stdio_src JPP((j_decompress_ptr cinfo, FILE * infile));
912
913/* Default parameter setup for compression */
914EXTERN(void) jpeg_set_defaults JPP((j_compress_ptr cinfo));
915/* Compression parameter setup aids */
916EXTERN(void) jpeg_set_colorspace JPP((j_compress_ptr cinfo,
917 J_COLOR_SPACE colorspace));
918EXTERN(void) jpeg_default_colorspace JPP((j_compress_ptr cinfo));
919EXTERN(void) jpeg_set_quality JPP((j_compress_ptr cinfo, int quality,
920 boolean force_baseline));
921EXTERN(void) jpeg_set_linear_quality JPP((j_compress_ptr cinfo,
922 int scale_factor,
923 boolean force_baseline));
924EXTERN(void) jpeg_add_quant_table JPP((j_compress_ptr cinfo, int which_tbl,
925 const unsigned int *basic_table,
926 int scale_factor,
927 boolean force_baseline));
928EXTERN(int) jpeg_quality_scaling JPP((int quality));
929EXTERN(void) jpeg_simple_progression JPP((j_compress_ptr cinfo));
930EXTERN(void) jpeg_suppress_tables JPP((j_compress_ptr cinfo,
931 boolean suppress));
932EXTERN(JQUANT_TBL *) jpeg_alloc_quant_table JPP((j_common_ptr cinfo));
933EXTERN(JHUFF_TBL *) jpeg_alloc_huff_table JPP((j_common_ptr cinfo));
934
935/* Main entry points for compression */
936EXTERN(void) jpeg_start_compress JPP((j_compress_ptr cinfo,
937 boolean write_all_tables));
938EXTERN(JDIMENSION) jpeg_write_scanlines JPP((j_compress_ptr cinfo,
939 JSAMPARRAY scanlines,
940 JDIMENSION num_lines));
941EXTERN(void) jpeg_finish_compress JPP((j_compress_ptr cinfo));
942
943/* Replaces jpeg_write_scanlines when writing raw downsampled data. */
944EXTERN(JDIMENSION) jpeg_write_raw_data JPP((j_compress_ptr cinfo,
945 JSAMPIMAGE data,
946 JDIMENSION num_lines));
947
948/* Write a special marker. See libjpeg.doc concerning safe usage. */
949EXTERN(void) jpeg_write_marker
950 JPP((j_compress_ptr cinfo, int marker,
951 const JOCTET * dataptr, unsigned int datalen));
952/* Same, but piecemeal. */
953EXTERN(void) jpeg_write_m_header
954 JPP((j_compress_ptr cinfo, int marker, unsigned int datalen));
955EXTERN(void) jpeg_write_m_byte
956 JPP((j_compress_ptr cinfo, int val));
957
958/* Alternate compression function: just write an abbreviated table file */
959EXTERN(void) jpeg_write_tables JPP((j_compress_ptr cinfo));
960
961/* Decompression startup: read start of JPEG datastream to see what's there */
962EXTERN(int) jpeg_read_header JPP((j_decompress_ptr cinfo,
963 boolean require_image));
964/* Return value is one of: */
965 #define JPEG_SUSPENDED 0 /* Suspended due to lack of input data */
966 #define JPEG_HEADER_OK 1 /* Found valid image datastream */
967 #define JPEG_HEADER_TABLES_ONLY2 /* Found valid table-specs-only datastream */
968/* If you pass require_image = TRUE (normal case), you need not check for
969 * a TABLES_ONLY return code; an abbreviated file will cause an error exit.
970 * JPEG_SUSPENDED is only possible if you use a data source module that can
971 * give a suspension return (the stdio source module doesn't).
972 */
973
974/* Main entry points for decompression */
975EXTERN(boolean) jpeg_start_decompress JPP((j_decompress_ptr cinfo));
976EXTERN(JDIMENSION) jpeg_read_scanlines JPP((j_decompress_ptr cinfo,
977 JSAMPARRAY scanlines,
978 JDIMENSION max_lines));
979EXTERN(boolean) jpeg_finish_decompress JPP((j_decompress_ptr cinfo));
980
981/* Replaces jpeg_read_scanlines when reading raw downsampled data. */
982EXTERN(JDIMENSION) jpeg_read_raw_data JPP((j_decompress_ptr cinfo,
983 JSAMPIMAGE data,
984 JDIMENSION max_lines));
985
986/* Additional entry points for buffered-image mode. */
987EXTERN(boolean) jpeg_has_multiple_scans JPP((j_decompress_ptr cinfo));
988EXTERN(boolean) jpeg_start_output JPP((j_decompress_ptr cinfo,
989 int scan_number));
990EXTERN(boolean) jpeg_finish_output JPP((j_decompress_ptr cinfo));
991EXTERN(boolean) jpeg_input_complete JPP((j_decompress_ptr cinfo));
992EXTERN(void) jpeg_new_colormap JPP((j_decompress_ptr cinfo));
993EXTERN(int) jpeg_consume_input JPP((j_decompress_ptr cinfo));
994/* Return value is one of: */
995 /* #define JPEG_SUSPENDED0 Suspended due to lack of input data */
996 #define JPEG_REACHED_SOS1 /* Reached start of new scan */
997 #define JPEG_REACHED_EOI2 /* Reached end of image */
998 #define JPEG_ROW_COMPLETED3 /* Completed one iMCU row */
999 #define JPEG_SCAN_COMPLETED4 /* Completed last iMCU row of a scan */
1000
1001/* Precalculate output dimensions for current decompression parameters. */
1002EXTERN(void) jpeg_calc_output_dimensions JPP((j_decompress_ptr cinfo));
1003
1004/* Control saving of COM and APPn markers into marker_list. */
1005EXTERN(void) jpeg_save_markers
1006 JPP((j_decompress_ptr cinfo, int marker_code,
1007 unsigned int length_limit));
1008
1009/* Install a special processing method for COM or APPn markers. */
1010EXTERN(void) jpeg_set_marker_processor
1011 JPP((j_decompress_ptr cinfo, int marker_code,
1012 jpeg_marker_parser_method routine));
1013
1014/* Read or write raw DCT coefficients --- useful for lossless transcoding. */
1015EXTERN(jvirt_barray_ptr *) jpeg_read_coefficients JPP((j_decompress_ptr cinfo));
1016EXTERN(void) jpeg_write_coefficients JPP((j_compress_ptr cinfo,
1017 jvirt_barray_ptr * coef_arrays));
1018EXTERN(void) jpeg_copy_critical_parameters JPP((j_decompress_ptr srcinfo,
1019 j_compress_ptr dstinfo));
1020
1021/* If you choose to abort compression or decompression before completing
1022 * jpeg_finish_(de)compress, then you need to clean up to release memory,
1023 * temporary files, etc. You can just call jpeg_destroy_(de)compress
1024 * if you're done with the JPEG object, but if you want to clean it up and
1025 * reuse it, call this:
1026 */
1027EXTERN(void) jpeg_abort_compress JPP((j_compress_ptr cinfo));
1028EXTERN(void) jpeg_abort_decompress JPP((j_decompress_ptr cinfo));
1029
1030/* Generic versions of jpeg_abort and jpeg_destroy that work on either
1031 * flavor of JPEG object. These may be more convenient in some places.
1032 */
1033EXTERN(void) jpeg_abort JPP((j_common_ptr cinfo));
1034EXTERN(void) jpeg_destroy JPP((j_common_ptr cinfo));
1035
1036/* Default restart-marker-resync procedure for use by data source modules */
1037EXTERN(boolean) jpeg_resync_to_restart JPP((j_decompress_ptr cinfo,
1038 int desired));
1039
1040
1041/* These marker codes are exported since applications and data source modules
1042 * are likely to want to use them.
1043 */
1044
1045 #define JPEG_RST0 0xD0/* RST0 marker code */
1046 #define JPEG_EOI 0xD9/* EOI marker code */
1047 #define JPEG_APP0 0xE0/* APP0 marker code */
1048 #define JPEG_COM 0xFE/* COM marker code */
1049
1050
1051/* If we have a brain-damaged compiler that emits warnings (or worse, errors)
1052 * for structure definitions that are never filled in, keep it quiet by
1053 * supplying dummy definitions for the various substructures.
1054 */
1055
1056#ifdef INCOMPLETE_TYPES_BROKEN
1057 #ifndef JPEG_INTERNALS /* will be defined in jpegint.h */
1058struct jvirt_sarray_control { long dummy; };
1059struct jvirt_barray_control { long dummy; };
1060struct jpeg_comp_master { long dummy; };
1061struct jpeg_c_main_controller { long dummy; };
1062struct jpeg_c_prep_controller { long dummy; };
1063struct jpeg_c_coef_controller { long dummy; };
1064struct jpeg_marker_writer { long dummy; };
1065struct jpeg_color_converter { long dummy; };
1066struct jpeg_downsampler { long dummy; };
1067struct jpeg_forward_dct { long dummy; };
1068struct jpeg_entropy_encoder { long dummy; };
1069struct jpeg_decomp_master { long dummy; };
1070struct jpeg_d_main_controller { long dummy; };
1071struct jpeg_d_coef_controller { long dummy; };
1072struct jpeg_d_post_controller { long dummy; };
1073struct jpeg_input_controller { long dummy; };
1074struct jpeg_marker_reader { long dummy; };
1075struct jpeg_entropy_decoder { long dummy; };
1076struct jpeg_inverse_dct { long dummy; };
1077struct jpeg_upsampler { long dummy; };
1078struct jpeg_color_deconverter { long dummy; };
1079struct jpeg_color_quantizer { long dummy; };
1080#endif /* JPEG_INTERNALS */
1081#endif /* INCOMPLETE_TYPES_BROKEN */
1082
1083
1084/*
1085 * The JPEG library modules define JPEG_INTERNALS before including this file.
1086 * The internal structure declarations are read only when that is true.
1087 * Applications using the library should not include jpegint.h, but may wish
1088 * to include jerror.h.
1089 */
1090
1091#ifdef JPEG_INTERNALS
1092 #include "jpegint.h" /* fetch private declarations */
1093 #include "jerror.h" /* fetch error codes too */
1094#endif
1095
1096#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 @@
1 TEMPLATE= lib
2 CONFIG += qt warn_on release
3 HEADERS = libflashplugin.h libflashpluginimpl.h
4 SOURCES = libflashplugin.cpp libflashpluginimpl.cpp \
5 adpcm.cc character.cc flash.cc graphic16.cc matrix.cc script.cc \
6 sprite.cc bitmap.cc cxform.cc font.cc graphic24.cc movie.cc \
7 shape.cc sqrt.cc button.cc displaylist.cc graphic.cc graphic32.cc \
8 program.cc sound.cc text.cc
9 TARGET = flashplugin
10 DESTDIR = ../../plugins/codecs
11INCLUDEPATH += $(QPEDIR)/include ..
12DEPENDPATH += ../$(QPEDIR)/include ..
13LIBS += -lqpe
14 VERSION = 1.0.0
15
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 @@
1/**********************************************************************
2** Copyright (C) 2001 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#include "libflashplugin.h"
21
22#if 0
23
24bool LibFlashPlugin::audioReadSamples( short *output, int channel, long samples, int stream ) {
25}
26
27
28bool LibFlashPlugin::audioReReadSamples( short *output, int channel, long samples, int stream ) {
29}
30
31
32bool LibFlashPlugin::audioReadMonoSamples( short *output, long samples, long& samplesRead, int stream ) {
33 samplesRead = samples;
34}
35
36
37bool LibFlashPlugin::audioReadStereoSamples( short *output, long samples, long& samplesRead, int stream ) {
38}
39
40
41bool LibFlashPlugin::videoReadFrame( unsigned char **output_rows, int in_x, int in_y, int in_w, int in_h, ColorFormat color_model, int stream ) {
42}
43
44
45bool 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 ) {
46/*
47 int format = MPEG3_RGB565;
48 switch ( color_model ) {
49 case RGB565:format = MPEG3_RGB565; break;
50 case RGBA8888:format = MPEG3_RGBA8888; break;
51 case BGRA8888:format = MPEG3_BGRA8888; break;
52 }
53*/
54}
55
56
57bool 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 ) {
58}
59
60
61FlashHandle file;
62FlashDisplay *fd;
63
64#endif
65
66
67LibFlashPlugin::LibFlashPlugin() {
68 file = NULL;
69 fd = 0;
70}
71#include <stdio.h>
72#include <stdlib.h>
73static int readFile(const char *filename, char **buffer, long *size)
74{
75 FILE *in;
76 char *buf;
77 long length;
78
79 printf("read files\n");
80
81 in = fopen(filename,"r");
82 if (in == 0) {
83 perror(filename);
84 return -1;
85 }
86 fseek(in,0,SEEK_END);
87 length = ftell(in);
88 rewind(in);
89 buf = (char *)malloc(length);
90 fread(buf,length,1,in);
91 fclose(in);
92
93 *size = length;
94 *buffer = buf;
95
96 return length;
97}
98
99static void showUrl(char *url, char * /*target*/, void * /*client_data*/) {
100 printf("get url\n");
101 printf("GetURL : %s\n", url);
102}
103
104static void getSwf(char *url, int level, void *client_data) {
105 FlashHandle flashHandle = (FlashHandle) client_data;
106 char *buffer;
107 long size;
108
109 printf("get swf\n");
110
111 printf("LoadMovie: %s @ %d\n", url, level);
112 if (readFile(url, &buffer, &size) > 0) {
113 FlashParse(flashHandle, level, buffer, size);
114 }
115}
116
117bool LibFlashPlugin::open( const QString& fileName ) {
118
119 printf("opening file\n");
120
121 delete fd;
122 fd = new FlashDisplay;
123 fd->pixels = new int[320*240*4];
124 fd->width = 200;
125 fd->bpl = 320*2;
126 fd->height = 300;
127 fd->depth = 16;
128 fd->bpp = 2;
129 fd->flash_refresh = 25;
130 fd->clip_x = 0;
131 fd->clip_y = 0;
132 fd->clip_width = 0;
133 fd->clip_height = 0;
134
135 char *buffer;
136 long size;
137 int status;
138 struct FlashInfo fi;
139
140 if (readFile(fileName.latin1(), &buffer, &size) < 0)
141 exit(2);
142
143 if (!(file = FlashNew()))
144 exit(1);
145
146 do
147 status = FlashParse(file, 0, buffer, size);
148 while (status & FLASH_PARSE_NEED_DATA);
149
150 free(buffer);
151 FlashGetInfo(file, &fi);
152 //FlashSettings(flashHandle, PLAYER_LOOP);
153 FlashGraphicInit(file, fd);
154 FlashSoundInit(file, "/dev/dsp");
155 FlashSetGetUrlMethod(file, showUrl, 0);
156 FlashSetGetSwfMethod(file, getSwf, (void*)file);
157
158 printf("opened file\n");
159}
160
161// If decoder doesn't support audio then return 0 here
162bool LibFlashPlugin::audioSetSample( long sample, int stream ) { return TRUE; }
163long LibFlashPlugin::audioGetSample( int stream ) { return 0; }
164//bool LibFlashPlugin::audioReadMonoSamples( short *output, long samples, long& samplesRead, int stream ) { return TRUE; }
165//bool LibFlashPlugin::audioReadStereoSamples( short *output, long samples, long& samplesRead, int stream ) { return FALSE; }
166bool LibFlashPlugin::audioReadSamples( short *output, int channels, long samples, long& samplesRead, int stream ) { return FALSE; }
167//bool LibFlashPlugin::audioReadSamples( short *output, int channel, long samples, int stream ) { return TRUE; }
168//bool LibFlashPlugin::audioReReadSamples( short *output, int channel, long samples, int stream ) { return TRUE; }
169
170// If decoder doesn't support video then return 0 here
171int LibFlashPlugin::videoStreams() { return 1; }
172int LibFlashPlugin::videoWidth( int stream ) { return 300; }
173int LibFlashPlugin::videoHeight( int stream ) { return 200; }
174double LibFlashPlugin::videoFrameRate( int stream ) { return 25.0; }
175int LibFlashPlugin::videoFrames( int stream ) { return 1000000; }
176bool LibFlashPlugin::videoSetFrame( long frame, int stream ) { return TRUE; }
177long LibFlashPlugin::videoGetFrame( int stream ) { return 0; }
178bool 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; }
179#include <time.h>
180bool 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 ) {
181 struct timeval wd;
182 FlashEvent fe;
183
184/*
185 delete fd;
186 fd = new FlashDisplay;
187 fd->pixels = output_rows[0];
188 fd->width = 300; // out_w;
189 fd->bpl = 640; // out_w*2;
190 fd->height = 200;//out_h;
191 fd->depth = 16;
192 fd->bpp = 2;
193 fd->flash_refresh = 50;
194 fd->clip_x = 0;//in_x;
195 fd->clip_y = 0;//in_y;
196 fd->clip_width = 300;//in_w;
197 fd->clip_height = 200;//in_h;
198 FlashGraphicInit(file, fd);
199*/
200
201 long cmd = FLASH_WAKEUP;
202 FlashExec(file, cmd, 0, &wd);
203
204 fe.type = FeRefresh;
205 cmd = FLASH_EVENT;
206 FlashExec(file, cmd, &fe, &wd);
207/*
208 for (int i = 0; i < out_h; i++)
209 memcpy( output_rows[i], (char*)fd->pixels + i*fd->bpl, QMIN( fd->width * fd->bpp, out_w * fd->bpp ) );
210 */
211 memcpy( output_rows[0], (char*)fd->pixels, out_w * out_h * 2 );
212}
213
214bool 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; }
215
216// Profiling
217double LibFlashPlugin::getTime() { return 0.0; }
218
219// Ignore if these aren't supported
220bool LibFlashPlugin::setSMP( int cpus ) { return TRUE; }
221bool LibFlashPlugin::setMMX( bool useMMX ) { return TRUE; }
222
223
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 @@
1/**********************************************************************
2** Copyright (C) 2001 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef LIBFLASH_PLUGIN_H
21#define LIBFLASH_PLUGIN_H
22
23
24#include <qstring.h>
25#include <qapplication.h>
26#include "flash.h"
27#include "mediaplayerplugininterface.h"
28
29
30class LibFlashPlugin : public MediaPlayerDecoder {
31
32public:
33 LibFlashPlugin();
34 ~LibFlashPlugin() { close(); }
35
36 const char *pluginName() { return "LibFlashPlugin: " PLUGIN_NAME " " FLASH_VERSION_STRING; }
37 const char *pluginComment() { return "This is the libflash library: " PLUGIN_NAME " " FLASH_VERSION_STRING; }
38 double pluginVersion() { return 1.0; }
39
40 bool isFileSupported( const QString& fileName ) { return fileName.right(4) == ".swf"; }
41 bool open( const QString& fileName );
42 bool close() { FlashClose( file ); file = NULL; return TRUE; }
43 bool isOpen() { return file != NULL; }
44 const QString &fileInfo() { return strInfo = qApp->translate( "MediaPlayer", "No Information Available", "media plugin text" ); }
45
46 // If decoder doesn't support audio then return 0 here
47 int audioStreams() { return 1; }
48 int audioChannels( int /*stream*/ ) { return 2; }
49 int audioFrequency( int /*stream*/ ) { return 44100; }
50 int audioSamples( int /*stream*/ ) { return 1000000; }
51 bool audioSetSample( long sample, int stream );
52 long audioGetSample( int stream );
53 //bool audioReadMonoSamples( short *output, long samples, long& samplesRead, int stream );
54 //bool audioReadStereoSamples( short *output, long samples, long& samplesRead, int stream );
55 bool audioReadSamples( short *output, int channels, long samples, long& samplesRead, int stream );
56 //bool audioReadSamples( short *output, int channel, long samples, int stream );
57 //bool audioReReadSamples( short *output, int channel, long samples, int stream );
58
59 // If decoder doesn't support video then return 0 here
60 int videoStreams();
61 int videoWidth( int stream );
62 int videoHeight( int stream );
63 double videoFrameRate( int stream );
64 int videoFrames( int stream );
65 bool videoSetFrame( long frame, int stream );
66 long videoGetFrame( int stream );
67 bool videoReadFrame( unsigned char **output_rows, int in_x, int in_y, int in_w, int in_h, ColorFormat color_model, int stream );
68 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 );
69 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 );
70
71 // Profiling
72 double getTime();
73
74 // Ignore if these aren't supported
75 bool setSMP( int cpus );
76 bool setMMX( bool useMMX );
77
78 // Capabilities
79 bool supportsAudio() { return TRUE; }
80 bool supportsVideo() { return TRUE; }
81 bool supportsYUV() { return TRUE; }
82 bool supportsMMX() { return TRUE; }
83 bool supportsSMP() { return TRUE; }
84 bool supportsStereo() { return TRUE; }
85 bool supportsScaling() { return TRUE; }
86
87private:
88 FlashHandle file;
89 FlashDisplay *fd;
90 QString strInfo;
91
92};
93
94
95#endif
96
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#include "libflashplugin.h"
21#include "libflashpluginimpl.h"
22
23
24LibFlashPluginImpl::LibFlashPluginImpl()
25 : libflashplugin(0), ref(0)
26{
27}
28
29
30LibFlashPluginImpl::~LibFlashPluginImpl()
31{
32 if ( libflashplugin )
33 delete libflashplugin;
34}
35
36
37MediaPlayerDecoder *LibFlashPluginImpl::decoder()
38{
39 if ( !libflashplugin )
40 libflashplugin = new LibFlashPlugin;
41 return libflashplugin;
42}
43
44
45MediaPlayerEncoder *LibFlashPluginImpl::encoder()
46{
47 return NULL;
48}
49
50
51#ifndef QT_NO_COMPONENT
52
53
54QRESULT LibFlashPluginImpl::queryInterface( const QUuid &uuid, QUnknownInterface **iface )
55{
56 *iface = 0;
57 if ( ( uuid == IID_QUnknown ) || ( uuid == IID_MediaPlayerPlugin ) )
58 *iface = this, (*iface)->addRef();
59 return QS_OK;
60}
61
62
63Q_EXPORT_INTERFACE()
64{
65 Q_CREATE_INSTANCE( LibFlashPluginImpl )
66}
67
68
69#endif
70
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 @@
1/**********************************************************************
2** Copyright (C) 2001 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef LIBFLASH_PLUGIN_IMPL_H
21#define LIBFLASH_PLUGIN_IMPL_H
22
23
24#include "../mediaplayerplugininterface.h"
25
26
27class LibFlashPlugin;
28
29
30class LibFlashPluginImpl : public MediaPlayerPluginInterface
31{
32public:
33 LibFlashPluginImpl();
34 virtual ~LibFlashPluginImpl();
35
36#ifndef QT_NO_COMPONENT
37
38 QRESULT queryInterface( const QUuid&, QUnknownInterface** );
39 Q_REFCOUNT
40
41#endif
42
43 virtual MediaPlayerDecoder *decoder();
44 virtual MediaPlayerEncoder *encoder();
45
46private:
47 LibFlashPlugin *libflashplugin;
48 ulong ref;
49};
50
51
52#endif
53
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 @@
1/////////////////////////////////////////////////////////////
2// Flash Plugin and Player
3// Copyright (C) 1998,1999 Olivier Debon
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19///////////////////////////////////////////////////////////////
20// Author : Olivier Debon <odebon@club-internet.fr>
21//
22
23#include "matrix.h"
24
25#ifdef RCSID
26static char *rcsid = "$Id$";
27#endif
28
29Matrix::Matrix()
30{
31 a = 1.0;
32 d = 1.0;
33 b = c = 0.0;
34 tx = ty = 0;
35}
36
37Matrix Matrix::operator*(Matrix m)
38{
39 Matrix mat;
40
41 mat.a = this->a * m.a + this->b * m.c;
42 mat.b = this->a * m.b + this->b * m.d;
43 mat.c = this->c * m.a + this->d * m.c;
44 mat.d = this->c * m.b + this->d * m.d;
45
46 mat.tx = this->getX(m.tx,m.ty);
47 mat.ty = this->getY(m.tx,m.ty);
48
49 return mat;
50}
51
52Matrix Matrix::invert()
53{
54 Matrix mat;
55 float det;
56
57 det = a*d-b*c;
58
59 mat.a = d/det;
60 mat.b = -b/det;
61 mat.c = -c/det;
62 mat.d = a/det;
63
64 mat.tx = - (long)(mat.a * tx + mat.b * ty);
65 mat.ty = - (long)(mat.c * tx + mat.d * ty);
66
67 return mat;
68}
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 @@
1/////////////////////////////////////////////////////////////
2// Flash Plugin and Player
3// Copyright (C) 1998,1999 Olivier Debon
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19///////////////////////////////////////////////////////////////
20#ifndef _MATRIX_H_
21#define _MATRIX_H_
22
23struct Matrix {
24 float a,b,c,d;
25 long tx,ty;
26public:
27 Matrix operator*(Matrix);
28 Matrix invert();
29 Matrix();
30
31#ifdef DUMP
32 void dump(BitStream *bs);
33#endif
34
35 inline
36 long Matrix::getX(long x, long y)
37 {
38 return (long) (x*a+y*b+tx);
39 };
40
41 inline
42 long Matrix::getY(long x, long y)
43 {
44 return (long) (x*c+y*d+ty);
45 };
46
47};
48
49#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 @@
1////////////////////////////////////////////////////////////
2// Flash Plugin and Player
3// Copyright (C) 1998,1999 Olivier Debon
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19///////////////////////////////////////////////////////////////
20// Author : Olivier Debon <odebon@club-internet.fr>
21//
22#include "movie.h"
23
24FlashMovie::FlashMovie()
25{
26 gd = NULL;
27 sm = NULL;
28 getSwf = NULL;
29 getUrl = NULL;
30 cursorOnOff = NULL;
31 buttons_updated = 0;
32 scheduledTime.tv_sec = -1;
33 cur_focus = NULL;
34 lost_over = NULL;
35 msPerFrame = 0;
36
37 /* mouse handling */
38 mouse_active = 0;
39 mouse_x = -1;
40 mouse_y = -1;
41 button_pressed = 0;
42 refresh = 1;
43}
44
45FlashMovie::~FlashMovie()
46{
47 CInputScript *n;
48
49 while (main != NULL) {
50 n = main->next;
51 delete main;
52 main = n;
53 }
54
55 if (gd) delete gd;
56 if (sm) delete sm;
57}
58
59int
60FlashMovie::processMovie(GraphicDevice *gd, SoundMixer *sm)
61{
62 CInputScript *script;
63 int wakeUp = 0;
64
65 if (sm && sm->playSounds()) {
66 wakeUp = 1;
67 }
68 for (script = this->main; script != NULL; script = script->next) {
69 if (script->program == NULL) continue;
70 if (script->program->nbFrames == 0) continue;
71 if (script->program->processMovie(gd,sm)) {
72 wakeUp = 1;
73 }
74 }
75 renderMovie();
76 return wakeUp;
77}
78
79int
80FlashMovie::handleEvent(GraphicDevice *gd, SoundMixer *sm, FlashEvent *event)
81{
82 int wakeUp = 0;
83
84 if (sm && sm->playSounds()) {
85 wakeUp = 1;
86 }
87 if (this->main == 0) return 0;
88 if (this->main->program == 0) return 0;
89 if (this->main->program->handleEvent(gd, sm, event)) {
90 wakeUp = 1;
91 }
92 renderMovie();
93 return wakeUp;
94}
95
96/* current focus bigger and translated if needed */
97void
98FlashMovie::renderFocus()
99{
100 Rect rect,boundary;
101 Matrix mat;
102
103 if (mouse_active || !cur_focus) return;
104
105 /* rect is the bbox in screen coordinates */
106
107 // Compute the bounding box in screen coordinates
108 cur_focus->character->getBoundingBox(&boundary,cur_focus);
109 mat = (*gd->adjust) * cur_focus->renderMatrix;
110 transformBoundingBox(&rect, &mat, &boundary, 1);
111
112 gd->drawBox(rect.xmin, rect.ymin, rect.xmax, rect.ymax);
113}
114
115void
116FlashMovie::renderMovie()
117{
118 CInputScript *script,*prev,*next;
119 Rect clipping;
120 Matrix identity;
121
122 clipping.reset();
123
124 // First pass to update the clipping region
125 for (script = this->main; script != NULL; script = script->next) {
126 if (script->level == -1) {
127 clipping.xmin = -32768;
128 clipping.ymin = -32768;
129 clipping.xmax = 32767;
130 clipping.ymax = 32767;
131 continue;
132 }
133 if (script->program == NULL) continue;
134 if (script->program->dl->bbox.xmin == LONG_MAX) continue;
135 transformBoundingBox(&clipping, &identity, &script->program->dl->bbox, 0);
136 script->program->render = 0;
137 }
138
139 if (clipping.xmin == LONG_MAX) return;
140
141 // Update the clipping region
142 gd->updateClippingRegion(&clipping);
143 gd->clearCanvas();
144
145 // Second pass to render the movie
146 for (script = this->main; script != NULL; script = script->next) {
147 if (script->level == -1) continue;
148 if (script->program == NULL) continue;
149 script->program->dl->render(gd);
150 }
151 renderFocus();
152
153 // Final pass to delete some movies
154 script = this->main;
155 prev = 0;
156 while (script != NULL) {
157 if (script->level == -1) {
158 next = script->next;
159 if (prev == 0) {
160 this->main = next;
161 } else {
162 prev->next = next;
163 }
164 delete script;
165 script = next;
166 } else {
167 prev = script;
168 script = script->next;
169 }
170 }
171}
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 @@
1/////////////////////////////////////////////////////////////
2// Flash Plugin and Player
3// Copyright (C) 1998 Olivier Debon
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19///////////////////////////////////////////////////////////////
20#ifndef _MOVIE_H_
21#define _MOVIE_H_
22
23#include "swf.h"
24
25struct FlashMovie {
26 /* true if a button has been moved */
27 int buttons_updated;
28
29 /* current keyboard focus */
30 DisplayListEntry *cur_focus;
31
32 /* mouse state */
33 long mouse_active;
34 long mouse_x;
35 long mouse_y;
36 int button_pressed;
37
38 Button *lost_over;
39
40 /* a button can return to a given state after some time */
41 FlashEvent scheduledEvent;
42 struct timeval scheduledTime;
43
44 int refresh;
45
46 CInputScript *main;
47 long msPerFrame;
48 GraphicDevice*gd;
49 SoundMixer *sm;
50
51 void (*getUrl)(char *,char *, void *);
52 void *getUrlClientData;
53
54 void (*getSwf)(char *url, int level, void *clientData);
55 void *getSwfClientData;
56
57 void (*cursorOnOff)(int , void *);
58 void *cursorOnOffClientData;
59
60 FlashMovie();
61 ~FlashMovie();
62 int processMovie(GraphicDevice *gd, SoundMixer *sm);
63 int handleEvent(GraphicDevice *gd, SoundMixer *sm, FlashEvent *event);
64 void renderMovie();
65 void renderFocus();
66};
67
68#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 @@
1/////////////////////////////////////////////////////////////
2// Flash Plugin and Player
3// Copyright (C) 1998,1999 Olivier Debon
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19///////////////////////////////////////////////////////////////
20// Author : Olivier Debon <odebon@club-internet.fr>
21//
22
23#include "swf.h"
24
25#define NOTHING 0x0
26#define WAKEUP 0x1
27#define GOTO 0x2
28#define REFRESH 0x4
29
30#ifdef RCSID
31static char *rcsid = "$Id$";
32#endif
33
34#define PRINT 0
35
36int debug = 0;
37
38Program::Program(FlashMovie *movie, long n)
39{
40 long f;
41
42 this->movie = movie;
43
44 totalFrames = 0;
45
46 dl = new DisplayList(movie);
47 if (dl == NULL) return;
48 frames = new Frame[n];
49 if (frames == NULL) {
50 delete dl;
51 return;
52 }
53
54 nbFrames = 0;
55 totalFrames = n;
56 currentFrame = 0;
57 loadingFrame = 0;
58 movieWait = 1;
59 nextFrame = currentFrame;
60 for(f = 0; f < n; f++)
61 {
62 frames[f].controls = 0;
63 frames[f].label = NULL;
64 }
65
66 movieStatus = MoviePlay;
67 settings = 0;
68}
69
70Program::~Program()
71{
72 int i;
73 Control *ctrl, *ctrl1;
74
75 delete dl;
76
77 if (frames != NULL) {
78 for(i=0;i<nbFrames;i++) {
79 ctrl = frames[i].controls;
80 if (frames[i].label) free(frames[i].label);
81 while (ctrl != NULL) {
82 ctrl1 = ctrl->next;
83 ctrl->next = NULL;
84 delete ctrl;
85 ctrl = ctrl1;
86 }
87 }
88
89 delete[] frames;
90 }
91}
92
93void
94Program::validateLoadingFrame()
95{
96 nbFrames = loadingFrame;
97 loadingFrame++;
98 movieWait = 0;
99}
100
101 Frame*
102Program::getFrames()
103{
104 return frames;
105}
106
107long
108Program::getNbFrames()
109{
110 return nbFrames;
111}
112
113DisplayList *
114Program::getDisplayList()
115{
116 return dl;
117}
118
119long
120Program::getCurrentFrame()
121{
122 return currentFrame;
123}
124
125void
126Program::setCurrentFrame(long n)
127{
128 currentFrame = n;
129 nextFrame = n;
130 //refresh = 1;
131}
132
133void
134Program::gotoFrame(GraphicDevice *gd, long frame)
135{
136 long f;
137
138 //printf("GotoFrame %d (Current = %d)\n", frame, currentFrame);
139 dl->clearList();
140
141 for(f=0; f <= frame; f++) {
142 runFrame(gd, 0, f, 0);
143 }
144}
145
146long
147Program::runFrame(GraphicDevice *gd, SoundMixer *sm, long f, long action)
148{
149 Control *ctrl;
150 Character*character;
151 Matrix *matrix;
152 Cxform *cxform;
153 long status = NOTHING;
154 long update = 0;
155 char *name;
156
157#if PRINT&1
158 if (action) printf("Prog %x (dl=%x): Frame N° %d/%d\n", this, this->dl, f, nbFrames-1);
159#endif
160 movie->buttons_updated = 0;
161
162 for(ctrl = frames[f].controls; ctrl; ctrl = ctrl->next)
163 {
164 switch (ctrl->type)
165 {
166 case ctrlPlaceObject:
167 case ctrlPlaceObject2:
168 character = 0;
169 matrix = 0;
170 cxform = 0;
171 name = "";
172 if (ctrl->flags & placeHasCharacter) {
173 character = ctrl->character;
174 }
175 if (ctrl->flags & placeHasMatrix) {
176 matrix = &ctrl->matrix;
177 }
178 if (ctrl->flags & placeHasColorXform) {
179 cxform = &ctrl->cxform;
180 }
181 if (ctrl->flags & placeHasName) {
182 name = ctrl->name;
183 }
184 if (!ctrl->clipDepth) {// Ignore
185 dl->placeObject(gd,character, ctrl->depth, matrix, cxform, name);
186 update = 1;
187 }
188 break;
189 case ctrlRemoveObject:
190 character = ctrl->character;
191
192 if (!character) break;// Should not happen
193
194 dl->removeObject(gd, character, ctrl->depth);
195 if (action) {
196 character->reset();
197 update = 1;
198 }
199 break;
200 case ctrlRemoveObject2:
201 character = dl->removeObject(gd,NULL, ctrl->depth);
202 if (character && action) {
203 character->reset();
204 update = 1;
205 }
206 break;
207 // Actions
208 case ctrlDoAction:
209 if (action) {
210 status = doAction(gd, ctrl->actionRecords, sm);
211 }
212 break;
213 case ctrlStartSound:
214 if (action && sm) {
215 sm->startSound( (Sound *)ctrl->character );
216 }
217 break;
218 case ctrlStopSound:
219 if (action && sm) {
220 sm->stopSounds();
221 }
222 break;
223 case ctrlBackgroundColor:
224 if (action) {
225 if (gd->setBackgroundColor(ctrl->color)) {
226 dl->bbox.xmin = -32768;
227 dl->bbox.ymin = -32768;
228 dl->bbox.xmax = 32768;
229 dl->bbox.ymax = 32768;
230 }
231 }
232 break;
233 }
234 }
235 if (movie->buttons_updated) {
236 dl->updateButtons(movie);
237 }
238
239 if (status & GOTO) {
240 if (nextFrame < nbFrames) {
241 gotoFrame(gd,nextFrame);
242 if (nextFrame != f)
243 if (movieStatus == MoviePaused) runFrame(gd,sm,nextFrame);
244 update = 1;
245 }
246 }
247
248#if PRINT&1
249 if (action) printf("Frame N° %d ready\n", f);
250#endif
251 return update;
252}
253
254long
255Program::nestedMovie(GraphicDevice *gd, SoundMixer *sm, Matrix *mat, Cxform *cxform)
256{
257 if (movieStatus == MoviePlay) {
258 // Movie Beeing Played
259 advanceFrame();
260 if (currentFrame == 0) {
261 dl->clearList();
262 }
263 runFrame(gd, sm, currentFrame);
264 if (nbFrames == 1) {
265 pauseMovie();
266 }
267 }
268
269 return (movieStatus == MoviePlay);
270}
271
272long
273Program::processMovie(GraphicDevice *gd, SoundMixer *sm)
274{
275 int wakeUp = 0;
276
277#if PRINT&1
278 printf("Prog %x (dl=%x): Current = %d Next = %d Wait = %d Status = %d\n", this, this->dl, currentFrame, nextFrame, movieWait, movieStatus);
279#endif
280
281 if (movieStatus == MoviePlay && movieWait == 0) {
282 // Movie Beeing Played
283 advanceFrame();
284 if (currentFrame == 0) {
285 dl->clearList();
286 }
287 wakeUp |= runFrame(gd, sm, currentFrame);
288 wakeUp |= dl->updateSprites();
289 if (nextFrame == nbFrames) {
290 if (nbFrames != totalFrames) {
291 movieWait = 1;
292 } else if ((settings & PLAYER_LOOP) == 0) {
293 pauseMovie();
294 }
295 }
296 } else {
297 wakeUp |= dl->updateSprites();
298 }
299
300 if (wakeUp) {
301 render = 1;
302 }
303
304 return (wakeUp || movieStatus == MoviePlay);
305}
306
307/* timer (ms) -1 = delete timer */
308void setFlashTimer(struct timeval *tv, int time_ms)
309{
310 if (time_ms == -1) {
311 tv->tv_sec = -1;
312 } else {
313 gettimeofday(tv,0);
314
315 tv->tv_usec += time_ms*1000;
316 while (tv->tv_usec > 1000000) {
317 tv->tv_usec -= 1000000;
318 tv->tv_sec++;
319 }
320 }
321}
322
323int checkFlashTimer(struct timeval *tv)
324{
325 struct timeval now;
326
327 if (tv->tv_sec == -1) return 0;
328
329 gettimeofday(&now,0);
330 return (now.tv_sec > tv->tv_sec ||
331 (now.tv_sec == tv->tv_sec && now.tv_usec >= tv->tv_usec));
332}
333
334/* bbox */
335typedef struct {
336 long x1,y1,x2,y2;
337} ButtonBoundingBox;
338
339
340static void button_bbox_func(void *id, long y, long start, long end)
341{
342 ButtonBoundingBox *h = (ButtonBoundingBox *) id;
343
344 if (y < h->y1) h->y1 = y;
345 if (y > h->y2) h->y2 = y;
346 if (start < h->x1) h->x1 = start;
347 if (end > h->x2) h->x2 = end;
348}
349
350void computeBBox(FlashMovie *movie, Rect *rect, DisplayListEntry *e)
351{
352 ButtonBoundingBox bb;
353
354 bb.x1 = LONG_MAX;
355 bb.y1 = LONG_MAX;
356 bb.x2 = LONG_MIN;
357 bb.y2 = LONG_MIN;
358
359 e->character->getRegion(movie->gd,&e->renderMatrix,&bb,button_bbox_func);
360
361 rect->xmin = bb.x1 / FRAC;
362 rect->xmax = bb.x2 / FRAC;
363 rect->ymin = bb.y1;
364 rect->ymax = bb.y2;
365}
366
367void transform_coords(long *x_ptr,long *y_ptr, long cx, long cy, long dx, long dy)
368{
369 long x,y,x1,y1;
370 x = *x_ptr;
371 y = *y_ptr;
372
373 x -= cx;
374 y -= cy;
375
376 if (dx < 0) {
377 /* left */
378 x1 = - x;
379 y1 = y;
380 } else if (dy < 0) {
381 /* up */
382 y1 = x;
383 x1 = -y;
384 } else if (dy > 0) {
385 /* down */
386 y1 = x;
387 x1 = y;
388 } else {
389 /* right */
390 x1 = x;
391 y1 = y;
392 }
393
394 *x_ptr = x1;
395 *y_ptr = y1;
396}
397
398typedef struct {
399 FlashMovie *movie;
400 DisplayListEntry *emin,*cur_focus;
401 long dmin;
402 long w,cx,cy,dx,dy;
403} ButtonFocus;
404
405static int button_focus(void *opaque, Program *prg, DisplayListEntry *e)
406{
407 ButtonFocus *h=(ButtonFocus *)opaque;
408 Rect rect;
409 long d,x,y;
410
411 if (e != h->cur_focus) {
412 computeBBox(h->movie,&rect,e);
413 x = (rect.xmin + rect.xmax) / 2;
414 y = (rect.ymin + rect.ymax) / 2;
415
416 /* transform the coords so that the angular sector is directed to the right */
417 transform_coords(&x,&y,h->cx,h->cy,h->dx,h->dy);
418
419 /* inside it ? */
420 if ( x >= 0 &&
421 (y - x - h->w) <= 0 &&
422 (y + x + h->w) >= 0) {
423 d = x*x + y*y;
424
425 if (d < h->dmin) {
426 h->dmin = d;
427 h->emin = e;
428 }
429 }
430 }
431 return 0;
432}
433
434DisplayListEntry *moveFocus(FlashMovie *movie, long dx, long dy,
435 DisplayListEntry *cur_focus)
436{
437 Rect cur_rect;
438 ButtonFocus h;
439
440 h.movie = movie;
441 h.dx = dx;
442 h.dy = dy;
443
444 computeBBox(movie,&cur_rect,cur_focus);
445 /* center */
446 h.cx = (cur_rect.xmin + cur_rect.xmax) / 2;
447 h.cy = (cur_rect.ymin + cur_rect.ymax) / 2;
448
449 /* width/2 of the 45 degrees angular sector */
450 if (dy != 0) {
451 /* for vertical displacement, we have a larger width */
452 h.w = (cur_rect.xmax - cur_rect.xmin) / 2;
453 } else {
454 /* zero width for horizontal displacement */
455 h.w = 0;
456 }
457
458 /* now we select the nearest button in the angular sector */
459 h.dmin = LONG_MAX;
460 h.emin = NULL;
461 h.cur_focus = cur_focus;
462
463 exploreButtons(movie, &h, button_focus);
464
465 return h.emin;
466}
467
468static int button_newfocus(void *opaque, Program *prg, DisplayListEntry *e)
469{
470 * (DisplayListEntry **)opaque = e;
471 return 2;
472}
473
474static int button_nextfocus(void *opaque, Program *prg, DisplayListEntry *e)
475{
476 static int found = 0;
477 DisplayListEntry **focus;
478
479 focus = (DisplayListEntry **)opaque;
480 if (found) {
481 *focus = e;
482 found = 0;
483 return 2;
484 }
485 if (e == *focus) {
486 found = 1;
487 }
488 return 0;
489}
490
491
492/* XXX: should not be here (one level upper) */
493long
494Program::handleEvent(GraphicDevice *gd, SoundMixer *sm, FlashEvent *fe)
495{
496 ActionRecord*action;
497 Program *prog;
498 long status = 0;
499 DisplayListEntry *cur_focus, *new_focus;
500 long dx,dy;
501 int refresh;
502
503 refresh = 0;
504
505 switch(fe->type) {
506
507 case FeKeyRelease:
508 if (movie->mouse_active == 0) {
509
510 if (movie->cur_focus) {
511 movie->cur_focus->owner->updateBoundingBox(movie->cur_focus);
512 movie->cur_focus->renderState = stateOver;
513 movie->cur_focus->owner->updateBoundingBox(movie->cur_focus);
514 }
515 }
516 break;
517
518 case FeKeyPress:
519
520 movie->mouse_active = 0;
521
522 /* find the button which has the focus */
523 cur_focus = movie->cur_focus;
524
525 if (fe->key == FeKeyEnter) {
526 /* selection */
527 if (cur_focus) {
528 /* select the button */
529 cur_focus->owner->updateBoundingBox(cur_focus);
530 cur_focus->renderState = stateDown;
531 ((Button *)cur_focus->character)->updateButtonState(cur_focus);
532 cur_focus->owner->updateBoundingBox(cur_focus);
533
534 movie->scheduledEvent.type = FeKeyRelease;
535 movie->scheduledEvent.key = FeKeyEnter;
536
537 setFlashTimer(&movie->scheduledTime, 250); /* 250 ms down */
538 }
539 } else {
540 /* displacement */
541
542 if (cur_focus == NULL) {
543 /* no current focus : set one */
544 exploreButtons(movie, &cur_focus, button_newfocus);
545 if (cur_focus) {
546 cur_focus->renderState = stateOver;
547 ((Button *)cur_focus->character)->updateButtonState(cur_focus);
548 cur_focus->owner->updateBoundingBox(cur_focus);
549 }
550 movie->cur_focus = cur_focus;
551 } else {
552 /* move the focus (test) */
553 switch(fe->key) {
554 case FeKeyNext:
555 /* Next available */
556 cur_focus->owner->updateBoundingBox(cur_focus);
557 cur_focus->renderState = stateUp;
558 ((Button *)cur_focus->character)->updateButtonState(cur_focus);
559 cur_focus->owner->updateBoundingBox(cur_focus);
560 exploreButtons(movie, &cur_focus, button_nextfocus);
561 if (cur_focus) {
562 cur_focus->renderState = stateOver;
563 ((Button *)cur_focus->character)->updateButtonState(cur_focus);
564 cur_focus->owner->updateBoundingBox(cur_focus);
565 }
566 movie->cur_focus = cur_focus;
567 dx = 0;
568 dy = 0;
569 break;
570 case FeKeyUp:
571 dx = 0;
572 dy = -1;
573 break;
574 case FeKeyDown:
575 dx = 0;
576 dy = 1;
577 break;
578 case FeKeyLeft:
579 dx = -1;
580 dy = 0;
581 break;
582 case FeKeyRight:
583 dx = 1;
584 dy = 0;
585 break;
586 default:
587 /* should not happen */
588 dx = 0;
589 dy = 0;
590 break;
591 }
592
593 if (dx != 0 || dy != 0) {
594
595 new_focus = moveFocus(movie, dx, dy, cur_focus);
596 if (new_focus) {
597 cur_focus->owner->updateBoundingBox(cur_focus);
598 cur_focus->renderState = stateUp;
599 ((Button *)cur_focus->character)->updateButtonState(cur_focus);
600 cur_focus->owner->updateBoundingBox(cur_focus);
601
602 if (computeActions(movie, &prog, &action)) {
603 status |= prog->doAction(gd, action, sm);
604 }
605
606 new_focus->renderState = stateOver;
607 ((Button *)new_focus->character)->updateButtonState(new_focus);
608 movie->cur_focus = new_focus;
609 new_focus->owner->updateBoundingBox(new_focus);
610 } else {
611 return 0;
612 }
613 }
614 }
615 if (movie->cur_focus == NULL) return 0;
616 }
617 break;
618
619 case FeMouseMove:
620 movie->mouse_active = 1;
621 movie->mouse_x = fe->x * FRAC;
622 movie->mouse_y = fe->y * FRAC;
623 dl->updateButtons(movie);
624 break;
625
626 case FeButtonPress:
627 movie->mouse_active = 1;
628 movie->button_pressed = 1;
629 dl->updateButtons(movie);
630 break;
631
632 case FeButtonRelease:
633 movie->mouse_active = 1;
634 movie->button_pressed = 0;
635 dl->updateButtons(movie);
636 break;
637
638 default:
639 return 0;
640 }
641
642 if (computeActions(movie, &prog, &action)) {
643 status |= prog->doAction(gd, action, sm);
644 }
645
646 if (status & REFRESH) {
647 status |= WAKEUP;
648 refresh = 1;
649 }
650 if (status & GOTO) {
651 if (nextFrame < nbFrames) {
652 gotoFrame(gd, nextFrame);
653 if (movieStatus == MoviePaused) runFrame(gd,sm,nextFrame);
654 refresh = 1;
655 }
656 }
657
658 if (refresh) {
659 dl->updateSprites();
660 render = 1;
661 }
662 return (refresh || movieStatus == MoviePlay);
663}
664
665long
666Program::doAction(GraphicDevice *gd, ActionRecord *action, SoundMixer *sm)
667{
668 long status = NOTHING;
669 long f;
670 char *target = "";
671 long skip = 0;
672
673 while(action)
674 {
675 if (skip) skip--;
676 else
677 switch (action->action)
678 {
679 case ActionPlaySound:
680#if PRINT&2
681 printf("Prog %x : PlaySound\n", this);
682#endif
683 if (sm) {
684 sm->startSound(action->sound);
685 }
686 status |= WAKEUP;
687 break;
688 case ActionRefresh:
689#if PRINT&2
690 printf("Prog %x : Refresh\n", this);
691#endif
692 status |= REFRESH;
693 break;
694 case ActionGotoFrame:
695#if PRINT&2
696 printf("Prog %x : GotoFrame %d\n", this, action->frameIndex);
697#endif
698 if (target[0] == 0) {
699 if (action->frameIndex < nbFrames) {
700 currentFrame = action->frameIndex;
701 pauseMovie();
702 status |= WAKEUP|GOTO;
703 }
704 }
705 break;
706 case ActionGetURL:
707#if PRINT&2
708 printf("Prog %x : GetURL %s target = %s\n", this, action->url, action->target);
709#endif
710 {
711 int len,level;
712 len = strlen(action->target);
713
714 if (len > 6 && memcmp(action->target,"_level", 6) == 0) {
715 level = atoi(action->target + 6);
716 loadNewSwf(movie, action->url, level);
717 } else {
718 if (movie->getUrl) {
719 movie->getUrl(action->url, action->target, movie->getUrlClientData);
720 }
721 }
722 }
723 break;
724 case ActionNextFrame:
725 nextFrame = currentFrame+1;
726 movieStatus = MoviePlay;
727 status |= WAKEUP;
728 break;
729 case ActionPrevFrame:
730 nextFrame = currentFrame-1;
731 status |= WAKEUP|GOTO;
732 break;
733 case ActionPlay:
734#if PRINT&2
735 printf("Prog %x : Play\n", this);
736#endif
737 if (target[0] == 0) {
738 movieStatus = MoviePlay;
739 if ((status & GOTO) == 0) {
740 if (currentFrame == nextFrame) advanceFrame();
741 }
742 status |= WAKEUP;
743 }
744 break;
745 case ActionStop:
746#if PRINT&2
747 printf("Prog %x : Stop\n", this);
748#endif
749 if (target[0] == 0) {
750 movieStatus = MoviePaused;
751 nextFrame = currentFrame;
752 }
753 break;
754 case ActionToggleQuality:
755 break;
756 case ActionStopSounds:
757 if (sm) {
758 sm->stopSounds();
759 }
760 break;
761 case ActionWaitForFrame:
762 if (action->frameIndex >= nbFrames) {
763 skip = action->skipCount;
764 }
765 break;
766 case ActionSetTarget:
767#if PRINT&2
768 printf("Prog %x : SetTarget '%s'\n", this, action->target);
769#endif
770 target = action->target;
771 break;
772 case ActionGoToLabel:
773#if PRINT&2
774 printf("Prog %x : GotoFrame '%s'\n", this, action->frameLabel);
775#endif
776 f = searchFrame(gd, action->frameLabel, target);
777 if (f >= 0) {
778 currentFrame = f;
779 pauseMovie();
780 status |= WAKEUP|GOTO;
781 } else {
782 status |= REFRESH;
783 }
784 break;
785 }
786 action = action->next;
787 }
788 return status;
789}
790
791void
792Program::setCurrentFrameLabel(char *label)
793{
794 frames[loadingFrame].label = label;
795}
796
797void
798Program::rewindMovie()
799{
800 currentFrame = 0;
801 nextFrame = 0;
802}
803
804void
805Program::pauseMovie()
806{
807 movieStatus = MoviePaused;
808 nextFrame = currentFrame;
809}
810
811void
812Program::continueMovie()
813{
814 movieStatus = MoviePlay;
815}
816
817void
818Program::nextStepMovie()
819{
820 if (movieStatus == MoviePaused) {
821 advanceFrame();
822 }
823}
824
825void
826Program::advanceFrame()
827{
828 currentFrame = nextFrame;
829 nextFrame = currentFrame+1;
830 if (currentFrame == nbFrames) {
831 currentFrame = 0;
832 nextFrame = 0;
833 movieStatus = MoviePlay;
834 }
835}
836
837void
838Program::addControlInCurrentFrame(Control *ctrl)
839{
840 Control *c;
841
842 ctrl->next = 0;
843 if (frames[loadingFrame].controls == 0) {
844 frames[loadingFrame].controls = ctrl;
845 } else {
846 for(c = frames[loadingFrame].controls; c->next; c = c->next);
847 c->next = ctrl;
848 }
849}
850
851void
852Program::modifySettings(long flags)
853{
854 settings = flags;
855}
856
857long
858Program::searchFrame(GraphicDevice *gd, char *label, char *target)
859{
860 long f;
861 DisplayListEntry *e;
862 Program *prg;
863
864 // Current movie
865 if (target[0] == 0) {
866 for(f=0; f < nbFrames; f++)
867 {
868 if (frames[f].label && !strcmp(label,frames[f].label)) {
869 return f;
870 }
871 }
872 }
873
874 // Kludge !!!
875 for (e = dl->list; e; e = e->next) {
876 if (e->character->isSprite()) {
877 prg = ((Sprite *)e->character)->program;
878 f = prg->searchFrame(gd,label,"");
879 if (f >= 0 && f < prg->nbFrames) {
880 prg->dl->updateBoundingBox(e);
881 prg->gotoFrame(gd, f);
882 prg->nextFrame = f;
883 prg->dl->updateBoundingBox(e);
884 return -1;
885 }
886 }
887 }
888
889 return -1;
890}
891
892void loadNewSwf(FlashMovie *movie, char *url, int level)
893{
894 CInputScript *s,*prev,**l;
895
896 if (movie->getSwf == NULL) return;
897
898 for(s = movie->main, prev = 0; s != NULL; prev = s, s = s->next) {
899 if (s->level == level) {
900 // Mark movie to be deleted
901 s->level = -1;
902 break;
903 }
904 }
905
906 //printf("Unload movie @ %d\n", level);
907
908 if (*url == 0) return;// Just UnloadMovie
909
910 s = new CInputScript(level);
911 if (s == NULL) return;
912
913 /* insert it in the right order */
914 l = &movie->main;
915 while (*l != NULL && (*l)->level < level) l = &(*l)->next;
916 s->next = *l;
917 *l = s;
918
919 // Notify the external loader of a new movie to load
920 movie->getSwf(url, level, movie->getSwfClientData);
921}
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 @@
1/////////////////////////////////////////////////////////////
2// Flash Plugin and Player
3// Copyright (C) 1998 Olivier Debon
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19///////////////////////////////////////////////////////////////
20#ifndef _PROGRAM_H_
21#define _PROGRAM_H_
22
23enum ControlType {
24 ctrlPlaceObject,
25 ctrlPlaceObject2,
26 ctrlRemoveObject,
27 ctrlRemoveObject2,
28 ctrlDoAction,
29 ctrlStartSound,
30 ctrlStopSound,
31 ctrlBackgroundColor
32};
33
34enum PlaceFlags {
35 placeIsMove = 0x01,
36 placeHasCharacter= 0x02,
37 placeHasMatrix = 0x04,
38 placeHasColorXform= 0x08,
39 placeHasRatio = 0x10,
40 placeHasName = 0x20,
41 placeHasClip = 0x40
42};
43
44struct Control {
45 ControlTypetype;
46
47 // Place, Remove, Sound
48 Character*character;
49 long depth;
50
51 // Place 1&2
52 PlaceFlags flags;
53 Matrix matrix;
54 Cxform cxform;
55 long ratio;
56 long clipDepth;
57 char *name;
58
59 // BackgroundColor
60 Color color;
61
62 // DoAction
63 ActionRecord*actionRecords;
64
65 struct Control *next;
66
67
68 // Methods
69
70 void addActionRecord( ActionRecord *ar)
71 {
72 ar->next = 0;
73
74 if (actionRecords == 0) {
75 actionRecords = ar;
76 } else {
77 ActionRecord *current;
78
79 for(current = actionRecords; current->next; current = current->next);
80
81 current->next = ar;
82 }
83 };
84
85 Control()
86 {
87 actionRecords = 0;
88 cxform.aa = 1.0; cxform.ab = 0;
89 cxform.ra = 1.0; cxform.rb = 0;
90 cxform.ga = 1.0; cxform.gb = 0;
91 cxform.ba = 1.0; cxform.bb = 0;
92 ratio = 0;
93 clipDepth = 0;
94 name = 0;
95 };
96
97 ~Control()
98 {
99 ActionRecord*ar,*del;
100 for(ar = actionRecords; ar;)
101 {
102 del = ar;
103 ar = ar->next;
104 delete del;
105 }
106 if (name) {
107 free(name);
108 }
109 };
110};
111
112struct Frame {
113 char *label;
114 Control *controls;// Controls for this frame
115};
116
117enum MovieStatus {
118 MoviePaused,
119 MoviePlay
120};
121
122struct FlashMovie;
123
124struct Program {
125 DisplayList*dl;
126
127 Frame *frames;// Array
128 long nbFrames;// Number of valid frames
129 long currentFrame;
130 long loadingFrame;
131 long totalFrames;// Total expected number of frames
132 long nextFrame;
133 int movieWait;// If true freeze movie until next loaded frame
134 MovieStatus movieStatus;
135 Sound *currentSound;
136 long settings;
137 FlashMovie *movie;
138 long render;// True if needed to be rendered
139
140 Program(FlashMovie *movie,long n);
141 ~Program();
142
143 void rewindMovie();
144 void pauseMovie();
145 void continueMovie();
146 void nextStepMovie();
147 void gotoFrame(GraphicDevice *gd, long f);
148
149 long processMovie(GraphicDevice *, SoundMixer *);
150 long nestedMovie(GraphicDevice *, SoundMixer *, Matrix *, Cxform *);
151 long runFrame(GraphicDevice *, SoundMixer *, long f, long action=1);
152 long handleEvent(GraphicDevice *, SoundMixer *, FlashEvent *);
153 long doAction(GraphicDevice *gd, ActionRecord *action, SoundMixer *);
154 void setCurrentFrameLabel(char *label);
155 void advanceFrame();
156 void addControlInCurrentFrame(Control *ctrl);
157 void setGetUrlMethod( void (*)(char *, char *, void *), void *);
158 void modifySettings(long flags);
159 long searchFrame(GraphicDevice *gd, char *, char *);
160 void validateLoadingFrame();
161 long getCurrentFrame();
162 void setCurrentFrame(long);
163
164 Frame*getFrames();
165 long getNbFrames();
166
167 DisplayList *getDisplayList();
168
169#ifdef DUMP
170 void dump(BitStream *bs);
171 static void dumpActions(BitStream *bs, ActionRecord *actions);
172#endif
173};
174
175DisplayListEntry *findFocus(DisplayList *dl);
176void setFlashTimer(struct timeval *tv, int time_ms);
177int checkFlashTimer(struct timeval *tv);
178
179void loadNewSwf(FlashMovie *movie, char *url, int level);
180
181void computeBBox(FlashMovie *movie, Rect *rect, DisplayListEntry *e);
182
183long processMovie(FlashMovie *movie);
184
185#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 @@
1/////////////////////////////////////////////////////////////
2// Flash Plugin and Player
3// Copyright (C) 1998,1999 Olivier Debon
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19///////////////////////////////////////////////////////////////
20#ifndef _RECT_H_
21#define _RECT_H_
22
23struct Rect
24{
25 long xmin;
26 long xmax;
27 long ymin;
28 long ymax;
29
30 long getWidth() {
31 return xmax-xmin;
32 };
33
34 long getHeight() {
35 return ymax-ymin;
36 };
37
38 void print() {
39 printf("Xmin = %d Xmax = %d Ymin = %d Ymax = %d\n",
40 (int)xmin,(int)xmax,(int)ymin,(int)ymax);
41 };
42
43 void reset() {
44 xmin = LONG_MAX;
45 ymin = LONG_MAX;
46 xmax = LONG_MIN;
47 ymax = LONG_MIN;
48 };
49
50#ifdef DUMP
51 void dump(BitStream *bs);
52#endif
53};
54
55#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 @@
1#include "swf.h"
2
3////////////////////////////////////////////////////////////
4// This file is derived from the 'buggy' SWF parser provided
5// by Macromedia.
6//
7// Modifications : Olivier Debon <odebon@club-internet.fr>
8//
9
10#ifdef RCSID
11static char *rcsid = "$Id$";
12#endif
13
14#define printf(fmt,args...)
15
16//////////////////////////////////////////////////////////////////////
17// Inline input script object methods.
18//////////////////////////////////////////////////////////////////////
19
20//
21// Inlines to parse a Flash file.
22//
23inline U8 CInputScript::GetByte(void)
24{
25 return m_fileBuf[m_filePos++];
26}
27
28inline U16 CInputScript::GetWord(void)
29{
30 U8 * s = m_fileBuf + m_filePos;
31 m_filePos += 2;
32 return (U16) s[0] | ((U16) s[1] << 8);
33}
34
35inline U32 CInputScript::GetDWord(void)
36{
37 U8 * s = m_fileBuf + m_filePos;
38 m_filePos += 4;
39 return (U32) s[0] | ((U32) s[1] << 8) | ((U32) s[2] << 16) | ((U32) s [3] << 24);
40}
41
42
43
44
45//////////////////////////////////////////////////////////////////////
46// Input script object methods.
47//////////////////////////////////////////////////////////////////////
48
49CInputScript::CInputScript(int level)
50// Class constructor.
51{
52 this->level = level;
53
54 // Initialize the input pointer.
55 m_fileBuf = NULL;
56
57 // Initialize the file information.
58 m_filePos = 0;
59 m_fileSize = 0;
60 m_fileVersion = 0;
61
62 // Initialize the bit position and buffer.
63 m_bitPos = 0;
64 m_bitBuf = 0;
65
66 // Initialize the output file.
67 m_outputFile = NULL;
68
69 // Set to true if we wish to dump all contents long form
70 m_dumpAll = false;
71
72 // if set to true will dump image guts (i.e. jpeg, zlib, etc. data)
73 m_dumpGuts = false;
74
75 needHeader = 1;
76 program = 0;
77
78 outOfMemory = 0;
79
80 next = NULL;
81
82 return;
83}
84
85
86CInputScript::~CInputScript(void)
87// Class destructor.
88{
89 // Free the buffer if it is there.
90 if (m_fileBuf)
91 {
92 delete program;
93 m_fileBuf = NULL;
94 m_fileSize = 0;
95 }
96}
97
98
99U16 CInputScript::GetTag(void)
100{
101 // Save the start of the tag.
102 m_tagStart = m_filePos;
103
104 if (m_actualSize-m_filePos < 2) return notEnoughData;
105
106 // Get the combined code and length of the tag.
107 U16 code = GetWord();
108
109 // The length is encoded in the tag.
110 U32 len = code & 0x3f;
111
112 // Remove the length from the code.
113 code = code >> 6;
114
115 // Determine if another long word must be read to get the length.
116 if (len == 0x3f) {
117 if (m_actualSize-m_filePos < 4) return notEnoughData;
118 len = (U32) GetDWord();
119 }
120
121 // Determine the end position of the tag.
122 m_tagEnd = m_filePos + (U32) len;
123 m_tagLen = (U32) len;
124
125 return code;
126}
127
128
129void CInputScript::GetRect (Rect * r)
130{
131 InitBits();
132 int nBits = (int) GetBits(5);
133 r->xmin = GetSBits(nBits);
134 r->xmax = GetSBits(nBits);
135 r->ymin = GetSBits(nBits);
136 r->ymax = GetSBits(nBits);
137}
138
139void CInputScript::GetMatrix(Matrix* mat)
140{
141 InitBits();
142
143 // Scale terms
144 if (GetBits(1))
145 {
146 int nBits = (int) GetBits(5);
147 mat->a = (float)(GetSBits(nBits))/(float)0x10000;
148 mat->d = (float)(GetSBits(nBits))/(float)0x10000;
149 }
150 else
151 {
152 mat->a = mat->d = 1.0;
153 }
154
155 // Rotate/skew terms
156 if (GetBits(1))
157 {
158 int nBits = (int)GetBits(5);
159 mat->c = (float)(GetSBits(nBits))/(float)0x10000;
160 mat->b = (float)(GetSBits(nBits))/(float)0x10000;
161 }
162 else
163 {
164 mat->b = mat->c = 0.0;
165 }
166
167 // Translate terms
168 int nBits = (int) GetBits(5);
169 mat->tx = GetSBits(nBits);
170 mat->ty = GetSBits(nBits);
171}
172
173
174void CInputScript::GetCxform(Cxform* cx, BOOL hasAlpha)
175{
176 int flags;
177 int nBits;
178 float aa; long ab;
179 float ra; long rb;
180 float ga; long gb;
181 float ba; long bb;
182
183 InitBits();
184
185 flags = (int) GetBits(2);
186 nBits = (int) GetBits(4);
187 aa = 1.0; ab = 0;
188 if (flags & 1)
189 {
190 ra = (float) GetSBits(nBits)/256.0;
191 ga = (float) GetSBits(nBits)/256.0;
192 ba = (float) GetSBits(nBits)/256.0;
193 if (hasAlpha) aa = (float) GetSBits(nBits)/256.0;
194 }
195 else
196 {
197 ra = ga = ba = 1.0;
198 }
199 if (flags & 2)
200 {
201 rb = (S32) GetSBits(nBits);
202 gb = (S32) GetSBits(nBits);
203 bb = (S32) GetSBits(nBits);
204 if (hasAlpha) ab = (S32) GetSBits(nBits);
205 }
206 else
207 {
208 rb = gb = bb = 0;
209 }
210 if (cx) {
211 cx->aa = aa;
212 cx->ab = ab;
213 cx->ra = ra;
214 cx->rb = rb;
215 cx->ga = ga;
216 cx->gb = gb;
217 cx->ba = ba;
218 cx->bb = bb;
219 }
220}
221
222
223/* XXX: should allocate string */
224char *CInputScript::GetString(void)
225{
226 // Point to the string.
227 char *str = (char *) &m_fileBuf[m_filePos];
228
229 // Skip over the string.
230 while (GetByte());
231
232 return str;
233}
234
235void CInputScript::InitBits(void)
236{
237 // Reset the bit position and buffer.
238 m_bitPos = 0;
239 m_bitBuf = 0;
240}
241
242
243S32 CInputScript::GetSBits (S32 n)
244// Get n bits from the string with sign extension.
245{
246 // Get the number as an unsigned value.
247 S32 v = (S32) GetBits(n);
248
249 // Is the number negative?
250 if (v & (1L << (n - 1)))
251 {
252 // Yes. Extend the sign.
253 v |= -1L << n;
254 }
255
256 return v;
257}
258
259
260U32 CInputScript::GetBits (S32 n)
261// Get n bits from the stream.
262{
263 U32 v = 0;
264
265 for (;;)
266 {
267 S32 s = n - m_bitPos;
268 if (s > 0)
269 {
270 // Consume the entire buffer
271 v |= m_bitBuf << s;
272 n -= m_bitPos;
273
274 // Get the next buffer
275 m_bitBuf = GetByte();
276 m_bitPos = 8;
277 }
278 else
279 {
280 // Consume a portion of the buffer
281 v |= m_bitBuf >> -s;
282 m_bitPos -= n;
283 m_bitBuf &= 0xff >> (8 - m_bitPos);// mask off the consumed bits
284 return v;
285 }
286 }
287}
288
289void CInputScript::ParseFreeCharacter()
290{
291 U32 tagid = (U32) GetWord();
292
293 tagid = tagid;
294
295 printf("tagFreeCharacter \ttagid %-5u\n", tagid);
296}
297
298
299void CInputScript::ParsePlaceObject()
300{
301 Control *ctrl;
302
303 ctrl = new Control;
304 if (ctrl == NULL) {
305 outOfMemory = 1;
306 return;
307 }
308 ctrl->type = ctrlPlaceObject;
309 ctrl->flags = (PlaceFlags)(placeHasMatrix | placeHasCharacter);
310
311 ctrl->character = getCharacter(GetWord());
312 ctrl->depth = GetWord();
313
314 GetMatrix(&(ctrl->matrix));
315
316 if ( m_filePos < m_tagEnd )
317 {
318 ctrl->flags = (PlaceFlags)(ctrl->flags | placeHasColorXform);
319
320 GetCxform(&ctrl->cxform, false);
321 }
322
323 program->addControlInCurrentFrame(ctrl);
324}
325
326
327void CInputScript::ParsePlaceObject2()
328{
329 Control *ctrl;
330
331 ctrl = new Control;
332 if (ctrl == NULL) {
333 outOfMemory = 1;
334 return;
335 }
336 ctrl->type = ctrlPlaceObject2;
337
338 ctrl->flags = (PlaceFlags)GetByte();
339 ctrl->depth = GetWord();
340
341 // Get the tag if specified.
342 if (ctrl->flags & placeHasCharacter)
343 {
344 ctrl->character = getCharacter(GetWord());
345 }
346
347 // Get the matrix if specified.
348 if (ctrl->flags & placeHasMatrix)
349 {
350 GetMatrix(&(ctrl->matrix));
351 }
352
353 // Get the color transform if specified.
354 if (ctrl->flags & placeHasColorXform)
355 {
356 GetCxform(&ctrl->cxform, true);
357 }
358
359 // Get the ratio if specified.
360 if (ctrl->flags & placeHasRatio)
361 {
362 ctrl->ratio = GetWord();
363 }
364
365 // Get the ratio if specified.
366 if (ctrl->flags & placeHasName)
367 {
368 ctrl->name = strdup(GetString());
369 }
370
371 // Get the clipdepth if specified.
372 if (ctrl->flags & placeHasClip)
373 {
374 ctrl->clipDepth = GetWord();
375 }
376
377 program->addControlInCurrentFrame(ctrl);
378}
379
380
381void CInputScript::ParseRemoveObject()
382{
383 Control *ctrl;
384
385 ctrl = new Control;
386 if (ctrl == NULL) {
387 outOfMemory = 1;
388 return;
389 }
390 ctrl->type = ctrlRemoveObject;
391 ctrl->character = getCharacter(GetWord());
392 ctrl->depth = GetWord();
393
394 program->addControlInCurrentFrame(ctrl);
395}
396
397
398void CInputScript::ParseRemoveObject2()
399{
400 Control *ctrl;
401
402 ctrl = new Control;
403 if (ctrl == NULL) {
404 outOfMemory = 1;
405 return;
406 }
407 ctrl->type = ctrlRemoveObject2;
408 ctrl->depth = GetWord();
409
410 program->addControlInCurrentFrame(ctrl);
411}
412
413
414void CInputScript::ParseSetBackgroundColor()
415{
416 Control *ctrl;
417
418 ctrl = new Control;
419 if (ctrl == NULL) {
420 outOfMemory = 1;
421 return;
422 }
423 ctrl->type = ctrlBackgroundColor;
424 ctrl->color.red = GetByte();
425 ctrl->color.green = GetByte();
426 ctrl->color.blue = GetByte();
427
428 program->addControlInCurrentFrame(ctrl);
429}
430
431
432void CInputScript::ParseDoAction()
433{
434 Control *ctrl;
435 ActionRecord *ar;
436
437 ctrl = new Control;
438 if (ctrl == NULL) {
439 outOfMemory = 1;
440 return;
441 }
442 ctrl->type = ctrlDoAction;
443
444 do {
445 ar = ParseActionRecord();
446 if (ar) {
447 ctrl->addActionRecord( ar );
448 }
449 if (outOfMemory) {
450 return;
451 }
452 } while (ar);
453
454 program->addControlInCurrentFrame(ctrl);
455
456}
457
458
459void CInputScript::ParseStartSound()
460{
461 Control *ctrl;
462
463 ctrl = new Control;
464 if (ctrl == NULL) {
465 outOfMemory = 1;
466 return;
467 }
468 ctrl->character = getCharacter(GetWord());
469 ctrl->type = ctrlStartSound;
470
471 program->addControlInCurrentFrame(ctrl);
472
473 if (!m_dumpAll)
474 return;
475
476 U32 code = GetByte();
477
478 printf("code %-3u", code);
479
480 if ( code & soundHasInPoint )
481 printf(" inpoint %u ", GetDWord());
482 if ( code & soundHasOutPoint )
483 printf(" oupoint %u", GetDWord());
484 if ( code & soundHasLoops )
485 printf(" loops %u", GetWord());
486
487 printf("\n");
488 if ( code & soundHasEnvelope )
489 {
490 int points = GetByte();
491
492 for ( int i = 0; i < points; i++ )
493 {
494 printf("\n");
495 printf("mark44 %u", GetDWord());
496 printf(" left chanel %u", GetWord());
497 printf(" right chanel %u", GetWord());
498 printf("\n");
499 }
500 }
501}
502
503
504void CInputScript::ParseStopSound()
505{
506 Control *ctrl;
507
508 ctrl = new Control;
509 if (ctrl == NULL) {
510 outOfMemory = 1;
511 return;
512 }
513 ctrl->type = ctrlStopSound;
514
515 program->addControlInCurrentFrame(ctrl);
516}
517
518
519void CInputScript::ParseShapeData(int getAlpha, int getStyles)
520{
521 int shapeRecord = 0;
522
523 if (getStyles) {
524 // ShapeWithStyle
525 ParseFillStyle(getAlpha);
526 ParseLineStyle(getAlpha);
527 }
528
529 InitBits();
530 m_nFillBits = (U16) GetBits(4);
531 m_nLineBits = (U16) GetBits(4);
532
533 do {
534 shapeRecord = ParseShapeRecord(getAlpha);
535 } while (shapeRecord);
536}
537
538int
539CInputScript::ParseShapeRecord(long getAlpha)
540{
541 // Determine if this is an edge.
542 BOOL isEdge = (BOOL) GetBits(1);
543
544 if (!isEdge)
545 {
546 // Handle a state change
547 U16 flags = (U16) GetBits(5);
548
549 // Are we at the end?
550 if (flags == 0)
551 {
552 // End of shape
553 return 0;
554 }
555
556 // Process a move to.
557 if (flags & flagsMoveTo)
558 {
559 U16 nBits = (U16) GetBits(5);
560 GetSBits(nBits);
561 GetSBits(nBits);
562 }
563
564 // Get new fill info.
565 if (flags & flagsFill0)
566 {
567 GetBits(m_nFillBits);
568 }
569 if (flags & flagsFill1)
570 {
571 GetBits(m_nFillBits);
572 }
573
574 // Get new line info
575 if (flags & flagsLine)
576 {
577 GetBits(m_nLineBits);
578 }
579
580 // Check to get a new set of styles for a new shape layer.
581 if (flags & flagsNewStyles)
582 {
583 // Parse the style.
584 ParseFillStyle(getAlpha);
585 ParseLineStyle(getAlpha);
586
587 InitBits();// Bug !
588
589 // Reset.
590 m_nFillBits = (U16) GetBits(4);
591 m_nLineBits = (U16) GetBits(4);
592 }
593
594 return flags & flagsEndShape ? 0 : 1;
595 }
596 else
597 {
598 if (GetBits(1))
599 {
600 // Handle a line
601 U16 nBits = (U16) GetBits(4) + 2;// nBits is biased by 2
602
603 // Save the deltas
604 if (GetBits(1))
605 {
606 // Handle a general line.
607 GetSBits(nBits);
608 GetSBits(nBits);
609 }
610 else
611 {
612 // Handle a vert or horiz line.
613 GetBits(1);
614 GetSBits(nBits);
615 }
616 }
617 else
618 {
619 // Handle a curve
620 U16 nBits = (U16) GetBits(4) + 2;// nBits is biased by 2
621
622 // Get the control
623 GetSBits(nBits);
624 GetSBits(nBits);
625
626 // Get the anchor
627 GetSBits(nBits);
628 GetSBits(nBits);
629 }
630
631 return 1;
632 }
633}
634
635
636void CInputScript::ParseFillStyle(long getAlpha)
637 //
638{
639 U16 i = 0;
640 FillType type;
641 Matrix matrix;
642
643 // Get the number of fills.
644 U16 nFills = GetByte();
645
646 // Do we have a larger number?
647 if (nFills == 255)
648 {
649 // Get the larger number.
650 nFills = GetWord();
651 }
652
653 // Get each of the fill style.
654 for (i = 0; i < nFills; i++)
655 {
656 U16 fillStyle = GetByte();
657
658 type = (FillType) fillStyle;
659
660 printf("fillstyle: type=%d\n",defs[i].type);
661 if (fillStyle & 0x10)
662 {
663 U16 nbGradients;
664
665 type = (FillType) (fillStyle & 0x12);
666
667 // Get the gradient matrix.
668 GetMatrix(&matrix);
669
670 // Get the number of colors.
671 nbGradients = GetByte();
672
673 // Get each of the colors.
674 for (U16 j = 0; j < nbGradients; j++)
675 {
676 GetByte();
677 GetByte();
678 GetByte();
679 GetByte();
680 if (getAlpha) {
681 GetByte();
682 }
683 }
684 }
685 else if (fillStyle & 0x40)
686 {
687 type = (FillType) (fillStyle & 0x41);
688
689 // Get the bitmapId
690 GetWord();
691
692 // Get the bitmap matrix.
693 GetMatrix(&matrix);
694 }
695 else
696 {
697 type = (FillType) 0;
698
699 // A solid color
700 GetByte();
701 GetByte();
702 GetByte();
703 if (getAlpha) {
704 GetByte();
705 }
706
707 printf("fillstyle: %x %x %x %x\n",
708 defs[i].color.red,
709 defs[i].color.green,
710 defs[i].color.blue,
711 defs[i].color.alpha);
712 }
713 }
714}
715
716void CInputScript::ParseLineStyle(long getAlpha)
717{
718 long i;
719
720 // Get the number of lines.
721 U16 nLines = GetByte();
722
723 // Do we have a larger number?
724 if (nLines == 255)
725 {
726 // Get the larger number.
727 nLines = GetWord();
728 }
729
730 // Get each of the line styles.
731 for (i = 0; i < nLines; i++)
732 {
733 GetWord();
734 GetByte();
735 GetByte();
736 GetByte();
737 if (getAlpha) {
738 GetByte();
739 }
740 }
741}
742
743
744void CInputScript::ParseDefineShape(int level)
745{
746 Shape *shape;
747 Rect rect;
748 U32 tagid;
749
750 tagid = (U32) GetWord();
751 shape = new Shape(tagid,level);
752 if (shape == NULL) {
753 outOfMemory = 1;
754 return;
755 }
756 shape->dict = this;
757
758 // Get the frame information.
759 GetRect(&rect);
760
761 shape->setBoundingBox(rect);
762
763 shape->file_ptr = (unsigned char*)malloc(m_tagEnd-m_filePos);
764 if (shape->file_ptr == NULL) {
765 outOfMemory = 1;
766 delete shape;
767 return;
768 }
769 memcpy((void*)shape->file_ptr,(void*)&m_fileBuf[m_filePos], m_tagEnd-m_filePos);
770
771 shape->getStyles = 1;
772 shape->getAlpha = (level == 3);
773
774 ParseShapeData(level == 3, 1);
775
776 addCharacter(shape);
777}
778
779void CInputScript::S_DumpImageGuts()
780{
781#if 0
782 U32 lfCount = 0;
783 printf("----- dumping image details -----");
784 while (m_filePos < m_tagEnd)
785 {
786 if ((lfCount % 16) == 0)
787 {
788 fprintf(stdout, "\n");
789 }
790 lfCount += 1;
791 fprintf(stdout, "%02x ", GetByte());
792 }
793 fprintf(stdout, "\n");
794#endif
795}
796
797void CInputScript::ParseDefineBits()
798{
799 Bitmap *bitmap;
800 U32 tagid = (U32) GetWord();
801 int status;
802
803 bitmap = new Bitmap(tagid,1);
804 if (bitmap == NULL) {
805 outOfMemory = 1;
806 return;
807 }
808
809 status = bitmap->buildFromJpegAbbreviatedData(&m_fileBuf[m_filePos]);
810
811 if (status < 0) {
812 fprintf(stderr,"Unable to read JPEG data\n");
813 delete bitmap;
814 return;
815 }
816
817 addCharacter(bitmap);
818}
819
820
821void CInputScript::ParseDefineBitsJPEG2()
822{
823 Bitmap *bitmap;
824 U32 tagid = (U32) GetWord();
825 int status;
826
827 bitmap = new Bitmap(tagid,2);
828 if (bitmap == NULL) {
829 outOfMemory = 1;
830 return;
831 }
832
833 status = bitmap->buildFromJpegInterchangeData(&m_fileBuf[m_filePos], 0, 0);
834
835 if (status < 0) {
836 fprintf(stderr,"Unable to read JPEG data\n");
837 delete bitmap;
838 return;
839 }
840
841 addCharacter(bitmap);
842}
843
844void CInputScript::ParseDefineBitsJPEG3()
845{
846 Bitmap *bitmap;
847 U32 tagid = (U32) GetWord();
848 int status;
849 long offset;
850
851 printf("tagDefineBitsJPEG3 \ttagid %-5u\n", tagid);
852
853 bitmap = new Bitmap(tagid,3);
854 if (bitmap == NULL) {
855 outOfMemory = 1;
856 return;
857 }
858
859 offset = GetDWord();// Not in the specs !!!!
860
861 status = bitmap->buildFromJpegInterchangeData(&m_fileBuf[m_filePos], 1, offset);
862 if (status < 0) {
863 fprintf(stderr,"Unable to read JPEG data\n");
864 delete bitmap;
865 return;
866 }
867
868 addCharacter(bitmap);
869}
870
871
872void CInputScript::ParseDefineBitsLossless(int level)
873{
874 Bitmap *bitmap;
875 U32 tagid = (U32) GetWord();
876 int status;
877 int tableSize;
878
879 bitmap = new Bitmap(tagid,0);
880 if (bitmap == NULL) {
881 outOfMemory = 1;
882 return;
883 }
884
885 int format = GetByte();
886 int width = GetWord();
887 int height = GetWord();
888
889 tableSize = 0;
890
891 if (format == 3) {
892 tableSize = GetByte();
893 }
894
895 status = bitmap->buildFromZlibData(&m_fileBuf[m_filePos], width, height, format, tableSize, level == 2);
896
897 if (status < 0) {
898 fprintf(stderr,"Unable to read ZLIB data\n");
899 delete bitmap;
900 return;
901 }
902
903 addCharacter(bitmap);
904}
905
906void CInputScript::ParseJPEGTables()
907{
908 Bitmap::readJpegTables(&m_fileBuf[m_filePos]);
909}
910
911
912ButtonRecord * CInputScript::ParseButtonRecord(long getCxform)
913{
914 U16 state;
915 ButtonRecord *br;
916 long tagid;
917 Matrix matrix;
918 long layer;
919 Cxform *cxform;
920
921 state = (U16) GetByte();
922
923 if (state == 0) return 0;
924
925 br = new ButtonRecord;
926 if (br == NULL) {
927 outOfMemory = 1;
928 return 0;
929 }
930
931 tagid = GetWord();
932 layer = GetWord();
933 GetMatrix(&matrix);
934
935 if (br) {
936 br->state = (ButtonState) state;
937 br->character = getCharacter(tagid);
938 br->layer = layer;
939 br->cxform = 0;
940 br->buttonMatrix = matrix;
941 }
942
943 if (getCxform) {
944 cxform = new Cxform;
945 GetCxform(cxform, true);
946 if (br) {
947 br->cxform = cxform;
948 if (cxform == NULL) {
949 outOfMemory = 1;
950 }
951 }
952 }
953
954 return br;
955}
956
957ActionRecord * CInputScript::ParseActionRecord()
958{
959 U8 action;
960 U16 length = 0;
961 char *url, *target, *label;
962 long frameIndex, skipCount;
963 ActionRecord *ar;
964
965 action = GetByte();
966 if (action == 0) return 0;
967
968 ar = new ActionRecord;
969 if (ar == NULL) {
970 outOfMemory = 1;
971 return 0;
972 }
973
974 ar->action = (Action)action;
975
976 if (action & 0x80) {
977 length = GetWord();
978 }
979
980 switch (action) {
981 case ActionGotoFrame:
982 frameIndex = GetWord();
983 if (ar) {
984 ar->frameIndex = frameIndex;
985 }
986 break;
987 case ActionGetURL:
988 url = GetString();
989 target = GetString();
990 if (ar) {
991 ar->url = strdup(url);
992 ar->target = strdup(target);
993 }
994 break;
995 case ActionWaitForFrame:
996 frameIndex = GetWord();
997 skipCount = GetByte();
998 if (ar) {
999 ar->frameIndex = frameIndex;
1000 ar->skipCount = skipCount;
1001 }
1002 break;
1003 case ActionSetTarget:
1004 target = strdup(GetString());
1005 if (ar) {
1006 ar->target = target;
1007 }
1008 break;
1009 case ActionGoToLabel:
1010 label = GetString();
1011 if (ar) {
1012 ar->frameLabel = strdup(label);
1013 }
1014 break;
1015 default:
1016 while (length--) {
1017 GetByte();
1018 }
1019 break;
1020 }
1021
1022 return ar;
1023}
1024
1025void CInputScript::ParseDefineButton()
1026{
1027 Button *button;
1028 ButtonRecord*buttonRecord;
1029 ActionRecord*actionRecord;
1030
1031 U32 tagid = (U32) GetWord();
1032
1033 button = new Button(tagid);
1034 if (button == NULL) {
1035 outOfMemory = 1;
1036 return;
1037 }
1038
1039 do {
1040 buttonRecord = ParseButtonRecord();
1041 if (buttonRecord) {
1042 button->addButtonRecord( buttonRecord );
1043 }
1044 if (outOfMemory) {
1045 return;
1046 }
1047 } while (buttonRecord);
1048
1049 do {
1050 actionRecord = ParseActionRecord();
1051 if (actionRecord) {
1052 button->addActionRecord( actionRecord );
1053 }
1054 if (outOfMemory) {
1055 return;
1056 }
1057 } while (actionRecord);
1058
1059 addCharacter(button);
1060}
1061
1062
1063void CInputScript::ParseDefineButton2()
1064{
1065 Button *button;
1066 ButtonRecord*buttonRecord;
1067 ActionRecord*actionRecord;
1068 U16 transition;
1069 U16 offset;
1070 U8 menu;
1071
1072 U32 tagid = (U32) GetWord();
1073
1074 button = new Button(tagid);
1075
1076 if (button == NULL) {
1077 outOfMemory = 1;
1078 return;
1079 }
1080
1081 menu = GetByte();
1082
1083 offset = GetWord();
1084
1085 do {
1086 buttonRecord = ParseButtonRecord(true);
1087 if (buttonRecord) {
1088 button->addButtonRecord( buttonRecord );
1089 }
1090 if (outOfMemory) {
1091 return;
1092 }
1093 } while (buttonRecord);
1094
1095 while (offset) {
1096 offset = GetWord();
1097
1098 transition = GetWord();
1099
1100 do {
1101 actionRecord = ParseActionRecord();
1102 if (actionRecord) {
1103 button->addActionRecord( actionRecord );
1104 }
1105 if (outOfMemory) {
1106 return;
1107 }
1108 } while (actionRecord);
1109
1110 button->addCondition( transition );
1111 }
1112
1113 addCharacter(button);
1114}
1115
1116
1117void CInputScript::ParseDefineFont()
1118{
1119 SwfFont*font = 0;
1120 U32 tagid = (U32) GetWord();
1121 long start;
1122 long nb,n;
1123 long offset;
1124 long*offsetTable = 0;
1125 Shape*shapes = 0;
1126
1127 font = new SwfFont(tagid);
1128 if (font == NULL) {
1129 outOfMemory = 1;
1130 return;
1131 }
1132 start = m_filePos;
1133
1134 offset = GetWord();
1135 nb = offset/2;
1136 offsetTable = new long[nb];
1137 if (offsetTable == NULL) {
1138 goto memory_error;
1139 }
1140 offsetTable[0] = offset;
1141
1142 for(n=1; n<nb; n++)
1143 {
1144 offsetTable[n] = GetWord();
1145 }
1146
1147 shapes = new Shape[nb];
1148 if (shapes == NULL) {
1149 goto memory_error;
1150 }
1151
1152 for(n=0; n<nb; n++)
1153 {
1154 long here;
1155
1156 m_filePos = offsetTable[n]+start;
1157
1158 here = m_filePos;
1159 ParseShapeData(0, 0);
1160
1161 // Keep data for later parsing
1162 shapes[n].file_ptr = (unsigned char*)malloc(m_filePos-here);
1163 if (shapes[n].file_ptr == NULL) {
1164 goto memory_error;
1165 }
1166 memcpy((void*)shapes[n].file_ptr,(void*)&m_fileBuf[here],m_filePos-here);
1167 }
1168
1169 font->setFontShapeTable(shapes,nb);
1170
1171 delete[] offsetTable;
1172
1173 addCharacter(font);
1174 return;
1175
1176memory_error:
1177 outOfMemory = 1;
1178 if (offsetTable) delete offsetTable;
1179 if (font) delete font;
1180 if (shapes) delete[] shapes;
1181}
1182
1183
1184void CInputScript::ParseDefineMorphShape()
1185{
1186 U32 tagid = (U32) GetWord();
1187
1188 tagid = tagid;
1189 printf("tagDefineMorphShape \ttagid %-5u\n", tagid);
1190}
1191
1192void CInputScript::ParseDefineFontInfo()
1193{
1194 SwfFont*font;
1195 U32 tagid = (U32) GetWord();
1196 long nameLen;
1197 char*name;
1198 long n,nb;
1199 FontFlags flags;
1200 long*lut;
1201
1202 font = (SwfFont *)getCharacter(tagid);
1203
1204 if (font == NULL) {
1205 outOfMemory = 1;
1206 return;
1207 }
1208
1209 nameLen = GetByte();
1210 name = new char[nameLen+1];
1211 if (name == NULL) {
1212 outOfMemory = 1;
1213 return;
1214 }
1215 for(n=0; n < nameLen; n++)
1216 {
1217 name[n] = GetByte();
1218 }
1219 name[n]=0;
1220
1221 font->setFontName(name);
1222
1223 delete name;
1224
1225 flags = (FontFlags)GetByte();
1226
1227 font->setFontFlags(flags);
1228
1229 nb = font->getNbGlyphs();
1230
1231 lut = new long[nb];
1232 if (lut == NULL) {
1233 outOfMemory = 1;
1234 delete font;
1235 return;
1236 }
1237
1238 for(n=0; n < nb; n++)
1239 {
1240 if (flags & fontWideCodes) {
1241 lut[n] = GetWord();
1242 } else {
1243 lut[n] = GetByte();
1244 }
1245 }
1246
1247 font->setFontLookUpTable(lut);
1248}
1249
1250
1251
1252
1253
1254void CInputScript::ParseDefineFont2()
1255{
1256 int n;
1257 U32 tagid = (U32) GetWord();
1258 FontFlags flags;
1259 char *name;
1260 long nameLen;
1261 long fontGlyphCount;
1262 long *offsetTable = NULL;
1263 Shape *shapes = NULL;
1264 long start;
1265 SwfFont *font;
1266 long *lut = NULL;
1267
1268 font = new SwfFont(tagid);
1269 if (font == NULL) {
1270 goto memory_error;
1271 }
1272
1273 flags = (FontFlags)GetWord();
1274
1275 font->setFontFlags(flags);
1276
1277 nameLen = GetByte();
1278 name = new char[nameLen+1];
1279 if (name == NULL) {
1280 goto memory_error;
1281 }
1282 for(n=0; n < nameLen; n++)
1283 {
1284 name[n] = GetByte();
1285 }
1286 name[n]=0;
1287
1288 font->setFontName(name);
1289
1290 delete name;
1291
1292 fontGlyphCount = GetWord();
1293
1294 start = m_filePos;
1295
1296 offsetTable = new long[fontGlyphCount];
1297 if (offsetTable == NULL) {
1298 goto memory_error;
1299 }
1300 for (n=0; n<fontGlyphCount; n++) {
1301 if (flags & 8) {
1302 offsetTable[n] = GetDWord();
1303 } else {
1304 offsetTable[n] = GetWord();
1305 }
1306 }
1307
1308 shapes = new Shape[fontGlyphCount];
1309 if (shapes == NULL) {
1310 goto memory_error;
1311 }
1312
1313 for (n=0; n<fontGlyphCount; n++) {
1314 long here;
1315
1316 m_filePos = offsetTable[n]+start;
1317
1318 here = m_filePos;
1319 ParseShapeData(0, 0);
1320
1321 // Keep data for later parsing
1322 shapes[n].file_ptr = (unsigned char*)malloc(m_filePos-here);
1323 if (shapes[n].file_ptr == NULL) {
1324 goto memory_error;
1325 }
1326 memcpy((void*)shapes[n].file_ptr,(void*)&m_fileBuf[here],m_filePos-here);
1327 }
1328
1329 font->setFontShapeTable(shapes,fontGlyphCount);
1330
1331 lut = new long[fontGlyphCount];
1332 if (lut == NULL) {
1333 goto memory_error;
1334 }
1335
1336 for(n=0; n < fontGlyphCount; n++)
1337 {
1338 if (flags & 4) {
1339 lut[n] = GetWord();
1340 } else {
1341 lut[n] = GetByte();
1342 }
1343 }
1344
1345 font->setFontLookUpTable(lut);
1346
1347 delete offsetTable;
1348
1349 addCharacter(font);
1350
1351 // This is an incomplete parsing
1352 return;
1353
1354memory_error:
1355 outOfMemory = 1;
1356 if (font) delete font;
1357 if (offsetTable) delete offsetTable;
1358 if (lut) delete lut;
1359 if (shapes) delete[] shapes;
1360}
1361
1362TextRecord * CInputScript::ParseTextRecord(int hasAlpha)
1363{
1364 TextRecord *tr;
1365 TextFlags flags;
1366
1367 flags = (TextFlags) GetByte();
1368 if (flags == 0) return 0;
1369
1370 tr = new TextRecord;
1371 if (tr == NULL) {
1372 outOfMemory = 1;
1373 return 0;
1374 }
1375
1376 tr->flags = flags;
1377
1378 if (flags & isTextControl) {
1379 if (flags & textHasFont) {
1380 long fontId;
1381
1382 fontId = GetWord();
1383 tr->font = (SwfFont *)getCharacter(fontId);
1384 }
1385 if (flags & textHasColor) {
1386 tr->color.red = GetByte();
1387 tr->color.green = GetByte();
1388 tr->color.blue = GetByte();
1389 if (hasAlpha) {
1390 tr->color.alpha = GetByte();
1391 } else {
1392 tr->color.alpha = ALPHA_OPAQUE;
1393 }
1394 }
1395 if (flags & textHasXOffset) {
1396 tr->xOffset = GetWord();
1397 }
1398 if (flags & textHasYOffset) {
1399 tr->yOffset = GetWord();
1400 }
1401 if (flags & textHasFont) {
1402 tr->fontHeight = GetWord();
1403 }
1404 tr->nbGlyphs = GetByte();
1405 } else {
1406 tr->flags = (TextFlags)0;
1407 tr->nbGlyphs = (long)flags;
1408 }
1409
1410 tr->glyphs = new Glyph[ tr->nbGlyphs ];
1411 if (tr->glyphs == NULL) {
1412 outOfMemory = 1;
1413 delete tr;
1414 return 0;
1415 }
1416
1417 InitBits();
1418 for (int g = 0; g < tr->nbGlyphs; g++)
1419 {
1420 tr->glyphs[g].index = GetBits(m_nGlyphBits);
1421 tr->glyphs[g].xAdvance = GetBits(m_nAdvanceBits);
1422 }
1423
1424 return tr;
1425}
1426
1427void CInputScript::ParseDefineText(int hasAlpha)
1428{
1429 Text *text;
1430 TextRecord*textRecord;
1431 Matrix m;
1432 Rect rect;
1433 U32 tagid = (U32) GetWord();
1434
1435 text = new Text(tagid);
1436 if (text == NULL) {
1437 outOfMemory = 1;
1438 return;
1439 }
1440
1441 GetRect(&rect);
1442 text->setTextBoundary(rect);
1443
1444 GetMatrix(&m);
1445 text->setTextMatrix(m);
1446
1447 m_nGlyphBits = GetByte();
1448 m_nAdvanceBits = GetByte();
1449
1450 do {
1451 textRecord = ParseTextRecord(hasAlpha);
1452 if (textRecord) {
1453 text->addTextRecord( textRecord );
1454 }
1455 if (outOfMemory) {
1456 delete text;
1457 return;
1458 }
1459 if (m_filePos >= m_tagEnd) break;
1460 } while (textRecord);
1461
1462 addCharacter(text);
1463}
1464
1465
1466void CInputScript::ParseDefineSound()
1467{
1468 Sound *sound;
1469 U32 tagid = (U32) GetWord();
1470 long nbSamples;
1471 long flags;
1472 char *buffer;
1473
1474 sound = new Sound(tagid);
1475
1476 flags = GetByte();
1477 sound->setSoundFlags(flags);
1478
1479 nbSamples = GetDWord();
1480 buffer = sound->setNbSamples(nbSamples);
1481 if (buffer == NULL) {
1482 outOfMemory = 1;
1483 delete sound;
1484 return;
1485 }
1486
1487 if (flags & soundIsADPCMCompressed) {
1488 Adpcm *adpcm;
1489
1490 adpcm = new Adpcm( &m_fileBuf[m_filePos] , flags & soundIsStereo );
1491
1492 adpcm->Decompress((short *)buffer, nbSamples);
1493
1494 delete adpcm;
1495 } else {
1496 memcpy(buffer, &m_fileBuf[m_filePos], m_tagLen-5);
1497 }
1498
1499 addCharacter(sound);
1500}
1501
1502
1503void CInputScript::ParseDefineButtonSound()
1504{
1505 U32 tagid = (U32) GetWord();
1506 Button*button;
1507
1508 tagid = tagid;
1509
1510 printf("tagDefineButtonSound \ttagid %-5u\n", tagid);
1511
1512 button = (Button *)getCharacter(tagid);
1513
1514 if (button == 0) {
1515 printf("Couldn't find Button id %d\n", tagid);
1516 return;
1517 }
1518
1519 // step through for button states
1520 for (int i = 0; i < 4; i++)
1521 {
1522 Sound*sound;
1523 U32 soundTag = GetWord();
1524
1525 sound = (Sound *)getCharacter(soundTag);
1526
1527 if (sound) {
1528 button->setButtonSound(sound,i);
1529 } else if (soundTag) {
1530 printf("Couldn't find Sound id %d\n", soundTag);
1531 }
1532
1533 switch (i)
1534 {
1535 case 0:
1536 printf("upState \ttagid %-5u\n", soundTag);
1537 break;
1538 case 1:
1539 printf("overState \ttagid %-5u\n", soundTag);
1540 break;
1541 case 2:
1542 printf("downState \ttagid %-5u\n", soundTag);
1543 break;
1544 }
1545
1546 if (soundTag)
1547 {
1548 U32 code = GetByte();
1549 printf("sound code %u", code);
1550
1551 if ( code & soundHasInPoint )
1552 printf(" inpoint %u", GetDWord());
1553 if ( code & soundHasOutPoint )
1554 printf(" outpoint %u", GetDWord());
1555 if ( code & soundHasLoops )
1556 printf(" loops %u", GetWord());
1557
1558 printf("\n");
1559 if ( code & soundHasEnvelope )
1560 {
1561 int points = GetByte();
1562
1563 for ( int p = 0; p < points; p++ )
1564 {
1565 printf("\n");
1566 printf("mark44 %u", GetDWord());
1567 printf(" left chanel %u", GetWord());
1568 printf(" right chanel %u", GetWord());
1569 printf("\n");
1570 }
1571 }
1572 }
1573 if (m_filePos == m_tagEnd) break;
1574 }
1575}
1576
1577void CInputScript::ParseSoundStreamHead()
1578{
1579 int mixFormat = GetByte();
1580
1581 // The stream settings
1582 int format = GetByte();
1583 int nSamples = GetWord();
1584
1585 mixFormat = mixFormat;
1586 format = format;
1587 nSamples = nSamples;
1588
1589 printf("tagSoundStreamHead \tmixFrmt %-3u frmt %-3u nSamples %-5u\n", mixFormat, format, nSamples);
1590}
1591
1592void CInputScript::ParseSoundStreamHead2()
1593{
1594 int mixFormat = GetByte();
1595
1596 // The stream settings
1597 int format = GetByte();
1598 int nSamples = GetWord();
1599
1600 mixFormat = mixFormat;
1601 format = format;
1602 nSamples = nSamples;
1603
1604 //printf("tagSoundStreamHead2 \tmixFormat %-3u format %-3u nSamples %-5u\n", mixFormat, format, nSamples);
1605}
1606
1607void CInputScript::ParseSoundStreamBlock()
1608{
1609 printf("tagSoundStreamBlock\n");
1610}
1611
1612void CInputScript::ParseDefineButtonCxform()
1613{
1614 ButtonRecord *br;
1615 Button*button;
1616 U32 tagid = (U32) GetWord();
1617
1618 button = (Button *)getCharacter(tagid);
1619
1620 for (br = button->getButtonRecords(); br; br = br->next)
1621 {
1622 br->cxform = new Cxform;
1623 GetCxform(br->cxform, false);
1624 }
1625}
1626
1627void CInputScript::ParseNameCharacter()
1628{
1629 U32 tagid = (U32) GetWord();
1630 char *label = strdup(GetString());
1631
1632 nameCharacter(tagid, label);
1633}
1634
1635
1636void CInputScript::ParseFrameLabel()
1637{
1638 char *label = strdup(GetString());
1639 program->setCurrentFrameLabel(label);
1640}
1641
1642
1643void CInputScript::ParseDefineMouseTarget()
1644{
1645 printf("tagDefineMouseTarget\n");
1646}
1647
1648
1649void CInputScript::ParseDefineSprite()
1650{
1651 Sprite *sprite;
1652 Program *prg;
1653 int status;
1654
1655 U32 tagid = (U32) GetWord();
1656 U32 frameCount = (U32) GetWord();
1657
1658 if (frameCount == 0) return;
1659
1660 printf("tagDefineSprite \ttagid %-5u \tframe count %-5u\n", tagid, frameCount);
1661
1662 sprite = new Sprite(program->movie, tagid, frameCount);
1663 if (sprite == NULL) {
1664 outOfMemory = 1;
1665 return;
1666 }
1667 if (sprite->getProgram() == NULL) {
1668 delete sprite;
1669 outOfMemory = 1;
1670 return;
1671 }
1672
1673 prg = sprite->getProgram();
1674
1675 // Set current program
1676 program = prg;
1677
1678 ParseTags(&status);
1679
1680 if (outOfMemory) {
1681 delete sprite;
1682 return;
1683 }
1684
1685 addCharacter(sprite);
1686}
1687
1688
1689void CInputScript::ParseUnknown(long code, long len)
1690{
1691 printf("Unknown Tag : %d - Length = %d\n", code, len);
1692}
1693
1694
1695void
1696CInputScript::ParseTags(int *status)
1697 // Parses the tags within the file.
1698{
1699
1700 // Initialize the end of frame flag.
1701 BOOL atEnd = false;
1702
1703 // Loop through each tag.
1704 while (!atEnd)
1705 {
1706 U32 here;
1707
1708 // Get the current tag.
1709 U16 code = GetTag();
1710
1711 if (code == notEnoughData) {
1712 m_filePos = m_tagStart;
1713 *status |= FLASH_PARSE_NEED_DATA;
1714 return;
1715 }
1716
1717 //printf("Code %d, tagLen %8u \n", code, m_tagLen);
1718
1719 here = m_filePos;
1720
1721 // Get the tag ending position.
1722 U32 tagEnd = m_tagEnd;
1723
1724 if (m_tagEnd > m_actualSize) {
1725 m_filePos = m_tagStart;
1726 *status |= FLASH_PARSE_NEED_DATA;
1727 return;
1728 }
1729
1730 switch (code)
1731 {
1732 case stagProtect:
1733 break;
1734
1735 case stagEnd:
1736
1737 // We reached the end of the file.
1738 atEnd = true;
1739
1740 printf("End of Movie\n");
1741
1742 break;
1743
1744 case stagShowFrame:
1745
1746 // Validate frame
1747 program->validateLoadingFrame();
1748 *status |= FLASH_PARSE_WAKEUP;
1749
1750 break;
1751
1752 case stagFreeCharacter:
1753 ParseFreeCharacter();
1754 break;
1755
1756 case stagPlaceObject:
1757 ParsePlaceObject();
1758 break;
1759
1760 case stagPlaceObject2:
1761 ParsePlaceObject2();
1762 break;
1763
1764 case stagRemoveObject:
1765 ParseRemoveObject();
1766 break;
1767
1768 case stagRemoveObject2:
1769 ParseRemoveObject2();
1770 break;
1771
1772 case stagSetBackgroundColor:
1773 ParseSetBackgroundColor();
1774 break;
1775
1776 case stagDoAction:
1777 ParseDoAction();
1778 break;
1779
1780 case stagStartSound:
1781 ParseStartSound();
1782 break;
1783
1784 case stagStopSound:
1785 ParseStopSound();
1786 break;
1787
1788 case stagDefineShape:
1789 ParseDefineShape(1);
1790 break;
1791
1792 case stagDefineShape2:
1793 ParseDefineShape(2);
1794 break;
1795
1796 case stagDefineShape3:
1797 ParseDefineShape(3);
1798 break;
1799
1800 case stagDefineBits:
1801 ParseDefineBits();
1802 break;
1803
1804 case stagDefineBitsJPEG2:
1805 ParseDefineBitsJPEG2();
1806 break;
1807
1808 case stagDefineBitsJPEG3:
1809 ParseDefineBitsJPEG3();
1810 break;
1811
1812 case stagDefineBitsLossless:
1813 ParseDefineBitsLossless(1);
1814 break;
1815
1816 case stagDefineBitsLossless2:
1817 ParseDefineBitsLossless(2);
1818 break;
1819
1820 case stagJPEGTables:
1821 ParseJPEGTables();
1822 break;
1823
1824 case stagDefineButton:
1825 ParseDefineButton();
1826 break;
1827
1828 case stagDefineButton2:
1829 ParseDefineButton2();
1830 break;
1831
1832 case stagDefineFont:
1833 ParseDefineFont();
1834 break;
1835
1836 case stagDefineMorphShape:
1837 ParseDefineMorphShape();
1838 break;
1839
1840 case stagDefineFontInfo:
1841 ParseDefineFontInfo();
1842 break;
1843
1844 case stagDefineText:
1845 ParseDefineText(0);
1846 break;
1847
1848 case stagDefineText2:
1849 ParseDefineText(1);
1850 break;
1851
1852 case stagDefineSound:
1853 ParseDefineSound();
1854 break;
1855
1856 case stagDefineButtonSound:
1857 ParseDefineButtonSound();
1858 break;
1859
1860 case stagSoundStreamHead:
1861 ParseSoundStreamHead();
1862 break;
1863
1864 case stagSoundStreamHead2:
1865 ParseSoundStreamHead2();
1866 break;
1867
1868 case stagSoundStreamBlock:
1869 ParseSoundStreamBlock();
1870 break;
1871
1872 case stagDefineButtonCxform:
1873 ParseDefineButtonCxform();
1874 break;
1875
1876 case stagDefineSprite:
1877 Program *save;
1878
1879 save = program;
1880 ParseDefineSprite();
1881 program->rewindMovie();
1882 program = save;
1883 break;
1884
1885 case stagNameCharacter:
1886 ParseNameCharacter();
1887 break;
1888
1889 case stagFrameLabel:
1890 ParseFrameLabel();
1891 break;
1892
1893 case stagDefineFont2:
1894 ParseDefineFont2();
1895 break;
1896
1897 default:
1898 ParseUnknown(code, m_tagLen);
1899 break;
1900 }
1901
1902 //printf("Bytes read = %d\n", m_filePos-here);
1903
1904 // Increment the past the tag.
1905 m_filePos = tagEnd;
1906
1907 if (outOfMemory) {
1908 fprintf(stderr,"Flash: Out of memory\n");
1909 *status |= FLASH_PARSE_OOM;
1910 return;
1911 }
1912 }
1913
1914 program->validateLoadingFrame();
1915 *status |= FLASH_PARSE_EOM;
1916}
1917
1918int
1919CInputScript::ParseData(FlashMovie *movie, char * data, long size)
1920{
1921 int status = FLASH_PARSE_ERROR;
1922
1923 m_fileBuf = (unsigned char *)data;
1924 m_actualSize = size;
1925
1926 if (needHeader) {
1927
1928 // Do we have sufficient data to read the header ?
1929 if (size < 21) {
1930 return FLASH_PARSE_NEED_DATA;// No, need more data
1931 }
1932
1933 needHeader = 0;// Yes
1934
1935 U8 fileHdr[8];
1936
1937 memcpy(fileHdr,data,8);
1938
1939 // Verify the header and get the file size.
1940 if (fileHdr[0] != 'F' || fileHdr[1] != 'W' || fileHdr[2] != 'S' )
1941 {
1942 //fprintf(stderr, "Not a Flash File.\n");
1943 return FLASH_PARSE_ERROR;// Error
1944 }
1945 else
1946 {
1947 // Get the file version.
1948 m_fileVersion = (U16) fileHdr[3];
1949 }
1950
1951 // Get the file size.
1952 m_fileSize = (U32) fileHdr[4]
1953 | ((U32) fileHdr[5] << 8)
1954 | ((U32) fileHdr[6] << 16)
1955 | ((U32) fileHdr[7] << 24);
1956
1957 // Verify the minimum length of a Flash file.
1958 if (m_fileSize < 21)
1959 {
1960 //printf("ERROR: File size is too short\n");
1961 return FLASH_PARSE_ERROR;// Error
1962 }
1963
1964 // Set the file position past the header and size information.
1965 m_filePos = 8;
1966
1967 // Get the frame information.
1968 GetRect(&frameRect);
1969
1970 frameRate = GetWord() >> 8;
1971
1972 frameCount = GetWord();
1973
1974 program = new Program(movie, frameCount);
1975
1976 if (program == NULL || program->totalFrames == 0) {
1977 return FLASH_PARSE_ERROR;
1978 }
1979
1980 status |= FLASH_PARSE_START;
1981 }
1982
1983 ParseTags(&status);
1984
1985 return status;
1986}
1987
1988
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 @@
1#ifndef _SCRIPT_H_
2#define _SCRIPT_H_
3
4// SWF file parser.
5//
6//////////////////////////////////////////////////////////////////////
7
8//////////////////////////////////////////////////////////////////////
9// Input script object definition.
10//////////////////////////////////////////////////////////////////////
11
12// An input script object. This object represents a script created from
13// an external file that is meant to be inserted into an output script.
14struct CInputScript : public Dict
15{
16 int level;
17 struct CInputScript *next;
18
19 Program *program;// Current parsed program
20
21 // Memory fences
22 int outOfMemory;
23
24 //Flash info
25 long frameRate;
26 long frameCount;
27 Rect frameRect;
28
29 // Pointer to file contents buffer.
30 U8 *m_fileBuf;
31
32 // File state information.
33 U32 m_filePos;
34 U32 m_fileSize;
35 U32 m_actualSize;
36 U32 m_fileStart;
37 U16 m_fileVersion;
38
39 int needHeader;
40
41 // Bit Handling
42 S32 m_bitPos;
43 U32 m_bitBuf;
44
45 // Tag parsing information.
46 U32 m_tagStart;
47 U32 m_tagEnd;
48 U32 m_tagLen;
49
50 // Parsing information.
51 S32 m_nFillBits;
52 S32 m_nLineBits;
53 S32 m_nGlyphBits;
54 S32 m_nAdvanceBits;
55
56 // Set to true if we wish to dump all contents long form
57 U32 m_dumpAll;
58
59 // if set to true will dump image guts (i.e. jpeg, zlib, etc. data)
60 U32 m_dumpGuts;
61
62 // Handle to output file.
63 FILE *m_outputFile;
64
65 // Constructor/destructor.
66 CInputScript(int level = 0);
67 ~CInputScript();
68
69 // Tag scanning methods.
70 U16 GetTag(void);
71 U8 GetByte(void);
72 U16 GetWord(void);
73 U32 GetDWord(void);
74 void GetRect(Rect *r);
75 void GetMatrix(Matrix *matrix);
76
77 void GetCxform(Cxform *cxform, BOOL hasAlpha);
78 char *GetString(void);
79
80 // Routines for reading arbitrary sized bit fields from the stream.
81 // Always call start bits before gettings bits and do not intermix
82 // these calls with GetByte, etc...
83 void InitBits();
84 S32 GetSBits(S32 n);
85 U32 GetBits(S32 n);
86
87 // Tag subcomponent parsing methods
88 void ParseFillStyle(long getAlpha = 0);
89 void ParseLineStyle(long getAlpha = 0);
90 int ParseShapeRecord(long getAlpha = 0);
91 ButtonRecord * ParseButtonRecord(long getCxform = 0);
92 ActionRecord * ParseActionRecord();
93 TextRecord * ParseTextRecord(int hasAlpha = 0);
94 void ParseShapeData(int getAlpha, int getStyles);
95
96 // Parsing methods.
97 void ParseEnd(); // 00: stagEnd
98 void ParseShowFrame(U32 frame, U32 offset);// 01: stagShowFrame
99 void ParseDefineShape(int level); // 02: stagDefineShape
100 void ParseFreeCharacter(); // 03: stagFreeCharacter
101 void ParsePlaceObject(); // 04: stagPlaceObject
102 void ParseRemoveObject(); // 05: stagRemoveObject
103 void ParseDefineBits(); // 06: stagDefineBits
104 void ParseDefineButton(); //x 07: stagDefineButton
105 void ParseJPEGTables(); // 08: stagJPEGTables
106 void ParseSetBackgroundColor(); // 09: stagSetBackgroundColor
107 void ParseDefineFont(); //x 10: stagDefineFont
108 void ParseDefineText(int hasAplha); //x 11: stagDefineText 33: stagDefineText2
109 void ParseDoAction(); // 12: stagDoAction
110 void ParseDefineFontInfo(); //x 13: stagDefineFontInfo
111 void ParseDefineSound(); // 14: stagDefineSound
112 void ParseStartSound(); // 15: stagStartSound
113 void ParseStopSound(); // 16: stagStopSound
114 void ParseDefineButtonSound(); // 17: stagDefineButtonSound
115 void ParseSoundStreamHead(); // 18: stagSoundStreamHead
116 void ParseSoundStreamBlock(); // 19: stagSoundStreamBlock
117 void ParseDefineBitsLossless(int level); // 20: stagDefineBitsLossless 36: stagDefineBitsLossless2
118 void ParseDefineBitsJPEG2(); // 21: stagDefineBitsJPEG2
119 void ParseDefineButtonCxform(); // 23: stagDefineButtonCxform
120 void ParseProtect(); // 24: stagProtect
121 void ParsePlaceObject2(); // 26: stagPlaceObject2
122 void ParseRemoveObject2(); // 28: stagRemoveObject2
123 void ParseDefineButton2(); //x 34: stagDefineButton2
124 void ParseDefineBitsJPEG3(); // 35: stagDefineBitsJPEG3
125 void ParseDefineMouseTarget(); // 38: stagDefineMouseTarget
126 void ParseDefineSprite(); //x 39: stagDefineSprite
127 void ParseNameCharacter(); // 40: stagNameCharacter
128 void ParseFrameLabel(); // 43: stagFrameLabel
129 void ParseSoundStreamHead2(); // 45: stagSoundStreamHead2
130 void ParseDefineMorphShape(); //x 46: stagDefineMorphShape
131 void ParseDefineFont2(); //x 48: stagDefineFont2
132 void ParseUnknown(long,long);
133
134 void ParseTags(int *);
135 int ParseData(FlashMovie *movie, char * data, long size);
136 void S_DumpImageGuts();
137
138#ifdef DUMP
139 long save(char *filenam);
140#endif
141};
142
143
144#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 @@
1/////////////////////////////////////////////////////////////
2// Flash Plugin and Player
3// Copyright (C) 1998,1999 Olivier Debon
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19///////////////////////////////////////////////////////////////
20// Author : Olivier Debon <odebon@club-internet.fr>
21//
22
23#include "swf.h"
24
25#ifdef RCSID
26static char *rcsid = "$Id$";
27#endif
28
29#define PRINT 0
30
31#define ABS(v) ((v) < 0 ? -(v) : (v))
32
33static void prepareStyles(GraphicDevice *gd, Matrix *matrix, Cxform *cxform, FillStyleDef *f, long n);
34
35static void clearStyles(GraphicDevice *gd, FillStyleDef *f, long n);
36
37static void drawShape(GraphicDevice *gd, Matrix *matrix1, Cxform *cxform, Shape *shape,
38 ShapeAction shapeAction, void *id,ScanLineFunc scan_line_func);
39
40// Constructor
41
42Shape::Shape(long id, int level) : Character(ShapeType, id)
43{
44 defLevel = level;
45
46 defaultFillStyle.type = f_Solid;
47 defaultFillStyle.color.red = 0;
48 defaultFillStyle.color.green = 0;
49 defaultFillStyle.color.blue = 0;
50 defaultFillStyle.color.alpha = ALPHA_OPAQUE;
51
52 defaultLineStyle.width = 0;
53
54 // This is to force a first update
55 lastMat.a = 0;
56 lastMat.d = 0;
57 shape_size += sizeof(Shape);
58 shape_nb ++;
59
60 file_ptr = NULL;
61 getStyles = 0;
62 getAlpha = 0;
63}
64
65Shape::~Shape()
66{
67 if (file_ptr) {
68 free(file_ptr);
69 }
70}
71
72void
73Shape::setBoundingBox(Rect rect)
74{
75 boundary = rect;
76}
77
78void
79Shape::getBoundingBox(Rect *bb, DisplayListEntry *e)
80{
81 *bb = boundary;
82}
83
84int
85Shape::execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform)
86{
87 //printf("TagId = %d\n", getTagId());
88 //if (getTagId() != 220) return 0;
89
90 if (cxform) {
91 defaultFillStyle.color = cxform->getColor(gd->getForegroundColor());
92 } else {
93 defaultFillStyle.color = gd->getForegroundColor();
94 }
95 defaultFillStyle.color.pixel = gd->allocColor(defaultFillStyle.color);
96
97 drawShape(gd, matrix, cxform, this, ShapeDraw, NULL, 0);
98 return 0;
99}
100
101void
102Shape::getRegion(GraphicDevice *gd, Matrix *matrix, void *id, ScanLineFunc scan_line_func)
103{
104 gd->setClipping(0);
105 drawShape(gd,matrix,0,this,ShapeGetRegion,id,scan_line_func);
106 gd->setClipping(1);
107}
108
109/************************************************************************/
110
111/* create a new path */
112
113static void newPath(ShapeParser *shape,
114 long x, long y)
115{
116 Path *p;
117 long x1,y1;
118
119 p=&shape->curPath;
120
121 x1 = shape->matrix->getX(x, y);
122 y1 = shape->matrix->getY(x, y);
123
124 p->lastX = x1;
125 p->lastY = y1;
126
127 p->nb_edges = 0;
128 p->nb_segments = 0;
129}
130
131
132static void addSegment1(ShapeParser *shape,
133 long x, long y,
134 FillStyleDef *f0,
135 FillStyleDef *f1,
136 LineStyleDef *l)
137{
138 Path *p;
139 p=&shape->curPath;
140
141 if (l) {
142 /* a line is defined ... it will be drawn later */
143 LineSegment *ls;
144
145 ls = new LineSegment;
146 if (ls != NULL) {
147 ls->l = l;
148 ls->x1 = p->lastX;
149 ls->y1 = p->lastY;
150 ls->x2 = x;
151 ls->y2 = y;
152 ls->first = (p->nb_segments == 0);
153 ls->next = NULL;
154 if (shape->last_line == NULL) {
155 shape->first_line = ls;
156 } else {
157 shape->last_line->next = ls;
158 }
159 shape->last_line = ls;
160 }
161 }
162
163 /* anti antialiasing not needed if line */
164 if (!shape->reverse) {
165 shape->gd->addSegment(p->lastX,p->lastY,x,y,f0,f1,l ? 0 : 1);
166 } else {
167 shape->gd->addSegment(p->lastX,p->lastY,x,y,f1,f0,l ? 0 : 1);
168 }
169
170 p->lastX = x;
171 p->lastY = y;
172
173 p->nb_segments++;
174}
175
176
177static void addLine(ShapeParser *shape, long x, long y,
178 FillStyleDef *f0,
179 FillStyleDef *f1,
180 LineStyleDef *l)
181{
182 long x1,y1;
183 Path *p;
184
185 p=&shape->curPath;
186
187 x1 = shape->matrix->getX(x, y);
188 y1 = shape->matrix->getY(x, y);
189
190 addSegment1(shape,x1,y1,f0,f1,l);
191
192 p->nb_edges++;
193}
194
195
196// This is based on Divide and Conquer algorithm.
197
198#define BFRAC_BITS 0
199#define BFRAC (1 << BFRAC_BITS)
200
201static void
202bezierBuildPoints (ShapeParser *s,
203 int subdivisions,
204 long a1X, long a1Y,
205 long cX, long cY,
206 long a2X, long a2Y)
207{
208 long c1X,c1Y;
209 long c2X,c2Y;
210 long X,Y;
211 long xmin,ymin,xmax,ymax;
212
213 if (subdivisions != 0) {
214
215 /* find the bounding box */
216
217 if (a1X < cX) {
218 xmin = a1X;
219 xmax = cX;
220 } else {
221 xmin = cX;
222 xmax = a1X;
223 }
224 if (a2X < xmin) xmin = a2X;
225 if (a2X > xmax) xmax = a2X;
226
227 if (a1Y < cY) {
228 ymin = a1Y;
229 ymax = cY;
230 } else {
231 ymin = cY;
232 ymax = a1Y;
233 }
234 if (a2Y < ymin) ymin = a2Y;
235 if (a2Y > ymax) ymax = a2Y;
236
237 if (((xmax - xmin) + (ymax - ymin)) >= (BFRAC*FRAC*2)) {
238 // Control point 1
239 c1X = (a1X+cX) >> 1;
240 c1Y = (a1Y+cY) >> 1;
241
242 // Control point 2
243 c2X = (a2X+cX) >> 1;
244 c2Y = (a2Y+cY) >> 1;
245
246 // New point
247 X = (c1X+c2X) >> 1;
248 Y = (c1Y+c2Y) >> 1;
249
250 subdivisions--;
251
252 bezierBuildPoints(s, subdivisions,
253 a1X, a1Y, c1X, c1Y, X, Y);
254 bezierBuildPoints(s, subdivisions,
255 X, Y, c2X, c2Y, a2X, a2Y);
256
257 return;
258 }
259 }
260
261 addSegment1(s, (a2X+(BFRAC/2)) >> BFRAC_BITS,
262 (a2Y+(BFRAC/2)) >> BFRAC_BITS, s->f0, s->f1, s->l);
263}
264
265/* this code is broken, but useful to get something */
266static void flushPaths(ShapeParser *s)
267{
268 LineSegment *ls;
269 LineStyleDef *l;
270 long nx,ny,nn,w;
271 GraphicDevice *gd = s->gd;
272
273 /* draw the filled polygon */
274 gd->drawPolygon();
275
276 /* draw the lines */
277 ls = s->first_line;
278 if (ls != NULL) {
279 do {
280 l = ls->l;
281
282#if 0
283 printf("line %d %d %d %d width=%d\n",
284 ls->x1, ls->y1, ls->x2, ls->y2, l->width);
285#endif
286
287 /* XXX: this width is false, but it is difficult (and expensive)
288 to have the correct one */
289 w = ABS((long)(s->matrix->a * l->width));
290
291 if (w <= ((3*FRAC)/2)) {
292 w = FRAC;
293 }
294#ifdef THIN_LINES
295 if (w <= ((3*FRAC)/2)) {
296 // draw the thin lines only in shapeAction == shapeDraw
297 if (gd->scan_line_func == NULL) {
298 gd->setForegroundColor(l->fillstyle.color);
299 gd->drawLine(ls->x1, ls->y1, ls->x2, ls->y2, w);
300 }
301 } else {
302#else
303 {
304#endif
305 /* compute the normal vector */
306
307 nx = -(ls->y2 - ls->y1);
308 ny = (ls->x2 - ls->x1);
309
310 /* normalize & width */
311 nn = 2 * (long) sqrt(nx * nx + ny * ny);
312
313#define UL ls->x1 + nx -ny, ls->y1 + ny +nx
314#define UR ls->x2 + nx +ny, ls->y2 + ny -nx
315#define LL ls->x1 - nx -ny, ls->y1 - ny +nx
316#define LR ls->x2 - nx +ny, ls->y2 - ny -nx
317
318 if (nn > 0) {
319 nx = (nx * w) / nn;
320 ny = (ny * w) / nn;
321
322 /* top segment */
323 gd->addSegment(UL, UR, NULL, &l->fillstyle, 1);
324
325 /* bottom segment */
326 gd->addSegment(LL, LR, &l->fillstyle, NULL, 1);
327
328 /* right segment */
329 gd->addSegment(UR, LR, &l->fillstyle, NULL, 1);
330
331 /* left segment */
332 gd->addSegment(UL, LL, NULL, &l->fillstyle, 1);
333
334 /* draw the line polygon */
335 gd->drawPolygon();
336 }
337 }
338
339 ls = ls->next;
340 } while (ls != NULL);
341
342 /* delete the line structures */
343
344 ls = s->first_line;
345 while (ls != NULL) {
346 LineSegment *ls1;
347 ls1 = ls->next;
348 delete ls;
349 ls = ls1;
350 }
351
352 /* reset the line pointers */
353 s->first_line = NULL;
354 s->last_line = NULL;
355 }
356}
357
358
359static void addBezier(ShapeParser *shape,
360 long ctrlX1, long ctrlY1,
361 long newX1, long newY1,
362 FillStyleDef *f0,
363 FillStyleDef *f1,
364 LineStyleDef *l)
365{
366 long newX,newY,ctrlX,ctrlY;
367 Path *p;
368
369 p=&shape->curPath;
370
371 /* note: we do the matrix multiplication before calculating the
372 bezier points (faster !) */
373
374 ctrlX = shape->matrix->getX(ctrlX1, ctrlY1);
375 ctrlY = shape->matrix->getY(ctrlX1, ctrlY1);
376 newX = shape->matrix->getX(newX1, newY1);
377 newY = shape->matrix->getY(newX1, newY1);
378
379 shape->f0 = f0;
380 shape->f1 = f1;
381 shape->l = l;
382
383 bezierBuildPoints(shape, 3,
384 p->lastX<<BFRAC_BITS,p->lastY<<BFRAC_BITS,
385 ctrlX<<BFRAC_BITS,ctrlY<<BFRAC_BITS,
386 newX<<BFRAC_BITS,newY<<BFRAC_BITS);
387
388 p->nb_edges++;
389}
390
391/***********************************************************************/
392
393
394/* bit parser */
395
396static void InitBitParser(struct BitParser *b,U8 *buf)
397{
398 b->ptr = buf;
399}
400
401static void InitBits(struct BitParser *b)
402{
403 // Reset the bit position and buffer.
404 b->m_bitPos = 0;
405 b->m_bitBuf = 0;
406}
407
408
409
410static inline U8 GetByte(struct BitParser *b)
411{
412 U8 v;
413 v = *b->ptr++;
414 return v;
415}
416
417static inline U16 GetWord(struct BitParser *b)
418{
419 U8 *s;
420 U16 v;
421 s = b->ptr;
422 v = s[0] | ((U16) s[1] << 8);
423 b->ptr = s + 2;
424 return v;
425}
426
427static inline U32 GetDWord(struct BitParser *b)
428{
429 U32 v;
430 U8 * s = b->ptr;
431 v = (U32) s[0] | ((U32) s[1] << 8) |
432 ((U32) s[2] << 16) | ((U32) s [3] << 24);
433 b->ptr = s + 4;
434 return v;
435}
436
437static inline U32 GetBit (struct BitParser *b)
438{
439 U32 v;
440 S32 m_bitPos = b->m_bitPos;
441 U32 m_bitBuf = b->m_bitBuf;
442
443 if (m_bitPos == 0) {
444 m_bitBuf = (U32)(*b->ptr++) << 24;
445 m_bitPos = 8;
446 }
447
448 v = (m_bitBuf >> 31);
449
450 m_bitPos--;
451 m_bitBuf <<= 1;
452
453 b->m_bitPos = m_bitPos;
454 b->m_bitBuf = m_bitBuf;
455
456 return v;
457}
458
459static inline U32 GetBits (struct BitParser *b, int n)
460{
461 U32 v;
462 S32 m_bitPos = b->m_bitPos;
463 U32 m_bitBuf = b->m_bitBuf;
464
465 if (n == 0)
466 return 0;
467
468 while (m_bitPos < n) {
469 m_bitBuf |= (U32)(*b->ptr++) << (24 - m_bitPos);
470 m_bitPos += 8;
471 }
472
473 v = m_bitBuf >> (32 - n);
474 m_bitBuf <<= n;
475 m_bitPos -= n;
476
477 b->m_bitPos = m_bitPos;
478 b->m_bitBuf = m_bitBuf;
479 return v;
480}
481
482// Get n bits from the string with sign extension.
483static inline S32 GetSBits (struct BitParser *b,S32 n)
484{
485 // Get the number as an unsigned value.
486 S32 v = (S32) GetBits(b,n);
487
488 // Is the number negative?
489 if (v & (1L << (n - 1)))
490 {
491 // Yes. Extend the sign.
492 v |= -1L << n;
493 }
494
495 return v;
496}
497
498
499
500/************************************************************************/
501
502static void GetMatrix(BitParser *b, Matrix* mat)
503{
504 InitBits(b);
505
506 // Scale terms
507 if (GetBit(b))
508 {
509 int nBits = (int) GetBits(b,5);
510 mat->a = (float)(GetSBits(b,nBits))/(float)0x10000;
511 mat->d = (float)(GetSBits(b,nBits))/(float)0x10000;
512 }
513 else
514 {
515 mat->a = mat->d = 1.0;
516 }
517
518 // Rotate/skew terms
519 if (GetBit(b))
520 {
521 int nBits = (int)GetBits(b,5);
522 mat->c = (float)(GetSBits(b,nBits))/(float)0x10000;
523 mat->b = (float)(GetSBits(b,nBits))/(float)0x10000;
524 }
525 else
526 {
527 mat->b = mat->c = 0.0;
528 }
529
530 // Translate terms
531 int nBits = (int) GetBits(b,5);
532 mat->tx = GetSBits(b,nBits);
533 mat->ty = GetSBits(b,nBits);
534}
535
536static FillStyleDef * ParseFillStyle(ShapeParser *shape, long *n, long getAlpha)
537{
538 BitParser *b = &shape->bit_parser;
539 FillStyleDef *defs;
540 U16 i = 0;
541
542 // Get the number of fills.
543 U16 nFills = GetByte(b);
544
545 // Do we have a larger number?
546 if (nFills == 255)
547 {
548 // Get the larger number.
549 nFills = GetWord(b);
550 }
551
552 *n = nFills;
553 defs = new FillStyleDef[ nFills ];
554 if (defs == NULL) return NULL;
555
556 // Get each of the fill style.
557 for (i = 0; i < nFills; i++)
558 {
559 U16 fillStyle = GetByte(b);
560
561 defs[i].type = (FillType) fillStyle;
562
563 if (fillStyle & 0x10)
564 {
565 defs[i].type = (FillType) (fillStyle & 0x12);
566
567 // Get the gradient matrix.
568 GetMatrix(b,&(defs[i].matrix));
569
570 // Get the number of colors.
571 defs[i].gradient.nbGradients = GetByte(b);
572
573 // Get each of the colors.
574 for (U16 j = 0; j < defs[i].gradient.nbGradients; j++)
575 {
576 defs[i].gradient.ratio[j] = GetByte(b);
577 defs[i].gradient.color[j].red = GetByte(b);
578 defs[i].gradient.color[j].green = GetByte(b);
579 defs[i].gradient.color[j].blue = GetByte(b);
580 if (getAlpha) {
581 defs[i].gradient.color[j].alpha = GetByte(b);
582 } else {
583 defs[i].gradient.color[j].alpha = ALPHA_OPAQUE;
584 }
585 }
586 }
587 else if (fillStyle & 0x40)
588 {
589 defs[i].type = (FillType) (fillStyle & 0x41);
590
591 // Get the bitmapId
592 defs[i].bitmap = (Bitmap *)shape->dict->getCharacter(GetWord(b));
593 // Get the bitmap matrix.
594 GetMatrix(b,&(defs[i].matrix));
595 }
596 else
597 {
598 defs[i].type = (FillType) 0;
599
600 // A solid color
601 defs[i].color.red = GetByte(b);
602 defs[i].color.green = GetByte(b);
603 defs[i].color.blue = GetByte(b);
604 if (getAlpha) {
605 defs[i].color.alpha = GetByte(b);
606 } else {
607 defs[i].color.alpha = ALPHA_OPAQUE;
608 }
609 }
610 }
611
612 return defs;
613}
614
615static LineStyleDef * ParseLineStyle(ShapeParser *shape, long *n, long getAlpha)
616{
617 BitParser *b = &shape->bit_parser;
618 LineStyleDef *defs,*def;
619 FillStyleDef *f;
620 long i;
621
622 // Get the number of lines.
623 U16 nLines = GetByte(b);
624
625 // Do we have a larger number?
626 if (nLines == 255)
627 {
628 // Get the larger number.
629 nLines = GetWord(b);
630 }
631
632 *n = nLines;
633 defs = new LineStyleDef[ nLines ];
634 if (defs == NULL) return NULL;
635
636 // Get each of the line styles.
637 for (i = 0; i < nLines; i++)
638 {
639 def=&defs[i];
640 def->width = GetWord(b);
641 def->color.red = GetByte(b);
642 def->color.green = GetByte(b);
643 def->color.blue = GetByte(b);
644 if (getAlpha) {
645 def->color.alpha = GetByte(b);
646 } else {
647 def->color.alpha = ALPHA_OPAQUE;
648 }
649
650 f=&def->fillstyle;
651 f->type = f_Solid;
652 f->color = def->color;
653 if (shape->cxform) {
654 f->color = shape->cxform->getColor(f->color);
655 }
656 f->color.pixel = shape->gd->allocColor(f->color);
657 }
658
659 return defs;
660}
661
662/* 0 = end of shape */
663static int ParseShapeRecord(ShapeParser *shape, ShapeRecord *sr, long getAlpha)
664{
665 BitParser *b = &shape->bit_parser;
666
667 // Determine if this is an edge.
668 BOOL isEdge = (BOOL) GetBit(b);
669
670 if (!isEdge)
671 {
672 // Handle a state change
673 U16 flags = (U16) GetBits(b,5);
674
675 // Are we at the end?
676 if (flags == 0)
677 {
678 // End of shape
679 return 0;
680 }
681
682 sr->type = shapeNonEdge;
683 sr->flags = (ShapeFlags)flags;
684
685 // Process a move to.
686 if (flags & flagsMoveTo)
687 {
688 U16 nBits = (U16) GetBits(b,5);
689 sr->x = GetSBits(b,nBits);
690 sr->y = GetSBits(b,nBits);
691 }
692
693 // Get new fill info.
694 if (flags & flagsFill0)
695 {
696 sr->fillStyle0 = GetBits(b,shape->m_nFillBits);
697 }
698 if (flags & flagsFill1)
699 {
700 sr->fillStyle1 = GetBits(b,shape->m_nFillBits);
701 }
702
703 // Get new line info
704 if (flags & flagsLine)
705 {
706 sr->lineStyle = GetBits(b,shape->m_nLineBits);
707 }
708
709 // Check to get a new set of styles for a new shape layer.
710 if (flags & flagsNewStyles)
711 {
712 FillStyleDef *fillDefs;
713 LineStyleDef *lineDefs;
714 long n;
715
716 // Parse the style.
717 fillDefs = ParseFillStyle(shape, &n, getAlpha);
718 if (fillDefs == NULL) return 0;
719
720 sr->newFillStyles = fillDefs;
721 sr->nbNewFillStyles = n;
722
723 lineDefs = ParseLineStyle(shape, &n, getAlpha);
724 if (lineDefs == NULL) return 0;
725
726 sr->newLineStyles = lineDefs;
727 sr->nbNewLineStyles = n;
728
729 InitBits(b);// Bug !
730
731 // Reset.
732 shape->m_nFillBits = (U16) GetBits(b,4);
733 shape->m_nLineBits = (U16) GetBits(b,4);
734 }
735
736 //if (flags & flagsEndShape)
737 //printf("\tEnd of shape.\n\n");
738
739 return flags & flagsEndShape ? 0 : 1;
740 }
741 else
742 {
743 if (GetBit(b))
744 {
745 sr->type = shapeLine;
746
747 // Handle a line
748 U16 nBits = (U16) GetBits(b,4) + 2;// nBits is biased by 2
749
750 // Save the deltas
751 if (GetBit(b))
752 {
753 // Handle a general line.
754 sr->dX = GetSBits(b,nBits);
755 sr->dY = GetSBits(b,nBits);
756 }
757 else
758 {
759 // Handle a vert or horiz line.
760 if (GetBit(b))
761 {
762 // Vertical line
763 sr->dY = GetSBits(b,nBits);
764 sr->dX = 0;
765 }
766 else
767 {
768 // Horizontal line
769 sr->dX = GetSBits(b,nBits);
770 sr->dY = 0;
771 }
772 }
773 }
774 else
775 {
776 sr->type = shapeCurve;
777
778 // Handle a curve
779 U16 nBits = (U16) GetBits(b,4) + 2;// nBits is biased by 2
780
781 // Get the control
782 sr->ctrlX = GetSBits(b,nBits);
783 sr->ctrlY = GetSBits(b,nBits);
784
785 // Get the anchor
786 sr->anchorX = GetSBits(b,nBits);
787 sr->anchorY = GetSBits(b,nBits);
788 }
789
790 return 1;
791 }
792}
793
794static void drawShape(GraphicDevice *gd, Matrix *matrix1, Cxform *cxform, Shape *shape,
795 ShapeAction shapeAction, void *id,ScanLineFunc scan_line_func)
796{
797 LineStyleDef *l;
798 FillStyleDef *f0;
799 FillStyleDef *f1;
800 ShapeRecord sr1,*sr = &sr1;
801 int firstPoint;
802 long lastX,lastY;
803 LineStyleDef *curLineStyle;
804 long curNbLineStyles;
805 FillStyleDef *curFillStyle;
806 long curNbFillStyles;
807 StyleList *sl;
808 ShapeParser sp1,*sp=&sp1;
809 BitParser *b;
810 Matrix mat,*matrix;
811
812 mat = (*gd->adjust) * (*matrix1);
813 matrix = &mat;
814
815 sp->reverse = (mat.a * mat.d) < 0;
816
817 curLineStyle = NULL;
818 curNbLineStyles = 0;
819 curFillStyle = NULL;
820 curNbFillStyles = 0;
821 sp->style_list = NULL;
822
823 sp->shape = shape;
824 sp->gd = gd;
825 sp->matrix = matrix;
826 sp->cxform = cxform;
827 sp->dict = shape->dict;
828
829 if (shapeAction == ShapeGetRegion) {
830 gd->scan_line_func = scan_line_func;
831 gd->scan_line_func_id = id;
832 } else {
833 gd->scan_line_func = NULL;
834 }
835
836 b = &sp->bit_parser;
837 InitBitParser(b,shape->file_ptr);
838
839 if (shape->getStyles) {
840 // ShapeWithStyle
841 curFillStyle = ParseFillStyle(sp, &curNbFillStyles, shape->getAlpha);
842 if (curFillStyle == NULL) return;
843
844 curLineStyle = ParseLineStyle(sp, &curNbLineStyles, shape->getAlpha);
845 if (curLineStyle == NULL) return;
846
847 sl = new StyleList;
848 if (sl == NULL) return;
849
850 sl->next = NULL;
851 sl->newFillStyles = curFillStyle;
852 sl->nbNewFillStyles = curNbFillStyles;
853 sl->newLineStyles = curLineStyle;
854 sl->nbNewLineStyles = curNbLineStyles;
855
856 sp->style_list = sl;
857
858 if (shapeAction == ShapeDraw) {
859 prepareStyles(gd, matrix, cxform, curFillStyle, curNbFillStyles);
860 }
861 }
862
863 InitBits(b);
864 sp->m_nFillBits = (U16) GetBits(b,4);
865 sp->m_nLineBits = (U16) GetBits(b,4);
866
867 l = 0;
868 f0 = 0;
869 f1 = 0;
870 firstPoint = 1;
871 lastX = 0;
872 lastY = 0;
873 sp->curPath.nb_edges = 0;
874 sp->first_line = NULL;
875 sp->last_line = NULL;
876
877 for(;;) {
878 if (ParseShapeRecord(sp, sr, shape->getAlpha) == 0) break;
879
880 switch (sr->type)
881 {
882 case shapeNonEdge:
883 if (sr->flags & flagsNewStyles) {
884
885 curFillStyle = sr->newFillStyles;
886 curNbFillStyles = sr->nbNewFillStyles;
887 curLineStyle = sr->newLineStyles;
888 curNbLineStyles = sr->nbNewLineStyles;
889
890 sl = new StyleList;
891 sl->next = sp->style_list;
892 sl->newFillStyles = sr->newFillStyles;
893 sl->nbNewFillStyles = sr->nbNewFillStyles;
894 sl->newLineStyles = sr->newLineStyles;
895 sl->nbNewLineStyles = sr->nbNewLineStyles;
896
897 sp->style_list = sl;
898
899 if (shapeAction == ShapeDraw) {
900 prepareStyles(gd, matrix, cxform, curFillStyle, curNbFillStyles);
901 }
902 }
903 if (sr->flags & flagsFill0) {
904 if (sr->fillStyle0) {
905 if (curFillStyle) {
906 f0 = &curFillStyle[sr->fillStyle0-1];
907 } else {
908 f0 = &shape->defaultFillStyle;
909 }
910 } else {
911 f0 = 0;
912 }
913 }
914 if (sr->flags & flagsFill1) {
915 if (sr->fillStyle1) {
916 if (curFillStyle) {
917 f1 = &curFillStyle[sr->fillStyle1-1];
918 } else {
919 f1 = &shape->defaultFillStyle;
920 }
921 } else {
922 f1 = 0;
923 }
924 }
925 if (sr->flags & flagsLine) {
926 if (sr->lineStyle) {
927 l = &curLineStyle[sr->lineStyle-1];
928 } else {
929 l = 0;
930 }
931 }
932 if (sr->flags & flagsMoveTo) {
933 if (sp->curPath.nb_edges == 0) {
934 /* if no edges, draw the polygon, then the lines */
935 flushPaths(sp);
936 }
937
938 newPath(sp, sr->x, sr->y);
939 firstPoint = 0;
940
941 lastX = sr->x;
942 lastY = sr->y;
943
944#if PRINT
945 printf("---------\nX,Y = %4d,%4d\n", sr->x/20, sr->y/20);
946#endif
947 }
948 break;
949 case shapeCurve:
950 // Handle Bezier Curves !!!
951 if (firstPoint) {
952 newPath(sp, 0, 0);
953 firstPoint = 0;
954 }
955 {
956 long newX,newY,ctrlX,ctrlY;
957
958 ctrlX = lastX+sr->ctrlX;
959 ctrlY = lastY+sr->ctrlY;
960 newX = ctrlX+sr->anchorX;
961 newY = ctrlY+sr->anchorY;
962
963#if 1
964 addBezier(sp, ctrlX, ctrlY, newX, newY, f0 , f1, l);
965#else
966 addLine(sp, newX, newY, f0, f1, l);
967#endif
968
969 lastX = newX;
970 lastY = newY;
971 }
972 break;
973 case shapeLine:
974 if (firstPoint) {
975 newPath(sp, 0, 0);
976 firstPoint = 0;
977 }
978
979 lastX += sr->dX;
980 lastY += sr->dY;
981
982 addLine(sp, lastX, lastY, f0, f1, l);
983#if PRINT
984 printf(" X, Y = %4d,%4d\n", lastX/20, lastY/20);
985#endif
986 break;
987 }
988 }
989
990 /* XXX: should test if there is something to draw */
991 flushPaths(sp);
992
993 /* free the styles */
994 while (sp->style_list) {
995 StyleList *sl;
996
997 sl=sp->style_list;
998 sp->style_list = sl->next;
999
1000 if (shapeAction == ShapeDraw) {
1001 clearStyles(gd, sl->newFillStyles, sl->nbNewFillStyles);
1002 }
1003
1004 delete[] sl->newFillStyles;
1005 delete[] sl->newLineStyles;
1006
1007 delete sl;
1008 }
1009}
1010
1011static void
1012prepareStyles(GraphicDevice *gd, Matrix *matrix, Cxform *cxform,
1013 FillStyleDef *ftab, long n)
1014{
1015 long fs;
1016 FillStyleDef *f;
1017
1018 for(fs = 0; fs < n; fs++)
1019 {
1020 f = ftab + fs;
1021 switch (f->type)
1022 {
1023 case f_None:
1024 break;
1025 case f_Solid:
1026 if (cxform) {
1027 f->color = cxform->getColor(f->color);
1028 }
1029 f->color.pixel = gd->allocColor(f->color);
1030 break;
1031 case f_LinearGradient:
1032 case f_RadialGradient:
1033 {
1034 Matrix mat;
1035 int n,r,l;
1036 long red, green, blue, alpha;
1037 long dRed, dGreen, dBlue, dAlpha;
1038 long min,max;
1039 Matrix *m;
1040
1041 mat = *(matrix) * f->matrix;
1042 // Compute inverted matrix
1043 f->gradient.imat = mat.invert();
1044
1045 /* renormalize the matrix */
1046 m=&f->gradient.imat;
1047 if (f->type == f_LinearGradient) {
1048 m->a = m->a * FRAC * (1/128.0) * 65536.0;
1049 m->b = m->b * FRAC * (1/128.0) * 65536.0;
1050 m->tx = (long) ((m->tx + 16384) * (1/128.0) * 65536.0);
1051 } else {
1052 m->a = m->a * FRAC * (1/64.0) * 65536.0;
1053 m->b = m->b * FRAC * (1/64.0) * 65536.0;
1054 m->c = m->c * FRAC * (1/64.0) * 65536.0;
1055 m->d = m->d * FRAC * (1/64.0) * 65536.0;
1056 m->tx = (long) (m->tx * (1/64.0) * 65536.0);
1057 m->ty = (long) (m->ty * (1/64.0) * 65536.0);
1058 }
1059
1060 // Reset translation in inverted matrix
1061 f->gradient.has_alpha = 0;
1062
1063 // Build a 256 color ramp
1064 f->gradient.ramp = new Color[256];
1065 if (f->gradient.ramp == NULL) {
1066 // Invalidate fill style
1067 f->type = f_None;
1068 continue;
1069 }
1070
1071 // Store min and max
1072 min = f->gradient.ratio[0];
1073 max = f->gradient.ratio[f->gradient.nbGradients-1];
1074 for(r=0; r < f->gradient.nbGradients-1; r++)
1075 {
1076 Color start,end;
1077
1078 l = f->gradient.ratio[r+1]-f->gradient.ratio[r];
1079 if (l == 0) continue;
1080
1081 if (cxform) {
1082 start = cxform->getColor(f->gradient.color[r]);
1083 end = cxform->getColor(f->gradient.color[r+1]);
1084 } else {
1085 start = f->gradient.color[r];
1086 end = f->gradient.color[r+1];
1087 }
1088
1089 if (start.alpha != ALPHA_OPAQUE ||
1090 end.alpha != ALPHA_OPAQUE) {
1091 f->gradient.has_alpha = 1;
1092 }
1093
1094 dRed = end.red - start.red;
1095 dGreen = end.green - start.green;
1096 dBlue = end.blue - start.blue;
1097 dAlpha = end.alpha - start.alpha;
1098
1099 dRed = (dRed<<16)/l;
1100 dGreen = (dGreen<<16)/l;
1101 dBlue = (dBlue<<16)/l;
1102 dAlpha = (dAlpha<<16)/l;
1103
1104 red = start.red <<16;
1105 green = start.green <<16;
1106 blue = start.blue <<16;
1107 alpha = start.alpha <<16;
1108
1109 for (n=f->gradient.ratio[r]; n<=f->gradient.ratio[r+1]; n++) {
1110 f->gradient.ramp[n].red = red>>16;
1111 f->gradient.ramp[n].green = green>>16;
1112 f->gradient.ramp[n].blue = blue>>16;
1113 f->gradient.ramp[n].alpha = alpha>>16;
1114
1115 f->gradient.ramp[n].pixel = gd->allocColor(f->gradient.ramp[n]);
1116 red += dRed;
1117 green += dGreen;
1118 blue += dBlue;
1119 alpha += dAlpha;
1120 }
1121 }
1122 for(n=0; n<min; n++) {
1123 f->gradient.ramp[n] = f->gradient.ramp[min];
1124 }
1125 for(n=max; n<256; n++) {
1126 f->gradient.ramp[n] = f->gradient.ramp[max];
1127 }
1128 }
1129 break;
1130 case f_TiledBitmap:
1131 case f_clippedBitmap:
1132 if (f->bitmap) {
1133 Matrix *m;
1134
1135 f->cmap = gd->getColormap(f->bitmap->colormap,
1136 f->bitmap->nbColors, cxform);
1137 if (f->cmap == NULL) {
1138 /* Get the normal cmap anyway */
1139 f->cmap = f->bitmap->colormap;
1140 }
1141
1142 f->bitmap_matrix = *(matrix) * f->matrix;
1143
1144 f->bitmap_matrix = f->bitmap_matrix.invert();
1145
1146 m=&f->bitmap_matrix;
1147 m->a = m->a * FRAC * 65536.0;
1148 m->b = m->b * FRAC * 65536.0;
1149 m->c = m->c * FRAC * 65536.0;
1150 m->d = m->d * FRAC * 65536.0;
1151 m->tx = (long) (m->tx * 65536.0);
1152 m->ty = (long) (m->ty * 65536.0);
1153
1154 f->alpha_table = NULL;
1155
1156 if (f->bitmap->alpha_buf && cxform) {
1157 unsigned char *alpha_table;
1158 int i;
1159
1160 alpha_table = (unsigned char *)malloc (256);
1161 if (alpha_table != NULL) {
1162 for(i=0;i<256;i++) {
1163 alpha_table[i] = cxform->getAlpha(i);
1164 }
1165 }
1166 f->alpha_table = alpha_table;
1167 }
1168 }
1169 break;
1170 }
1171 }
1172}
1173
1174static void
1175clearStyles(GraphicDevice *gd, FillStyleDef *ftab, long n)
1176{
1177 long fs;
1178 FillStyleDef *f;
1179
1180 for(fs = 0; fs < n; fs++)
1181 {
1182 f = ftab + fs;
1183 switch (f->type)
1184 {
1185 case f_Solid:
1186 break;
1187 case f_LinearGradient:
1188 case f_RadialGradient:
1189 if (f->gradient.ramp) {
1190 delete f->gradient.ramp;
1191 }
1192 break;
1193 case f_TiledBitmap:
1194 case f_clippedBitmap:
1195 if (f->bitmap) {
1196 if (f->cmap && f->cmap != f->bitmap->colormap) delete f->cmap;
1197 if (f->alpha_table) free(f->alpha_table);
1198 }
1199 break;
1200 case f_None:
1201 break;
1202 }
1203 }
1204}
1205
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 @@
1/////////////////////////////////////////////////////////////
2// Flash Plugin and Player
3// Copyright (C) 1998,1999 Olivier Debon
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19///////////////////////////////////////////////////////////////
20#ifndef _SHAPE_H_
21#define _SHAPE_H_
22
23struct LineStyleDef {
24 long width;
25 Color color;
26 FillStyleDef fillstyle;
27};
28
29enum ShapeRecordType {
30 shapeNonEdge,
31 shapeCurve,
32 shapeLine
33};
34
35enum ShapeFlags {
36 flagsMoveTo = 0x01,
37 flagsFill0 = 0x02,
38 flagsFill1 = 0x04,
39 flagsLine = 0x08,
40 flagsNewStyles = 0x10,
41 flagsEndShape = 0x80
42};
43
44struct ShapeRecord {
45 ShapeRecordType type;
46
47 // Non Edge
48 ShapeFlags flags;
49 long x,y;// Moveto
50 long fillStyle0;
51 long fillStyle1;
52 long lineStyle;
53 FillStyleDef*newFillStyles; // Array
54 long nbNewFillStyles;
55 LineStyleDef*newLineStyles; // Array
56 long nbNewLineStyles;
57
58 // Curve Edge
59 long ctrlX, ctrlY;
60 long anchorX, anchorY;
61
62 // Straight Line
63 long dX,dY;
64
65 struct ShapeRecord *next;
66
67 ShapeRecord() {
68 shaperecord_size += sizeof(ShapeRecord);
69 shaperecord_nb++;
70 }
71
72};
73
74enum ShapeAction {
75 ShapeDraw,
76 ShapeGetRegion
77};
78
79struct LineSegment {
80 long x1,y1,x2,y2;
81 char first;
82 LineStyleDef *l;
83 struct LineSegment *next;
84};
85
86struct Path {
87 long lastX,lastY;
88 int nb_edges;
89 int nb_segments;
90};
91
92struct StyleList {
93 FillStyleDef*newFillStyles; // Array
94 long nbNewFillStyles;
95 LineStyleDef*newLineStyles; // Array
96 long nbNewLineStyles;
97
98 StyleList *next;
99};
100
101
102/* fast bit parser */
103struct BitParser {
104 // Bit Handling
105 S32 m_bitPos;
106 U32 m_bitBuf;
107
108 U8 *ptr;
109};
110
111class Shape;
112
113/* state of the shape parser */
114struct ShapeParser {
115 Dict *dict; /* XXX: should be put elsewhere */
116
117 BitParser bit_parser;
118 S32 m_nFillBits;
119 S32 m_nLineBits;
120
121 StyleList *style_list;
122 Matrix *matrix;
123 Path curPath;
124 int reverse;
125
126 /* line rasteriser */
127 LineSegment *first_line,*last_line;
128 GraphicDevice *gd;
129 Cxform *cxform;
130 Shape *shape;
131
132 FillStyleDef *f0;
133 FillStyleDef *f1;
134 LineStyleDef *l;
135};
136
137class Shape : public Character {
138 public:
139 int defLevel; // 1,2 or 3
140
141
142 Rect boundary;
143 FillStyleDef defaultFillStyle;
144 LineStyleDef defaultLineStyle;
145
146 Matrix lastMat;
147 /* parsing for the rendering stage (saves a lot of memory &
148 may not reduce significantly the size). These variables
149 should be in another structure (no state need to be
150 maintained between two renderings) */
151 int getAlpha, getStyles;
152 unsigned char *file_ptr;
153 Dict *dict; /* XXX: should be put elsewhere */
154
155protected:
156 void drawLines(GraphicDevice *gd, Matrix *matrix, Cxform *cxform, long, long);
157 void buildSegmentList(Segment **segs, int height, long &n, Matrix *matrix, int update, int reverse);
158 Segment *progressSegments(Segment *, long);
159 Segment *newSegments(Segment *, Segment *);
160
161public:
162 Shape(long id = 0 , int level = 1);
163 ~Shape();
164
165 void setBoundingBox(Rect rect);
166 int execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform);
167 void getRegion(GraphicDevice *gd, Matrix *matrix,
168 void *id, ScanLineFunc scan_line_func);
169
170 void getBoundingBox(Rect *bb, DisplayListEntry *);
171
172#ifdef DUMP
173 void dump(BitStream *bs);
174 void dumpShapeRecords(BitStream *bs, int alpha);
175 void dumpFillStyles(BitStream *bs, FillStyleDef *defs, long n, int alpha);
176 void dumpLineStyles(BitStream *bs, LineStyleDef *defs, long n, int alpha);
177 void checkBitmaps(BitStream *bs);
178#endif
179};
180
181#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 @@
1/////////////////////////////////////////////////////////////
2// Flash Plugin and Player
3// Copyright (C) 1998,1999 Olivier Debon
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19///////////////////////////////////////////////////////////////
20// Author : Olivier Debon <odebon@club-internet.fr>
21//
22
23#include "swf.h"
24
25#include <unistd.h>
26#include <fcntl.h>
27#include <sys/ioctl.h>
28#ifndef NOSOUND
29#include <linux/soundcard.h>
30#endif
31
32#ifdef RCSID
33static char *rcsid = "$Id$";
34#endif
35
36#define PRINT 0
37
38//////////// SOUND
39
40Sound::Sound(long id) : Character(SoundType, id)
41{
42 samples = 0;
43 stereo = 0;
44 soundRate = 0;
45 sampleSize = 1;
46}
47
48Sound::~Sound()
49{
50 if (samples) {
51 delete samples;
52 }
53}
54
55void
56Sound::setSoundFlags(long f) {
57 switch (GET_SOUND_RATE_CODE(f)) {
58 case 0:
59 soundRate = 5500;
60 break;
61 case 1:
62 soundRate = 11000;
63 break;
64 case 2:
65 soundRate = 22000;
66 break;
67 case 3:
68 soundRate = 44000;
69 break;
70 }
71 if (f & soundIs16bit) {
72 sampleSize = 2;
73 }
74 if (f & soundIsStereo) {
75 stereo = 1;
76 }
77
78#if PRINT
79 printf("-----\nFlags = %2x\n", f);
80 printf("Rate = %d kHz ", soundRate);
81 printf("SampleSize = %d byte(s) ", sampleSize);
82 if (f & soundIsStereo) {
83 printf("Stereo ");
84 } else {
85 printf("Mono ");
86 }
87 if (f & soundIsADPCMCompressed) {
88 printf("ADPCM\n");
89 } else {
90 printf("Raw\n");
91 }
92#endif
93}
94
95char *
96Sound::setNbSamples(long n) {
97 long size;
98
99 nbSamples = n;
100
101 size = nbSamples * (stereo ? 2 : 1) * sampleSize;
102
103 samples = new char[ size ];
104
105 memset((char *)samples,0, size);
106
107 return samples;
108}
109
110long
111Sound::getRate() {
112 return soundRate;
113}
114
115long
116Sound::getChannel() {
117 return stereo ? 2 : 1;
118}
119
120long
121Sound::getNbSamples() {
122 return nbSamples;
123}
124
125long
126Sound::getSampleSize() {
127 return sampleSize;
128}
129
130char *
131Sound::getSamples() {
132 return samples;
133}
134
135//////////// SOUND MIXER
136
137 long SoundMixer::dsp = -1;// Init of descriptor
138 long SoundMixer::blockSize = 0;// Driver sound buffer size
139 long SoundMixer::nbInst = 0;// Nb SoundMixer instances
140long SoundMixer::sampleSize = 0;
141long SoundMixer::stereo = 0;
142long SoundMixer::soundRate = 0;
143char *SoundMixer::buffer = 0;
144
145SoundMixer::SoundMixer(char *device)
146{
147#ifndef NOSOUND
148 int status;
149 long fmt;
150
151 list = 0;// No sound to play
152
153 if (nbInst++) {
154 // Device is already open
155 return;
156 }
157
158 dsp = open(device,O_WRONLY);
159 if (dsp < 0) {
160 perror("open dsp");
161 return;
162 }
163
164 // Reset device
165 status = ioctl(dsp, SNDCTL_DSP_RESET);
166 if (status < 0) perror("ioctl SNDCTL_DSP_RESET");
167
168 // Set sample size
169 fmt = AFMT_S16_LE;
170 sampleSize = 2;
171 status = ioctl(dsp, SNDCTL_DSP_SETFMT, &fmt);
172 if (status < 0) perror("ioctl SNDCTL_DSP_SETFMT");
173
174 if (status) {
175 fmt = AFMT_U8;
176 sampleSize = 1;
177 status = ioctl(dsp, SNDCTL_DSP_SETFMT, &fmt);
178 if (status < 0) perror("ioctl SNDCTL_DSP_SETFMT");
179 }
180
181 // Set stereo channel
182 stereo = 1;
183 status = ioctl(dsp, SNDCTL_DSP_STEREO, &stereo);
184
185 if (status) {
186 stereo = 0;
187 }
188
189 // Set sound rate in Hertz
190 soundRate = 11000;
191 status = ioctl(dsp, SNDCTL_DSP_SPEED, &soundRate);
192 if (status < 0) perror("ioctl SNDCTL_DSP_SPEED");
193
194 // Get device buffer size
195 status = ioctl(dsp, SNDCTL_DSP_GETBLKSIZE, &blockSize);
196 if (status < 0) perror("ioctl SNDCTL_DSP_GETBLKSIZE");
197 if (blockSize < 1024) {
198 blockSize = 32768;
199 }
200 blockSize *= 2;
201
202 buffer = (char *)malloc(blockSize);
203 if (buffer == 0) {
204 close(dsp);
205 dsp = -1;
206 }
207
208#if PRINT
209 int caps;
210
211 ioctl(dsp,SNDCTL_DSP_GETCAPS, &caps);
212 printf("Audio capabilities = %x\n", caps);
213 printf("Sound Rate = %d\n", soundRate);
214 printf("Stereo = %d\n", stereo);
215 printf("Sample Size = %d\n", sampleSize);
216 printf("Buffer Size = %d\n", blockSize);
217#endif /* PRINT */
218
219 #endif/* NOSOUND */
220}
221
222SoundMixer::~SoundMixer()
223{
224 if (--nbInst == 0) {
225 if (dsp > 0) {
226 close(dsp);
227 free(buffer);
228 }
229 }
230}
231
232void
233SoundMixer::stopSounds()
234{
235#ifndef NOSOUND
236 SoundList *sl,*del;
237
238 for(sl = list; sl; ) {
239 del = sl;
240 sl = sl->next;
241 delete del;
242 }
243 list = 0;
244#endif
245}
246
247void
248SoundMixer::startSound(Sound *sound)
249{
250#ifndef NOSOUND
251 SoundList *sl;
252
253 if (sound) {
254 // Add sound in list
255 sl = new SoundList;
256 sl->rate = sound->getRate();
257 sl->stereo = (sound->getChannel() == 2);
258 sl->sampleSize = sound->getSampleSize();
259 sl->current = sound->getSamples();
260 sl->remaining = sound->getSampleSize()*sound->getNbSamples()*sound->getChannel();
261 sl->next = list;
262 list = sl;
263 }
264#endif
265}
266
267long
268SoundMixer::playSounds()
269{
270#ifndef NOSOUND
271 audio_buf_info bufInfo;
272 long nbBytes, n;
273 SoundList*sl,*prev;
274 int status;
275
276 // Init failed
277 if (dsp < 0) return 0;
278
279 // No sound to play
280 if (list == 0) return 0;
281
282 // Get free DMA buffer space
283 status = ioctl(dsp, SNDCTL_DSP_GETOSPACE, &bufInfo);
284
285 // Free space is not large enough to output data without blocking
286 // But there are still sounds to play. We must wait.
287 if (bufInfo.bytes < blockSize) return 1;
288
289 nbBytes = 0;
290
291 // Fill buffer with silence.
292 memset((void*)buffer, 0, blockSize);
293
294 prev = 0;
295 sl = list;
296 while(sl) {
297
298 // Ask sound to fill the buffer
299 // according to device capabilities
300 n = fillSoundBuffer(sl, buffer, blockSize);
301
302 // Remember the largest written size
303 if (n > nbBytes) {
304 nbBytes = n;
305 }
306
307 // No more samples for this sound
308 if (sl->remaining == 0) {
309 // Remove sound from list
310 if (prev) {
311 prev->next = sl->next;
312 delete sl;
313 sl = prev->next;
314 } else {
315 list = sl->next;
316 delete sl;
317 sl = list;
318 }
319 } else {
320 sl = sl->next;
321 }
322 }
323
324 if (nbBytes) {
325 // At last ! Play It !
326 write(dsp,buffer,nbBytes);
327 status = ioctl(dsp, SNDCTL_DSP_POST);
328 }
329
330 return nbBytes;
331#else
332 return 0;
333#endif
334}
335
336long
337SoundMixer::fillSoundBuffer(SoundList *sl, char *buff, long buffSize)
338{
339 long sampleLeft, sampleRight;
340 long skipOut, skipOutInit;
341 long skipIn, skipInInit;
342 long freqRatio;
343 long totalOut = 0;
344
345 sampleLeft = sampleRight = 0;
346 skipOutInit = skipInInit = 0;
347
348 freqRatio = sl->rate / soundRate;
349 if (freqRatio) {
350 skipOutInit = freqRatio - 1;
351 skipInInit = 0;
352 }
353
354 freqRatio = soundRate / sl->rate;
355 if (freqRatio) {
356 skipInInit = freqRatio - 1;
357 skipOutInit = 0;
358 }
359
360 skipOut = skipOutInit;
361 skipIn = skipInInit;
362 while (buffSize && sl->remaining) {
363 if (skipIn-- == 0) {
364 // Get sampleLeft
365 if (sl->sampleSize == 2) {
366 sampleLeft = (long)(*(short *)(sl->current));
367 if (sampleSize == 1) {
368 sampleLeft = (sampleLeft >> 8) &0xff;
369 }
370 } else {
371 sampleLeft = (long)*(sl->current);
372 if (sampleSize == 2) {
373 sampleLeft <<= 8;
374 }
375 }
376 sl->current += sl->sampleSize;
377 sl->remaining -= sl->sampleSize;
378
379 if (sl->stereo) {
380 // Get sampleRight
381 if (sl->sampleSize == 2) {
382 sampleRight = (long)(*(short *)(sl->current));
383 if (sampleSize == 1) {
384 sampleRight = (sampleRight >> 8) &0xff;
385 }
386 } else {
387 sampleRight = (long)*(sl->current);
388 if (sampleSize == 2) {
389 sampleRight <<= 8;
390 }
391 }
392 sl->current += sl->sampleSize;
393 sl->remaining -= sl->sampleSize;
394
395 } else {
396 sampleRight = sampleLeft;
397 }
398
399 skipIn = skipInInit;
400 }
401
402 if (skipOut-- == 0) {
403 // Output
404 if (stereo) {
405 if (sampleSize == 2) {
406 *((short *)buff) += sampleLeft/2;
407 buffSize -= sampleSize;
408 buff += sampleSize;
409 *((short *)buff) += sampleRight/2;
410 buffSize -= sampleSize;
411 buff += sampleSize;
412 } else {
413 *((char *)buff) += sampleLeft/2;
414 buffSize -= sampleSize;
415 buff += sampleSize;
416 *((char *)buff) += sampleRight/2;
417 buffSize -= sampleSize;
418 buff += sampleSize;
419 }
420 totalOut += 2*sampleSize;
421 } else {
422 if (sampleSize == 2) {
423 *((short *)buff) += (sampleLeft+sampleRight)>>2;
424 buffSize -= sampleSize;
425 buff += sampleSize;
426 } else {
427 *((char *)buff) += (sampleLeft+sampleRight)>>2;
428 buffSize -= sampleSize;
429 buff += sampleSize;
430 }
431 totalOut += sampleSize;
432 }
433
434 skipOut = skipOutInit;
435 }
436 }
437
438 return totalOut;
439}
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 @@
1/////////////////////////////////////////////////////////////
2// Flash Plugin and Player
3// Copyright (C) 1998 Olivier Debon
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19///////////////////////////////////////////////////////////////
20#ifndef _SOUND_H_
21#define _SOUND_H_
22
23#define GET_SOUND_RATE_CODE(f) (((f)&0x0c)>>2)
24
25class Sound : public Character {
26 long soundRate;// In hz
27 long stereo;// True if stereo sound
28 long sampleSize;// 1 or 2 bytes
29
30 char *samples; // Array of samples
31 long nbSamples;
32
33public:
34 Sound(long id);
35 ~Sound();
36 void setSoundFlags(long f);
37 char *setNbSamples(long n);
38
39 long getRate();
40 long getChannel();
41 long getNbSamples();
42 long getSampleSize();
43 char *getSamples();
44};
45
46struct SoundList {
47 long rate;
48 long stereo;
49 long sampleSize;
50 long nbSamples;
51 long remaining;
52 char*current;
53
54 SoundList *next;
55};
56
57class SoundMixer {
58
59 SoundList*list;
60
61// Class variables
62 static long dsp; // Descriptor for /dev/dsp
63 static char * buffer;// DMA buffer
64 static long blockSize;
65 static long nbInst;// Number of instances
66
67 // Sound Device Capabilities
68 static long soundRate;// In hz
69 static long stereo;// True if stereo sound
70 static long sampleSize;// 1 or 2 bytes
71
72public:
73 SoundMixer(char*);
74 ~SoundMixer();
75
76 void startSound(Sound *sound);// Register a sound to be played
77 void stopSounds(); // Stop every current sounds in the instance
78
79 long playSounds(); // Actually play sounds of all instances
80 long fillSoundBuffer(SoundList *, char *buffer, long bufferSize); // Fill sound buffer
81};
82
83#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 @@
1/////////////////////////////////////////////////////////////
2// Flash Plugin and Player
3// Copyright (C) 1998,1999 Olivier Debon
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19///////////////////////////////////////////////////////////////
20// Author : Olivier Debon <odebon@club-internet.fr>
21//
22
23#include "swf.h"
24
25#ifdef RCSID
26static char *rcsid = "$Id$";
27#endif
28
29Sprite::Sprite(FlashMovie *movie, long id, long frameCount) : Character(SpriteType, id)
30{
31 program = new Program(movie, frameCount);
32 if (program == NULL) return;
33 if (program->totalFrames == 0) {
34 delete program;
35 program = NULL;
36 return;
37 }
38 program->dl->isSprite = 1;
39}
40
41Sprite::~Sprite()
42{
43 delete program;
44}
45
46void
47Sprite::reset()
48{
49 program->rewindMovie();
50}
51
52int
53Sprite::isSprite(void)
54{
55 return 1;
56}
57
58Program *
59Sprite::getProgram()
60{
61 return program;
62}
63
64int
65Sprite::execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform)
66{
67 return program->dl->render(gd,matrix,cxform);
68}
69
70ActionRecord *
71Sprite::eventHandler(GraphicDevice *gd, FlashEvent *event)
72{
73#if 0
74 DisplayList *dl;
75 ActionRecord *actions;
76
77 dl = program->getDisplayList();
78 actions = dl->processEvent(gd, event);
79 if (actions) {
80 program->doAction(actions,0);
81 }
82 return actions;
83#endif
84 return NULL;
85}
86
87void
88Sprite::getBoundingBox(Rect *bb, DisplayListEntry *e)
89{
90 program->dl->getBoundary(bb);
91}
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 @@
1/////////////////////////////////////////////////////////////
2// Flash Plugin and Player
3// Copyright (C) 1998 Olivier Debon
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19///////////////////////////////////////////////////////////////
20#ifndef _SPRITE_H_
21#define _SPRITE_H_
22
23class Sprite : public Character {
24public:
25 Program *program;
26
27 Sprite(FlashMovie *movie, long id, long frameCount);
28 ~Sprite();
29 Program *getProgram();
30 int execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform);
31 int hasEventHandler();
32 void reset();
33 ActionRecord*eventHandler(GraphicDevice *, FlashEvent *);
34 int isSprite(void);
35 void getBoundingBox(Rect *bb, DisplayListEntry *de);
36};
37
38#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 @@
1unsigned char SQRT[] = {
2
30,1,1,1,2,2,2,2,2,3,3,3,3,3,3,3,
44,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,
55,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,
66,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
78,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
88,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
99,9,9,9,10,10,10,10,10,10,10,10,10,10,10,10,
1010,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,
1111,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
1212,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
1312,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,
1413,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
1513,13,13,13,14,14,14,14,14,14,14,14,14,14,14,14,
1614,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
1714,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
1815,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
1916,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
2016,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
2116,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
2217,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
2317,17,17,17,18,18,18,18,18,18,18,18,18,18,18,18,
2418,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
2518,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,
2619,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
2719,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
2820,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
2920,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
3020,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21,
3121,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
3221,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
3321,21,21,21,22,22,22,22,22,22,22,22,22,22,22,22,
3422,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,
3522,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,
3622,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
3723,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
3823,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
3924,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,
4024,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,
4124,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,
4224,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
4325,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
4425,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
4525,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,
4626,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,
4726,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,
4826,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,
4927,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,
5027,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,
5127,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,
5228,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,
5328,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,
5428,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,
5528,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,
5629,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,
5729,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,
5829,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,
5929,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,
6030,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,
6130,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,
6230,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,
6330,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
6431,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
6531,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
6631,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
6732,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
6832,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
6932,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
7032,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
7132,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,
7233,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,
7333,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,
7433,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,
7533,33,33,33,34,34,34,34,34,34,34,34,34,34,34,34,
7634,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,
7734,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,
7834,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,
7934,34,34,34,34,34,34,34,34,35,35,35,35,35,35,35,
8035,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,
8135,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,
8235,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,
8335,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,
8436,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,
8536,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,
8636,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,
8736,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,
8836,36,36,36,36,36,36,36,36,37,37,37,37,37,37,37,
8937,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,
9037,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,
9137,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,
9237,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,
9337,37,37,37,38,38,38,38,38,38,38,38,38,38,38,38,
9438,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,
9538,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,
9638,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,
9738,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,
9838,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
9939,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
10039,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
10139,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
10239,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
10340,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,
10440,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,
10540,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,
10640,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,
10740,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,
10840,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,
10941,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,
11041,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,
11141,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,
11241,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,
11341,41,41,41,42,42,42,42,42,42,42,42,42,42,42,42,
11442,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,
11542,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,
11642,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,
11742,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,
11842,42,42,42,42,42,42,42,42,43,43,43,43,43,43,43,
11943,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,
12043,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,
12143,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,
12243,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,
12343,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,
12444,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,
12544,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,
12644,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,
12744,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,
12844,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,
12944,44,44,44,44,44,44,44,44,45,45,45,45,45,45,45,
13045,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,
13145,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,
13245,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,
13345,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,
13445,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,
13545,45,45,45,46,46,46,46,46,46,46,46,46,46,46,46,
13646,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,
13746,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,
13846,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,
13946,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,
14046,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,
14146,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
14247,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
14347,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
14447,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
14547,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
14647,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
14748,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,
14848,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,
14948,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,
15048,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,
15148,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,
15248,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,
15348,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,
15449,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,
15549,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,
15649,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,
15749,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,
15849,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,
15949,49,49,49,50,50,50,50,50,50,50,50,50,50,50,50,
16050,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
16150,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
16250,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
16350,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
16450,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
16550,50,50,50,50,50,50,50,50,51,51,51,51,51,51,51,
16651,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
16751,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
16851,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
16951,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
17051,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
17151,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
17252,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,
17352,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,
17452,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,
17552,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,
17652,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,
17752,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,
17852,52,52,52,52,52,52,52,52,53,53,53,53,53,53,53,
17953,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,
18053,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,
18153,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,
18253,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,
18353,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,
18453,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,
18553,53,53,53,54,54,54,54,54,54,54,54,54,54,54,54,
18654,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,
18754,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,
18854,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,
18954,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,
19054,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,
19154,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,
19254,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,
19355,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,
19455,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,
19555,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,
19655,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,
19755,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,
19855,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,
19956,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,
20056,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,
20156,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,
20256,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,
20356,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,
20456,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,
20556,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,
20656,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,
20757,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,
20857,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,
20957,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,
21057,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,
21157,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,
21257,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,
21357,57,57,57,58,58,58,58,58,58,58,58,58,58,58,58,
21458,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,
21558,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,
21658,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,
21758,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,
21858,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,
21958,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,
22058,58,58,58,58,58,58,58,58,59,59,59,59,59,59,59,
22159,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,
22259,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,
22359,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,
22459,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,
22559,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,
22659,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,
22759,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,
22860,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,
22960,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,
23060,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,
23160,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,
23260,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,
23360,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,
23460,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,
23560,60,60,60,60,60,60,60,60,61,61,61,61,61,61,61,
23661,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,
23761,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,
23861,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,
23961,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,
24061,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,
24161,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,
24261,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,
24361,61,61,61,62,62,62,62,62,62,62,62,62,62,62,62,
24462,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,
24562,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,
24662,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,
24762,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,
24862,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,
24962,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,
25062,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,
25162,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,
25263,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,
25363,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,
25463,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,
25563,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,
25663,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,
25763,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,
25863,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,
25964,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
26064,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
26164,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
26264,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
26364,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
26464,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
26564,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
26664,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
26764,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,
26865,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,
26965,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,
27065,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,
27165,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,
27265,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,
27365,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,
27465,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,
27565,65,65,65,66,66,66,66,66,66,66,66,66,66,66,66,
27666,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,
27766,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,
27866,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,
27966,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,
28066,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,
28166,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,
28266,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,
28366,66,66,66,66,66,66,66,66,67,67,67,67,67,67,67,
28467,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,
28567,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,
28667,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,
28767,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,
28867,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,
28967,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,
29067,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,
29167,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,
29268,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,
29368,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,
29468,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,
29568,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,
29668,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,
29768,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,
29868,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,
29968,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,
30068,68,68,68,68,68,68,68,68,69,69,69,69,69,69,69,
30169,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,
30269,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,
30369,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,
30469,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,
30569,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,
30669,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,
30769,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,
30869,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,
30969,69,69,69,70,70,70,70,70,70,70,70,70,70,70,70,
31070,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,
31170,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,
31270,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,
31370,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,
31470,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,
31570,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,
31670,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,
31770,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,
31870,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,
31971,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,
32071,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,
32171,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,
32271,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,
32371,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,
32471,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,
32571,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,
32671,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,
32772,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,
32872,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,
32972,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,
33072,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,
33172,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,
33272,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,
33372,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,
33472,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,
33572,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,
33672,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,
33773,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,
33873,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,
33973,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,
34073,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,
34173,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,
34273,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,
34373,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,
34473,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,
34573,73,73,73,74,74,74,74,74,74,74,74,74,74,74,74,
34674,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,
34774,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,
34874,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,
34974,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,
35074,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,
35174,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,
35274,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,
35374,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,
35474,74,74,74,74,74,74,74,74,75,75,75,75,75,75,75,
35575,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,
35675,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,
35775,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,
35875,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,
35975,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,
36075,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,
36175,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,
36275,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,
36375,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,
36476,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
36576,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
36676,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
36776,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
36876,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
36976,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
37076,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
37176,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
37276,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
37376,76,76,76,76,76,76,76,76,77,77,77,77,77,77,77,
37477,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
37577,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
37677,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
37777,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
37877,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
37977,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
38077,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
38177,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
38277,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
38377,77,77,77,78,78,78,78,78,78,78,78,78,78,78,78,
38478,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,
38578,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,
38678,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,
38778,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,
38878,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,
38978,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,
39078,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,
39178,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,
39278,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,
39378,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,
39479,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,
39579,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,
39679,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,
39779,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,
39879,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,
39979,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,
40079,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,
40179,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,
40279,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,
40380,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
40480,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
40580,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
40680,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
40780,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
40880,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
40980,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
41080,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
41180,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
41280,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
41380,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
41481,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
41581,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
41681,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
41781,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
41881,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
41981,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
42081,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
42181,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
42281,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
42381,81,81,81,82,82,82,82,82,82,82,82,82,82,82,82,
42482,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
42582,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
42682,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
42782,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
42882,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
42982,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
43082,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
43182,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
43282,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
43382,82,82,82,82,82,82,82,82,83,83,83,83,83,83,83,
43483,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,
43583,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,
43683,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,
43783,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,
43883,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,
43983,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,
44083,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,
44183,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,
44283,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,
44383,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,
44484,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
44584,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
44684,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
44784,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
44884,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
44984,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
45084,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
45184,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
45284,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
45384,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
45484,84,84,84,84,84,84,84,84,85,85,85,85,85,85,85,
45585,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
45685,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
45785,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
45885,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
45985,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
46085,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
46185,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
46285,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
46385,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
46485,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
46585,85,85,85,86,86,86,86,86,86,86,86,86,86,86,86,
46686,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,
46786,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,
46886,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,
46986,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,
47086,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,
47186,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,
47286,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,
47386,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,
47486,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,
47586,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,
47686,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,
47787,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,
47887,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,
47987,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,
48087,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,
48187,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,
48287,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,
48387,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,
48487,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,
48587,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,
48687,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,
48788,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,
48888,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,
48988,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,
49088,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,
49188,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,
49288,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,
49388,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,
49488,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,
49588,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,
49688,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,
49788,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,
49888,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,
49989,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,
50089,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,
50189,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,
50289,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,
50389,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,
50489,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,
50589,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,
50689,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,
50789,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,
50889,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,
50989,89,89,89,90,90,90,90,90,90,90,90,90,90,90,90,
51090,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,
51190,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,
51290,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,
51390,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,
51490,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,
51590,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,
51690,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,
51790,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,
51890,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,
51990,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,
52090,90,90,90,90,90,90,90,90,91,91,91,91,91,91,91,
52191,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,
52291,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,
52391,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,
52491,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,
52591,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,
52691,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,
52791,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,
52891,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,
52991,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,
53091,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,
53191,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,
53292,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,
53392,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,
53492,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,
53592,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,
53692,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,
53792,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,
53892,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,
53992,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,
54092,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,
54192,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,
54292,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,
54392,92,92,92,92,92,92,92,92,93,93,93,93,93,93,93,
54493,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,
54593,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,
54693,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,
54793,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,
54893,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,
54993,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,
55093,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,
55193,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,
55293,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,
55393,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,
55493,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,
55593,93,93,93,94,94,94,94,94,94,94,94,94,94,94,94,
55694,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,
55794,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,
55894,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,
55994,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,
56094,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,
56194,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,
56294,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,
56394,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,
56494,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,
56594,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,
56694,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,
56794,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,
56895,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,
56995,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,
57095,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,
57195,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,
57295,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,
57395,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,
57495,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,
57595,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,
57695,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,
57795,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,
57895,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,
57996,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
58096,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
58196,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
58296,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
58396,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
58496,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
58596,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
58696,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
58796,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
58896,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
58996,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
59096,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
59196,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
59297,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
59397,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
59497,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
59597,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
59697,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
59797,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
59897,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
59997,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
60097,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
60197,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
60297,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
60397,97,97,97,98,98,98,98,98,98,98,98,98,98,98,98,
60498,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,
60598,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,
60698,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,
60798,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,
60898,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,
60998,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,
61098,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,
61198,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,
61298,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,
61398,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,
61498,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,
61598,98,98,98,98,98,98,98,98,99,99,99,99,99,99,99,
61699,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,
61799,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,
61899,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,
61999,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,
62099,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,
62199,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,
62299,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,
62399,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,
62499,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,
62599,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,
62699,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,
62799,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,
628100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
629100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
630100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
631100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
632100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
633100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
634100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
635100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
636100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
637100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
638100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
639100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
640100,100,100,100,100,100,100,100,100,101,101,101,101,101,101,101,
641101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
642101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
643101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
644101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
645101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
646101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
647101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
648101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
649101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
650101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
651101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
652101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
653101,101,101,101,102,102,102,102,102,102,102,102,102,102,102,102,
654102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,
655102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,
656102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,
657102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,
658102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,
659102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,
660102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,
661102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,
662102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,
663102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,
664102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,
665102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,
666102,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,
667103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,
668103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,
669103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,
670103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,
671103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,
672103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,
673103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,
674103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,
675103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,
676103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,
677103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,
678103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,
679104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
680104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
681104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
682104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
683104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
684104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
685104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
686104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
687104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
688104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
689104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
690104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
691104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
692104,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,
693105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,
694105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,
695105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,
696105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,
697105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,
698105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,
699105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,
700105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,
701105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,
702105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,
703105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,
704105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,
705105,105,105,105,106,106,106,106,106,106,106,106,106,106,106,106,
706106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,
707106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,
708106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,
709106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,
710106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,
711106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,
712106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,
713106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,
714106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,
715106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,
716106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,
717106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,
718106,106,106,106,106,106,106,106,106,107,107,107,107,107,107,107,
719107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,
720107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,
721107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,
722107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,
723107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,
724107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,
725107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,
726107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,
727107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,
728107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,
729107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,
730107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,
731107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,
732108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,
733108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,
734108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,
735108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,
736108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,
737108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,
738108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,
739108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,
740108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,
741108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,
742108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,
743108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,
744108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,
745108,108,108,108,108,108,108,108,108,109,109,109,109,109,109,109,
746109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
747109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
748109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
749109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
750109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
751109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
752109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
753109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
754109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
755109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
756109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
757109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
758109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
759109,109,109,109,110,110,110,110,110,110,110,110,110,110,110,110,
760110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
761110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
762110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
763110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
764110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
765110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
766110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
767110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
768110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
769110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
770110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
771110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
772110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
773110,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
774111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
775111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
776111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
777111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
778111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
779111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
780111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
781111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
782111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
783111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
784111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
785111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
786111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
787112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
788112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
789112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
790112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
791112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
792112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
793112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
794112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
795112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
796112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
797112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
798112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
799112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
800112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
801112,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
802113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
803113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
804113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
805113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
806113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
807113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
808113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
809113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
810113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
811113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
812113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
813113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
814113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
815113,113,113,113,114,114,114,114,114,114,114,114,114,114,114,114,
816114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,
817114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,
818114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,
819114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,
820114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,
821114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,
822114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,
823114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,
824114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,
825114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,
826114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,
827114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,
828114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,
829114,114,114,114,114,114,114,114,114,115,115,115,115,115,115,115,
830115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
831115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
832115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
833115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
834115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
835115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
836115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
837115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
838115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
839115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
840115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
841115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
842115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
843115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
844116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
845116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
846116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
847116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
848116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
849116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
850116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
851116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
852116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
853116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
854116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
855116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
856116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
857116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
858116,116,116,116,116,116,116,116,116,117,117,117,117,117,117,117,
859117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
860117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
861117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
862117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
863117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
864117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
865117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
866117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
867117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
868117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
869117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
870117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
871117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
872117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
873117,117,117,117,118,118,118,118,118,118,118,118,118,118,118,118,
874118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,
875118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,
876118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,
877118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,
878118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,
879118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,
880118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,
881118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,
882118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,
883118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,
884118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,
885118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,
886118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,
887118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,
888118,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
889119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
890119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
891119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
892119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
893119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
894119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
895119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
896119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
897119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
898119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
899119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
900119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
901119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
902119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
903120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
904120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
905120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
906120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
907120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
908120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
909120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
910120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
911120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
912120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
913120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
914120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
915120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
916120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
917120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
918120,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
919121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
920121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
921121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
922121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
923121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
924121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
925121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
926121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
927121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
928121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
929121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
930121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
931121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
932121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
933121,121,121,121,122,122,122,122,122,122,122,122,122,122,122,122,
934122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,
935122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,
936122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,
937122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,
938122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,
939122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,
940122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,
941122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,
942122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,
943122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,
944122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,
945122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,
946122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,
947122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,
948122,122,122,122,122,122,122,122,122,123,123,123,123,123,123,123,
949123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,
950123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,
951123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,
952123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,
953123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,
954123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,
955123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,
956123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,
957123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,
958123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,
959123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,
960123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,
961123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,
962123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,
963123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,
964124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
965124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
966124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
967124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
968124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
969124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
970124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
971124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
972124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
973124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
974124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
975124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
976124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
977124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
978124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
979124,124,124,124,124,124,124,124,124,125,125,125,125,125,125,125,
980125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
981125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
982125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
983125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
984125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
985125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
986125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
987125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
988125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
989125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
990125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
991125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
992125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
993125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
994125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
995125,125,125,125,126,126,126,126,126,126,126,126,126,126,126,126,
996126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,
997126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,
998126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,
999126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,
1000126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,
1001126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,
1002126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,
1003126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,
1004126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,
1005126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,
1006126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,
1007126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,
1008126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,
1009126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,
1010126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,
1011126,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
1012127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
1013127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
1014127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
1015127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
1016127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
1017127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
1018127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
1019127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
1020127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
1021127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
1022127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
1023127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
1024127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
1025127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
1026127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
1027128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
1028128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
1029128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
1030128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
1031128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
1032128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
1033128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
1034128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
1035128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
1036128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
1037128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
1038128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
1039128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
1040128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
1041128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
1042128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
1043128,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
1044129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
1045129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
1046129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
1047129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
1048129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
1049129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
1050129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
1051129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
1052129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
1053129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
1054129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
1055129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
1056129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
1057129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
1058129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
1059129,129,129,129,130,130,130,130,130,130,130,130,130,130,130,130,
1060130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,
1061130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,
1062130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,
1063130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,
1064130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,
1065130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,
1066130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,
1067130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,
1068130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,
1069130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,
1070130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,
1071130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,
1072130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,
1073130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,
1074130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,
1075130,130,130,130,130,130,130,130,130,131,131,131,131,131,131,131,
1076131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
1077131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
1078131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
1079131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
1080131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
1081131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
1082131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
1083131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
1084131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
1085131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
1086131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
1087131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
1088131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
1089131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
1090131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
1091131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
1092132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
1093132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
1094132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
1095132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
1096132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
1097132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
1098132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
1099132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
1100132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
1101132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
1102132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
1103132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
1104132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
1105132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
1106132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
1107132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
1108132,132,132,132,132,132,132,132,132,133,133,133,133,133,133,133,
1109133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
1110133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
1111133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
1112133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
1113133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
1114133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
1115133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
1116133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
1117133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
1118133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
1119133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
1120133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
1121133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
1122133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
1123133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
1124133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
1125133,133,133,133,134,134,134,134,134,134,134,134,134,134,134,134,
1126134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
1127134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
1128134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
1129134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
1130134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
1131134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
1132134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
1133134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
1134134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
1135134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
1136134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
1137134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
1138134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
1139134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
1140134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
1141134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
1142134,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
1143135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
1144135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
1145135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
1146135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
1147135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
1148135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
1149135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
1150135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
1151135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
1152135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
1153135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
1154135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
1155135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
1156135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
1157135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
1158135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
1159136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
1160136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
1161136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
1162136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
1163136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
1164136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
1165136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
1166136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
1167136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
1168136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
1169136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
1170136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
1171136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
1172136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
1173136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
1174136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
1175136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
1176136,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
1177137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
1178137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
1179137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
1180137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
1181137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
1182137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
1183137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
1184137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
1185137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
1186137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
1187137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
1188137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
1189137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
1190137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
1191137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
1192137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
1193137,137,137,137,138,138,138,138,138,138,138,138,138,138,138,138,
1194138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
1195138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
1196138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
1197138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
1198138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
1199138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
1200138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
1201138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
1202138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
1203138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
1204138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
1205138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
1206138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
1207138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
1208138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
1209138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
1210138,138,138,138,138,138,138,138,138,139,139,139,139,139,139,139,
1211139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,
1212139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,
1213139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,
1214139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,
1215139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,
1216139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,
1217139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,
1218139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,
1219139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,
1220139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,
1221139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,
1222139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,
1223139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,
1224139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,
1225139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,
1226139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,
1227139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,
1228140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
1229140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
1230140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
1231140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
1232140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
1233140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
1234140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
1235140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
1236140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
1237140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
1238140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
1239140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
1240140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
1241140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
1242140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
1243140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
1244140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
1245140,140,140,140,140,140,140,140,140,141,141,141,141,141,141,141,
1246141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
1247141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
1248141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
1249141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
1250141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
1251141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
1252141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
1253141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
1254141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
1255141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
1256141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
1257141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
1258141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
1259141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
1260141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
1261141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
1262141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
1263141,141,141,141,142,142,142,142,142,142,142,142,142,142,142,142,
1264142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
1265142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
1266142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
1267142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
1268142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
1269142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
1270142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
1271142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
1272142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
1273142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
1274142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
1275142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
1276142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
1277142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
1278142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
1279142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
1280142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
1281142,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
1282143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
1283143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
1284143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
1285143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
1286143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
1287143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
1288143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
1289143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
1290143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
1291143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
1292143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
1293143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
1294143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
1295143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
1296143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
1297143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
1298143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
1299144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
1300144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
1301144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
1302144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
1303144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
1304144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
1305144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
1306144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
1307144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
1308144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
1309144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
1310144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
1311144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
1312144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
1313144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
1314144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
1315144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
1316144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
1317144,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
1318145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
1319145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
1320145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
1321145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
1322145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
1323145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
1324145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
1325145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
1326145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
1327145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
1328145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
1329145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
1330145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
1331145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
1332145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
1333145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
1334145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
1335145,145,145,145,146,146,146,146,146,146,146,146,146,146,146,146,
1336146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,
1337146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,
1338146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,
1339146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,
1340146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,
1341146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,
1342146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,
1343146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,
1344146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,
1345146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,
1346146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,
1347146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,
1348146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,
1349146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,
1350146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,
1351146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,
1352146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,
1353146,146,146,146,146,146,146,146,146,147,147,147,147,147,147,147,
1354147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
1355147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
1356147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
1357147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
1358147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
1359147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
1360147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
1361147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
1362147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
1363147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
1364147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
1365147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
1366147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
1367147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
1368147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
1369147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
1370147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
1371147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
1372148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
1373148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
1374148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
1375148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
1376148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
1377148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
1378148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
1379148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
1380148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
1381148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
1382148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
1383148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
1384148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
1385148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
1386148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
1387148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
1388148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
1389148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
1390148,148,148,148,148,148,148,148,148,149,149,149,149,149,149,149,
1391149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
1392149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
1393149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
1394149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
1395149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
1396149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
1397149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
1398149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
1399149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
1400149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
1401149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
1402149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
1403149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
1404149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
1405149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
1406149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
1407149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
1408149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
1409149,149,149,149,150,150,150,150,150,150,150,150,150,150,150,150,
1410150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
1411150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
1412150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
1413150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
1414150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
1415150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
1416150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
1417150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
1418150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
1419150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
1420150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
1421150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
1422150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
1423150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
1424150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
1425150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
1426150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
1427150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
1428150,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
1429151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
1430151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
1431151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
1432151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
1433151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
1434151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
1435151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
1436151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
1437151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
1438151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
1439151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
1440151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
1441151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
1442151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
1443151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
1444151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
1445151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
1446151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
1447152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
1448152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
1449152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
1450152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
1451152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
1452152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
1453152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
1454152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
1455152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
1456152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
1457152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
1458152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
1459152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
1460152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
1461152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
1462152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
1463152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
1464152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
1465152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
1466152,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
1467153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
1468153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
1469153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
1470153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
1471153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
1472153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
1473153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
1474153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
1475153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
1476153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
1477153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
1478153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
1479153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
1480153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
1481153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
1482153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
1483153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
1484153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
1485153,153,153,153,154,154,154,154,154,154,154,154,154,154,154,154,
1486154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
1487154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
1488154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
1489154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
1490154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
1491154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
1492154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
1493154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
1494154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
1495154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
1496154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
1497154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
1498154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
1499154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
1500154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
1501154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
1502154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
1503154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
1504154,154,154,154,154,154,154,154,154,155,155,155,155,155,155,155,
1505155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
1506155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
1507155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
1508155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
1509155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
1510155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
1511155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
1512155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
1513155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
1514155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
1515155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
1516155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
1517155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
1518155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
1519155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
1520155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
1521155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
1522155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
1523155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
1524156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
1525156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
1526156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
1527156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
1528156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
1529156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
1530156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
1531156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
1532156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
1533156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
1534156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
1535156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
1536156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
1537156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
1538156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
1539156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
1540156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
1541156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
1542156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
1543156,156,156,156,156,156,156,156,156,157,157,157,157,157,157,157,
1544157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
1545157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
1546157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
1547157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
1548157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
1549157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
1550157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
1551157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
1552157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
1553157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
1554157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
1555157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
1556157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
1557157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
1558157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
1559157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
1560157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
1561157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
1562157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
1563157,157,157,157,158,158,158,158,158,158,158,158,158,158,158,158,
1564158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
1565158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
1566158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
1567158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
1568158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
1569158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
1570158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
1571158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
1572158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
1573158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
1574158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
1575158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
1576158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
1577158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
1578158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
1579158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
1580158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
1581158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
1582158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
1583158,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
1584159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
1585159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
1586159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
1587159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
1588159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
1589159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
1590159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
1591159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
1592159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
1593159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
1594159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
1595159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
1596159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
1597159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
1598159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
1599159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
1600159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
1601159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
1602159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
1603160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
1604160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
1605160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
1606160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
1607160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
1608160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
1609160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
1610160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
1611160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
1612160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
1613160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
1614160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
1615160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
1616160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
1617160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
1618160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
1619160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
1620160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
1621160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
1622160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
1623160,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
1624161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
1625161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
1626161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
1627161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
1628161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
1629161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
1630161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
1631161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
1632161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
1633161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
1634161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
1635161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
1636161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
1637161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
1638161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
1639161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
1640161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
1641161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
1642161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
1643161,161,161,161,162,162,162,162,162,162,162,162,162,162,162,162,
1644162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
1645162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
1646162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
1647162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
1648162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
1649162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
1650162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
1651162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
1652162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
1653162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
1654162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
1655162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
1656162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
1657162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
1658162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
1659162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
1660162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
1661162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
1662162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
1663162,162,162,162,162,162,162,162,162,163,163,163,163,163,163,163,
1664163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
1665163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
1666163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
1667163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
1668163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
1669163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
1670163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
1671163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
1672163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
1673163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
1674163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
1675163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
1676163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
1677163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
1678163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
1679163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
1680163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
1681163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
1682163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
1683163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
1684164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
1685164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
1686164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
1687164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
1688164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
1689164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
1690164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
1691164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
1692164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
1693164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
1694164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
1695164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
1696164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
1697164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
1698164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
1699164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
1700164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
1701164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
1702164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
1703164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
1704164,164,164,164,164,164,164,164,164,165,165,165,165,165,165,165,
1705165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
1706165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
1707165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
1708165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
1709165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
1710165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
1711165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
1712165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
1713165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
1714165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
1715165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
1716165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
1717165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
1718165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
1719165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
1720165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
1721165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
1722165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
1723165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
1724165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
1725165,165,165,165,166,166,166,166,166,166,166,166,166,166,166,166,
1726166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
1727166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
1728166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
1729166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
1730166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
1731166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
1732166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
1733166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
1734166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
1735166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
1736166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
1737166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
1738166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
1739166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
1740166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
1741166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
1742166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
1743166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
1744166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
1745166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
1746166,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
1747167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
1748167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
1749167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
1750167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
1751167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
1752167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
1753167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
1754167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
1755167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
1756167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
1757167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
1758167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
1759167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
1760167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
1761167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
1762167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
1763167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
1764167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
1765167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
1766167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
1767168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
1768168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
1769168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
1770168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
1771168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
1772168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
1773168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
1774168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
1775168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
1776168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
1777168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
1778168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
1779168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
1780168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
1781168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
1782168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
1783168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
1784168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
1785168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
1786168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
1787168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
1788168,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
1789169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
1790169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
1791169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
1792169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
1793169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
1794169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
1795169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
1796169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
1797169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
1798169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
1799169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
1800169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
1801169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
1802169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
1803169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
1804169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
1805169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
1806169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
1807169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
1808169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
1809169,169,169,169,170,170,170,170,170,170,170,170,170,170,170,170,
1810170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
1811170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
1812170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
1813170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
1814170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
1815170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
1816170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
1817170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
1818170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
1819170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
1820170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
1821170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
1822170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
1823170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
1824170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
1825170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
1826170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
1827170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
1828170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
1829170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
1830170,170,170,170,170,170,170,170,170,171,171,171,171,171,171,171,
1831171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
1832171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
1833171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
1834171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
1835171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
1836171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
1837171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
1838171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
1839171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
1840171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
1841171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
1842171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
1843171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
1844171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
1845171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
1846171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
1847171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
1848171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
1849171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
1850171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
1851171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
1852172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
1853172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
1854172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
1855172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
1856172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
1857172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
1858172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
1859172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
1860172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
1861172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
1862172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
1863172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
1864172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
1865172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
1866172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
1867172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
1868172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
1869172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
1870172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
1871172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
1872172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
1873172,172,172,172,172,172,172,172,172,173,173,173,173,173,173,173,
1874173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
1875173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
1876173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
1877173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
1878173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
1879173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
1880173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
1881173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
1882173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
1883173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
1884173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
1885173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
1886173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
1887173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
1888173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
1889173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
1890173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
1891173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
1892173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
1893173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
1894173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
1895173,173,173,173,174,174,174,174,174,174,174,174,174,174,174,174,
1896174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
1897174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
1898174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
1899174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
1900174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
1901174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
1902174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
1903174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
1904174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
1905174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
1906174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
1907174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
1908174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
1909174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
1910174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
1911174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
1912174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
1913174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
1914174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
1915174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
1916174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
1917174,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
1918175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
1919175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
1920175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
1921175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
1922175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
1923175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
1924175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
1925175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
1926175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
1927175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
1928175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
1929175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
1930175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
1931175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
1932175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
1933175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
1934175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
1935175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
1936175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
1937175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
1938175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
1939176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
1940176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
1941176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
1942176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
1943176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
1944176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
1945176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
1946176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
1947176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
1948176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
1949176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
1950176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
1951176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
1952176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
1953176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
1954176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
1955176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
1956176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
1957176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
1958176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
1959176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
1960176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
1961176,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
1962177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
1963177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
1964177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
1965177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
1966177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
1967177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
1968177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
1969177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
1970177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
1971177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
1972177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
1973177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
1974177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
1975177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
1976177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
1977177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
1978177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
1979177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
1980177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
1981177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
1982177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
1983177,177,177,177,178,178,178,178,178,178,178,178,178,178,178,178,
1984178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
1985178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
1986178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
1987178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
1988178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
1989178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
1990178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
1991178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
1992178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
1993178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
1994178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
1995178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
1996178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
1997178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
1998178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
1999178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
2000178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
2001178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
2002178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
2003178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
2004178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
2005178,178,178,178,178,178,178,178,178,179,179,179,179,179,179,179,
2006179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
2007179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
2008179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
2009179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
2010179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
2011179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
2012179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
2013179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
2014179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
2015179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
2016179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
2017179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
2018179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
2019179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
2020179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
2021179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
2022179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
2023179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
2024179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
2025179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
2026179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
2027179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
2028180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
2029180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
2030180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
2031180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
2032180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
2033180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
2034180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
2035180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
2036180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
2037180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
2038180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
2039180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
2040180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
2041180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
2042180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
2043180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
2044180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
2045180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
2046180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
2047180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
2048180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
2049180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
2050180,180,180,180,180,180,180,180,180,181,181,181,181,181,181,181,
2051181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
2052181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
2053181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
2054181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
2055181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
2056181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
2057181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
2058181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
2059181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
2060181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
2061181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
2062181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
2063181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
2064181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
2065181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
2066181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
2067181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
2068181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
2069181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
2070181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
2071181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
2072181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
2073181,181,181,181,182,182,182,182,182,182,182,182,182,182,182,182,
2074182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
2075182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
2076182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
2077182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
2078182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
2079182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
2080182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
2081182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
2082182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
2083182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
2084182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
2085182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
2086182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
2087182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
2088182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
2089182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
2090182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
2091182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
2092182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
2093182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
2094182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
2095182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
2096182,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
2097183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
2098183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
2099183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
2100183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
2101183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
2102183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
2103183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
2104183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
2105183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
2106183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
2107183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
2108183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
2109183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
2110183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
2111183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
2112183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
2113183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
2114183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
2115183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
2116183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
2117183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
2118183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
2119184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
2120184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
2121184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
2122184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
2123184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
2124184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
2125184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
2126184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
2127184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
2128184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
2129184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
2130184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
2131184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
2132184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
2133184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
2134184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
2135184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
2136184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
2137184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
2138184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
2139184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
2140184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
2141184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
2142184,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
2143185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
2144185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
2145185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
2146185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
2147185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
2148185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
2149185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
2150185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
2151185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
2152185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
2153185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
2154185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
2155185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
2156185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
2157185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
2158185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
2159185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
2160185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
2161185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
2162185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
2163185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
2164185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
2165185,185,185,185,186,186,186,186,186,186,186,186,186,186,186,186,
2166186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
2167186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
2168186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
2169186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
2170186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
2171186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
2172186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
2173186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
2174186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
2175186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
2176186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
2177186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
2178186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
2179186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
2180186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
2181186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
2182186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
2183186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
2184186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
2185186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
2186186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
2187186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
2188186,186,186,186,186,186,186,186,186,187,187,187,187,187,187,187,
2189187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
2190187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
2191187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
2192187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
2193187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
2194187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
2195187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
2196187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
2197187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
2198187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
2199187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
2200187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
2201187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
2202187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
2203187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
2204187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
2205187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
2206187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
2207187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
2208187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
2209187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
2210187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
2211187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
2212188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
2213188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
2214188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
2215188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
2216188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
2217188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
2218188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
2219188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
2220188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
2221188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
2222188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
2223188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
2224188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
2225188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
2226188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
2227188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
2228188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
2229188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
2230188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
2231188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
2232188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
2233188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
2234188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
2235188,188,188,188,188,188,188,188,188,189,189,189,189,189,189,189,
2236189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
2237189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
2238189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
2239189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
2240189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
2241189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
2242189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
2243189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
2244189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
2245189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
2246189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
2247189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
2248189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
2249189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
2250189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
2251189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
2252189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
2253189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
2254189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
2255189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
2256189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
2257189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
2258189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
2259189,189,189,189,190,190,190,190,190,190,190,190,190,190,190,190,
2260190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
2261190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
2262190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
2263190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
2264190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
2265190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
2266190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
2267190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
2268190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
2269190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
2270190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
2271190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
2272190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
2273190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
2274190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
2275190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
2276190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
2277190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
2278190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
2279190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
2280190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
2281190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
2282190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
2283190,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
2284191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
2285191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
2286191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
2287191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
2288191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
2289191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
2290191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
2291191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
2292191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
2293191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
2294191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
2295191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
2296191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
2297191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
2298191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
2299191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
2300191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
2301191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
2302191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
2303191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
2304191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
2305191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
2306191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
2307192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
2308192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
2309192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
2310192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
2311192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
2312192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
2313192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
2314192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
2315192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
2316192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
2317192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
2318192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
2319192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
2320192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
2321192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
2322192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
2323192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
2324192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
2325192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
2326192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
2327192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
2328192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
2329192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
2330192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
2331192,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
2332193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
2333193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
2334193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
2335193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
2336193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
2337193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
2338193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
2339193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
2340193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
2341193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
2342193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
2343193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
2344193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
2345193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
2346193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
2347193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
2348193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
2349193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
2350193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
2351193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
2352193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
2353193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
2354193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
2355193,193,193,193,194,194,194,194,194,194,194,194,194,194,194,194,
2356194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
2357194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
2358194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
2359194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
2360194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
2361194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
2362194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
2363194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
2364194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
2365194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
2366194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
2367194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
2368194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
2369194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
2370194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
2371194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
2372194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
2373194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
2374194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
2375194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
2376194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
2377194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
2378194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
2379194,194,194,194,194,194,194,194,194,195,195,195,195,195,195,195,
2380195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
2381195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
2382195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
2383195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
2384195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
2385195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
2386195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
2387195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
2388195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
2389195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
2390195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
2391195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
2392195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
2393195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
2394195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
2395195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
2396195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
2397195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
2398195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
2399195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
2400195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
2401195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
2402195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
2403195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
2404196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
2405196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
2406196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
2407196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
2408196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
2409196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
2410196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
2411196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
2412196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
2413196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
2414196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
2415196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
2416196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
2417196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
2418196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
2419196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
2420196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
2421196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
2422196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
2423196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
2424196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
2425196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
2426196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
2427196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
2428196,196,196,196,196,196,196,196,196,197,197,197,197,197,197,197,
2429197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
2430197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
2431197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
2432197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
2433197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
2434197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
2435197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
2436197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
2437197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
2438197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
2439197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
2440197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
2441197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
2442197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
2443197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
2444197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
2445197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
2446197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
2447197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
2448197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
2449197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
2450197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
2451197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
2452197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
2453197,197,197,197,198,198,198,198,198,198,198,198,198,198,198,198,
2454198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
2455198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
2456198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
2457198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
2458198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
2459198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
2460198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
2461198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
2462198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
2463198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
2464198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
2465198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
2466198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
2467198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
2468198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
2469198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
2470198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
2471198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
2472198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
2473198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
2474198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
2475198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
2476198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
2477198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
2478198,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
2479199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
2480199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
2481199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
2482199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
2483199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
2484199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
2485199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
2486199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
2487199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
2488199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
2489199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
2490199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
2491199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
2492199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
2493199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
2494199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
2495199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
2496199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
2497199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
2498199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
2499199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
2500199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
2501199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
2502199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
2503200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
2504200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
2505200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
2506200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
2507200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
2508200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
2509200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
2510200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
2511200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
2512200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
2513200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
2514200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
2515200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
2516200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
2517200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
2518200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
2519200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
2520200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
2521200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
2522200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
2523200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
2524200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
2525200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
2526200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
2527200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
2528200,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
2529201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
2530201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
2531201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
2532201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
2533201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
2534201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
2535201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
2536201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
2537201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
2538201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
2539201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
2540201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
2541201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
2542201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
2543201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
2544201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
2545201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
2546201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
2547201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
2548201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
2549201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
2550201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
2551201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
2552201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
2553201,201,201,201,202,202,202,202,202,202,202,202,202,202,202,202,
2554202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
2555202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
2556202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
2557202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
2558202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
2559202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
2560202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
2561202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
2562202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
2563202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
2564202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
2565202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
2566202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
2567202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
2568202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
2569202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
2570202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
2571202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
2572202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
2573202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
2574202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
2575202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
2576202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
2577202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
2578202,202,202,202,202,202,202,202,202,203,203,203,203,203,203,203,
2579203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
2580203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
2581203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
2582203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
2583203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
2584203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
2585203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
2586203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
2587203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
2588203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
2589203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
2590203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
2591203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
2592203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
2593203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
2594203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
2595203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
2596203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
2597203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
2598203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
2599203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
2600203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
2601203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
2602203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
2603203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
2604204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
2605204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
2606204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
2607204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
2608204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
2609204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
2610204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
2611204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
2612204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
2613204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
2614204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
2615204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
2616204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
2617204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
2618204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
2619204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
2620204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
2621204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
2622204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
2623204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
2624204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
2625204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
2626204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
2627204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
2628204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
2629204,204,204,204,204,204,204,204,204,205,205,205,205,205,205,205,
2630205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
2631205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
2632205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
2633205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
2634205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
2635205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
2636205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
2637205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
2638205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
2639205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
2640205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
2641205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
2642205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
2643205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
2644205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
2645205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
2646205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
2647205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
2648205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
2649205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
2650205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
2651205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
2652205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
2653205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
2654205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
2655205,205,205,205,206,206,206,206,206,206,206,206,206,206,206,206,
2656206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
2657206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
2658206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
2659206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
2660206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
2661206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
2662206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
2663206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
2664206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
2665206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
2666206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
2667206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
2668206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
2669206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
2670206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
2671206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
2672206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
2673206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
2674206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
2675206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
2676206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
2677206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
2678206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
2679206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
2680206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
2681206,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
2682207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
2683207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
2684207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
2685207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
2686207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
2687207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
2688207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
2689207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
2690207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
2691207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
2692207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
2693207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
2694207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
2695207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
2696207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
2697207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
2698207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
2699207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
2700207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
2701207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
2702207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
2703207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
2704207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
2705207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
2706207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
2707208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
2708208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
2709208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
2710208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
2711208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
2712208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
2713208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
2714208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
2715208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
2716208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
2717208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
2718208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
2719208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
2720208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
2721208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
2722208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
2723208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
2724208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
2725208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
2726208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
2727208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
2728208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
2729208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
2730208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
2731208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
2732208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
2733208,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
2734209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
2735209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
2736209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
2737209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
2738209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
2739209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
2740209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
2741209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
2742209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
2743209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
2744209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
2745209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
2746209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
2747209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
2748209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
2749209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
2750209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
2751209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
2752209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
2753209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
2754209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
2755209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
2756209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
2757209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
2758209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
2759209,209,209,209,210,210,210,210,210,210,210,210,210,210,210,210,
2760210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
2761210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
2762210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
2763210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
2764210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
2765210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
2766210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
2767210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
2768210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
2769210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
2770210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
2771210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
2772210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
2773210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
2774210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
2775210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
2776210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
2777210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
2778210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
2779210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
2780210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
2781210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
2782210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
2783210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
2784210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
2785210,210,210,210,210,210,210,210,210,211,211,211,211,211,211,211,
2786211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
2787211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
2788211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
2789211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
2790211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
2791211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
2792211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
2793211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
2794211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
2795211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
2796211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
2797211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
2798211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
2799211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
2800211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
2801211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
2802211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
2803211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
2804211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
2805211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
2806211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
2807211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
2808211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
2809211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
2810211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
2811211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
2812212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
2813212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
2814212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
2815212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
2816212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
2817212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
2818212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
2819212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
2820212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
2821212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
2822212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
2823212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
2824212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
2825212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
2826212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
2827212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
2828212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
2829212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
2830212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
2831212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
2832212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
2833212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
2834212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
2835212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
2836212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
2837212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
2838212,212,212,212,212,212,212,212,212,213,213,213,213,213,213,213,
2839213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
2840213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
2841213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
2842213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
2843213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
2844213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
2845213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
2846213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
2847213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
2848213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
2849213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
2850213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
2851213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
2852213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
2853213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
2854213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
2855213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
2856213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
2857213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
2858213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
2859213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
2860213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
2861213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
2862213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
2863213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
2864213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
2865213,213,213,213,214,214,214,214,214,214,214,214,214,214,214,214,
2866214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
2867214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
2868214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
2869214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
2870214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
2871214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
2872214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
2873214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
2874214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
2875214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
2876214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
2877214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
2878214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
2879214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
2880214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
2881214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
2882214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
2883214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
2884214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
2885214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
2886214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
2887214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
2888214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
2889214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
2890214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
2891214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
2892214,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
2893215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
2894215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
2895215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
2896215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
2897215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
2898215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
2899215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
2900215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
2901215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
2902215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
2903215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
2904215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
2905215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
2906215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
2907215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
2908215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
2909215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
2910215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
2911215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
2912215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
2913215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
2914215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
2915215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
2916215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
2917215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
2918215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
2919216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
2920216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
2921216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
2922216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
2923216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
2924216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
2925216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
2926216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
2927216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
2928216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
2929216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
2930216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
2931216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
2932216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
2933216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
2934216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
2935216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
2936216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
2937216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
2938216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
2939216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
2940216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
2941216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
2942216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
2943216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
2944216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
2945216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
2946216,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
2947217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
2948217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
2949217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
2950217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
2951217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
2952217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
2953217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
2954217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
2955217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
2956217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
2957217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
2958217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
2959217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
2960217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
2961217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
2962217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
2963217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
2964217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
2965217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
2966217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
2967217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
2968217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
2969217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
2970217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
2971217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
2972217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
2973217,217,217,217,218,218,218,218,218,218,218,218,218,218,218,218,
2974218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
2975218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
2976218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
2977218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
2978218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
2979218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
2980218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
2981218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
2982218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
2983218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
2984218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
2985218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
2986218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
2987218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
2988218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
2989218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
2990218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
2991218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
2992218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
2993218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
2994218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
2995218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
2996218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
2997218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
2998218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
2999218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
3000218,218,218,218,218,218,218,218,218,219,219,219,219,219,219,219,
3001219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
3002219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
3003219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
3004219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
3005219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
3006219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
3007219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
3008219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
3009219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
3010219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
3011219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
3012219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
3013219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
3014219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
3015219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
3016219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
3017219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
3018219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
3019219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
3020219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
3021219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
3022219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
3023219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
3024219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
3025219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
3026219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
3027219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
3028220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
3029220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
3030220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
3031220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
3032220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
3033220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
3034220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
3035220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
3036220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
3037220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
3038220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
3039220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
3040220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
3041220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
3042220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
3043220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
3044220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
3045220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
3046220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
3047220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
3048220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
3049220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
3050220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
3051220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
3052220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
3053220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
3054220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
3055220,220,220,220,220,220,220,220,220,221,221,221,221,221,221,221,
3056221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
3057221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
3058221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
3059221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
3060221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
3061221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
3062221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
3063221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
3064221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
3065221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
3066221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
3067221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
3068221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
3069221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
3070221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
3071221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
3072221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
3073221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
3074221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
3075221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
3076221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
3077221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
3078221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
3079221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
3080221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
3081221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
3082221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
3083221,221,221,221,222,222,222,222,222,222,222,222,222,222,222,222,
3084222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
3085222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
3086222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
3087222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
3088222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
3089222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
3090222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
3091222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
3092222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
3093222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
3094222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
3095222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
3096222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
3097222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
3098222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
3099222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
3100222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
3101222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
3102222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
3103222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
3104222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
3105222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
3106222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
3107222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
3108222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
3109222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
3110222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
3111222,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
3112223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
3113223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
3114223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
3115223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
3116223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
3117223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
3118223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
3119223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
3120223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
3121223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
3122223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
3123223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
3124223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
3125223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
3126223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
3127223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
3128223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
3129223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
3130223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
3131223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
3132223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
3133223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
3134223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
3135223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
3136223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
3137223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
3138223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
3139224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
3140224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
3141224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
3142224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
3143224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
3144224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
3145224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
3146224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
3147224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
3148224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
3149224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
3150224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
3151224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
3152224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
3153224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
3154224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
3155224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
3156224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
3157224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
3158224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
3159224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
3160224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
3161224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
3162224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
3163224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
3164224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
3165224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
3166224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
3167224,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
3168225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
3169225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
3170225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
3171225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
3172225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
3173225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
3174225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
3175225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
3176225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
3177225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
3178225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
3179225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
3180225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
3181225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
3182225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
3183225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
3184225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
3185225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
3186225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
3187225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
3188225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
3189225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
3190225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
3191225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
3192225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
3193225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
3194225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
3195225,225,225,225,226,226,226,226,226,226,226,226,226,226,226,226,
3196226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
3197226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
3198226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
3199226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
3200226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
3201226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
3202226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
3203226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
3204226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
3205226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
3206226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
3207226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
3208226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
3209226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
3210226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
3211226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
3212226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
3213226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
3214226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
3215226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
3216226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
3217226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
3218226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
3219226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
3220226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
3221226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
3222226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
3223226,226,226,226,226,226,226,226,226,227,227,227,227,227,227,227,
3224227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
3225227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
3226227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
3227227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
3228227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
3229227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
3230227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
3231227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
3232227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
3233227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
3234227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
3235227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
3236227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
3237227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
3238227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
3239227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
3240227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
3241227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
3242227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
3243227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
3244227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
3245227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
3246227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
3247227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
3248227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
3249227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
3250227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
3251227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
3252228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
3253228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
3254228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
3255228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
3256228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
3257228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
3258228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
3259228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
3260228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
3261228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
3262228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
3263228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
3264228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
3265228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
3266228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
3267228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
3268228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
3269228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
3270228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
3271228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
3272228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
3273228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
3274228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
3275228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
3276228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
3277228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
3278228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
3279228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
3280228,228,228,228,228,228,228,228,228,229,229,229,229,229,229,229,
3281229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
3282229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
3283229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
3284229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
3285229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
3286229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
3287229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
3288229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
3289229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
3290229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
3291229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
3292229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
3293229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
3294229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
3295229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
3296229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
3297229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
3298229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
3299229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
3300229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
3301229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
3302229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
3303229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
3304229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
3305229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
3306229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
3307229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
3308229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
3309229,229,229,229,230,230,230,230,230,230,230,230,230,230,230,230,
3310230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
3311230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
3312230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
3313230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
3314230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
3315230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
3316230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
3317230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
3318230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
3319230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
3320230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
3321230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
3322230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
3323230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
3324230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
3325230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
3326230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
3327230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
3328230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
3329230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
3330230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
3331230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
3332230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
3333230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
3334230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
3335230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
3336230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
3337230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
3338230,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
3339231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
3340231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
3341231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
3342231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
3343231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
3344231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
3345231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
3346231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
3347231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
3348231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
3349231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
3350231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
3351231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
3352231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
3353231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
3354231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
3355231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
3356231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
3357231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
3358231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
3359231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
3360231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
3361231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
3362231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
3363231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
3364231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
3365231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
3366231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
3367232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
3368232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
3369232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
3370232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
3371232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
3372232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
3373232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
3374232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
3375232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
3376232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
3377232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
3378232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
3379232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
3380232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
3381232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
3382232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
3383232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
3384232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
3385232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
3386232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
3387232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
3388232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
3389232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
3390232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
3391232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
3392232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
3393232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
3394232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
3395232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
3396232,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
3397233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
3398233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
3399233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
3400233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
3401233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
3402233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
3403233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
3404233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
3405233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
3406233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
3407233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
3408233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
3409233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
3410233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
3411233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
3412233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
3413233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
3414233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
3415233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
3416233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
3417233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
3418233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
3419233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
3420233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
3421233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
3422233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
3423233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
3424233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
3425233,233,233,233,234,234,234,234,234,234,234,234,234,234,234,234,
3426234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
3427234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
3428234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
3429234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
3430234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
3431234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
3432234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
3433234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
3434234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
3435234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
3436234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
3437234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
3438234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
3439234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
3440234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
3441234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
3442234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
3443234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
3444234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
3445234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
3446234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
3447234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
3448234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
3449234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
3450234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
3451234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
3452234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
3453234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
3454234,234,234,234,234,234,234,234,234,235,235,235,235,235,235,235,
3455235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
3456235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
3457235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
3458235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
3459235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
3460235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
3461235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
3462235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
3463235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
3464235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
3465235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
3466235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
3467235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
3468235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
3469235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
3470235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
3471235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
3472235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
3473235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
3474235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
3475235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
3476235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
3477235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
3478235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
3479235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
3480235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
3481235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
3482235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
3483235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
3484236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
3485236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
3486236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
3487236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
3488236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
3489236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
3490236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
3491236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
3492236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
3493236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
3494236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
3495236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
3496236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
3497236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
3498236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
3499236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
3500236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
3501236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
3502236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
3503236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
3504236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
3505236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
3506236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
3507236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
3508236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
3509236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
3510236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
3511236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
3512236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
3513236,236,236,236,236,236,236,236,236,237,237,237,237,237,237,237,
3514237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
3515237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
3516237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
3517237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
3518237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
3519237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
3520237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
3521237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
3522237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
3523237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
3524237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
3525237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
3526237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
3527237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
3528237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
3529237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
3530237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
3531237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
3532237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
3533237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
3534237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
3535237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
3536237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
3537237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
3538237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
3539237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
3540237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
3541237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
3542237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
3543237,237,237,237,238,238,238,238,238,238,238,238,238,238,238,238,
3544238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
3545238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
3546238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
3547238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
3548238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
3549238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
3550238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
3551238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
3552238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
3553238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
3554238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
3555238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
3556238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
3557238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
3558238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
3559238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
3560238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
3561238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
3562238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
3563238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
3564238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
3565238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
3566238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
3567238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
3568238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
3569238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
3570238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
3571238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
3572238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
3573238,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
3574239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
3575239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
3576239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
3577239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
3578239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
3579239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
3580239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
3581239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
3582239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
3583239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
3584239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
3585239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
3586239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
3587239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
3588239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
3589239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
3590239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
3591239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
3592239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
3593239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
3594239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
3595239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
3596239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
3597239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
3598239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
3599239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
3600239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
3601239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
3602239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
3603240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
3604240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
3605240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
3606240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
3607240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
3608240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
3609240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
3610240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
3611240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
3612240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
3613240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
3614240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
3615240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
3616240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
3617240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
3618240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
3619240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
3620240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
3621240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
3622240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
3623240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
3624240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
3625240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
3626240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
3627240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
3628240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
3629240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
3630240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
3631240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
3632240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
3633240,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
3634241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
3635241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
3636241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
3637241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
3638241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
3639241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
3640241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
3641241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
3642241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
3643241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
3644241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
3645241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
3646241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
3647241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
3648241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
3649241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
3650241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
3651241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
3652241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
3653241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
3654241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
3655241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
3656241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
3657241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
3658241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
3659241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
3660241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
3661241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
3662241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
3663241,241,241,241,242,242,242,242,242,242,242,242,242,242,242,242,
3664242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
3665242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
3666242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
3667242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
3668242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
3669242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
3670242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
3671242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
3672242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
3673242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
3674242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
3675242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
3676242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
3677242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
3678242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
3679242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
3680242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
3681242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
3682242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
3683242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
3684242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
3685242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
3686242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
3687242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
3688242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
3689242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
3690242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
3691242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
3692242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
3693242,242,242,242,242,242,242,242,242,243,243,243,243,243,243,243,
3694243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
3695243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
3696243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
3697243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
3698243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
3699243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
3700243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
3701243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
3702243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
3703243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
3704243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
3705243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
3706243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
3707243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
3708243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
3709243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
3710243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
3711243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
3712243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
3713243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
3714243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
3715243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
3716243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
3717243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
3718243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
3719243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
3720243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
3721243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
3722243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
3723243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
3724244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
3725244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
3726244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
3727244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
3728244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
3729244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
3730244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
3731244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
3732244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
3733244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
3734244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
3735244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
3736244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
3737244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
3738244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
3739244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
3740244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
3741244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
3742244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
3743244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
3744244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
3745244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
3746244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
3747244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
3748244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
3749244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
3750244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
3751244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
3752244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
3753244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
3754244,244,244,244,244,244,244,244,244,245,245,245,245,245,245,245,
3755245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
3756245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
3757245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
3758245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
3759245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
3760245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
3761245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
3762245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
3763245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
3764245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
3765245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
3766245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
3767245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
3768245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
3769245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
3770245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
3771245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
3772245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
3773245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
3774245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
3775245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
3776245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
3777245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
3778245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
3779245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
3780245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
3781245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
3782245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
3783245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
3784245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
3785245,245,245,245,246,246,246,246,246,246,246,246,246,246,246,246,
3786246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
3787246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
3788246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
3789246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
3790246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
3791246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
3792246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
3793246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
3794246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
3795246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
3796246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
3797246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
3798246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
3799246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
3800246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
3801246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
3802246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
3803246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
3804246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
3805246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
3806246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
3807246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
3808246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
3809246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
3810246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
3811246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
3812246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
3813246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
3814246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
3815246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
3816246,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
3817247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
3818247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
3819247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
3820247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
3821247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
3822247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
3823247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
3824247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
3825247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
3826247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
3827247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
3828247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
3829247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
3830247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
3831247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
3832247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
3833247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
3834247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
3835247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
3836247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
3837247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
3838247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
3839247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
3840247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
3841247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
3842247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
3843247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
3844247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
3845247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
3846247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
3847248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
3848248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
3849248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
3850248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
3851248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
3852248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
3853248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
3854248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
3855248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
3856248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
3857248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
3858248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
3859248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
3860248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
3861248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
3862248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
3863248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
3864248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
3865248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
3866248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
3867248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
3868248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
3869248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
3870248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
3871248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
3872248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
3873248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
3874248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
3875248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
3876248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
3877248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
3878248,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
3879249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
3880249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
3881249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
3882249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
3883249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
3884249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
3885249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
3886249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
3887249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
3888249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
3889249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
3890249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
3891249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
3892249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
3893249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
3894249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
3895249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
3896249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
3897249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
3898249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
3899249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
3900249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
3901249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
3902249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
3903249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
3904249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
3905249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
3906249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
3907249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
3908249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
3909249,249,249,249,250,250,250,250,250,250,250,250,250,250,250,250,
3910250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
3911250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
3912250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
3913250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
3914250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
3915250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
3916250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
3917250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
3918250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
3919250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
3920250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
3921250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
3922250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
3923250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
3924250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
3925250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
3926250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
3927250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
3928250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
3929250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
3930250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
3931250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
3932250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
3933250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
3934250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
3935250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
3936250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
3937250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
3938250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
3939250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
3940250,250,250,250,250,250,250,250,250,251,251,251,251,251,251,251,
3941251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
3942251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
3943251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
3944251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
3945251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
3946251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
3947251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
3948251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
3949251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
3950251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
3951251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
3952251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
3953251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
3954251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
3955251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
3956251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
3957251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
3958251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
3959251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
3960251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
3961251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
3962251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
3963251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
3964251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
3965251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
3966251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
3967251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
3968251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
3969251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
3970251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
3971251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
3972252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
3973252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
3974252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
3975252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
3976252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
3977252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
3978252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
3979252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
3980252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
3981252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
3982252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
3983252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
3984252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
3985252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
3986252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
3987252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
3988252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
3989252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
3990252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
3991252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
3992252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
3993252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
3994252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
3995252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
3996252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
3997252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
3998252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
3999252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
4000252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
4001252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
4002252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
4003252,252,252,252,252,252,252,252,252,253,253,253,253,253,253,253,
4004253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
4005253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
4006253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
4007253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
4008253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
4009253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
4010253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
4011253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
4012253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
4013253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
4014253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
4015253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
4016253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
4017253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
4018253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
4019253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
4020253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
4021253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
4022253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
4023253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
4024253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
4025253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
4026253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
4027253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
4028253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
4029253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
4030253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
4031253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
4032253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
4033253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
4034253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
4035253,253,253,253,254,254,254,254,254,254,254,254,254,254,254,254,
4036254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
4037254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
4038254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
4039254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
4040254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
4041254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
4042254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
4043254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
4044254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
4045254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
4046254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
4047254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
4048254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
4049254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
4050254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
4051254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
4052254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
4053254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
4054254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
4055254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
4056254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
4057254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
4058254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
4059254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
4060254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
4061254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
4062254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
4063254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
4064254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
4065254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
4066254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
4067254,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
4068255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
4069255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
4070255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
4071255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
4072255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
4073255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
4074255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
4075255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
4076255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
4077255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
4078255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
4079255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
4080255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
4081255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
4082255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
4083255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
4084255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
4085255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
4086255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
4087255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
4088255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
4089255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
4090255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
4091255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
4092255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
4093255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
4094255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
4095255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
4096255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
4097255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
4098255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
4099};
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 @@
1#ifndef _SWF_H_
2#define _SWF_H_
3
4#include <stdio.h>
5#include <stdlib.h>
6#include <string.h>
7#include <setjmp.h>
8#include <assert.h>
9#include <limits.h>
10
11#ifdef DUMP
12#include "bitstream.h"
13#endif
14
15#include "flash.h"
16
17extern int debug;
18
19// Global Types
20typedef unsigned long U32, *P_U32, **PP_U32;
21typedef signed long S32, *P_S32, **PP_S32;
22typedef unsigned short U16, *P_U16, **PP_U16;
23typedef signed short S16, *P_S16, **PP_S16;
24typedef unsigned char U8, *P_U8, **PP_U8;
25typedef signed char S8, *P_S8, **PP_S8;
26typedef signed long SFIXED, *P_SFIXED;
27typedef signed long SCOORD, *P_SCOORD;
28typedef unsigned long BOOL;
29
30#define ZOOM(v,f) ((v)/(f))
31
32#include "matrix.h"
33#include "cxform.h"
34#include "rect.h"
35
36#include <sys/time.h>
37#define ST struct timeval t1,t2;
38#define START gettimeofday(&t1,0)
39#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);
40
41// Start Sound Flags
42enum {
43 soundHasInPoint = 0x01,
44 soundHasOutPoint= 0x02,
45 soundHasLoops = 0x04,
46 soundHasEnvelope= 0x08
47
48 // the upper 4 bits are reserved for synchronization flags
49};
50
51// Flags for Sound Format
52enum SounfFlags {
53 soundIsStereo = 0x01,
54 soundIs16bit = 0x02,
55 soundIsADPCMCompressed= 0x10
56};
57
58// Flags for defining Button States
59enum ButtonState {
60 stateHitTest = 0x08,
61 stateDown = 0x04,
62 stateOver = 0x02,
63 stateUp = 0x01
64};
65
66// Actions
67enum Action {
68 // Internal actions
69 ActionRefresh = 0x00,
70 ActionPlaySound = 0x01,
71 // Normal actions
72 ActionGotoFrame = 0x81,
73 ActionGetURL = 0x83,
74 ActionNextFrame = 0x04,
75 ActionPrevFrame = 0x05,
76 ActionPlay = 0x06,
77 ActionStop = 0x07,
78 ActionToggleQuality= 0x08,
79 ActionStopSounds= 0x09,
80 ActionWaitForFrame= 0x8a,
81 ActionSetTarget = 0x8b,
82 ActionGoToLabel = 0x8c
83};
84
85class Sound;
86
87struct ActionRecord {
88 Action action;
89
90 // GotoFrame & WaitForFrame
91 long frameIndex;
92
93 // GetURL
94 char *url;
95 char *target;
96
97 // GotoLabel
98 char *frameLabel;
99
100 // WaitForFrame
101 long skipCount;
102
103 // Sound
104 Sound *sound;
105
106 struct ActionRecord*next;
107
108 ActionRecord() {
109 frameLabel = 0;
110 url = 0;
111 target = 0;
112 sound = 0;
113 };
114
115 ~ActionRecord() {
116 if (frameLabel) free(frameLabel);
117 if (url) free(url);
118 if (target) free(target);
119 };
120};
121
122enum FontFlags {
123 fontUnicode = 0x20,
124 fontShiftJIS = 0x10,
125 fontANSI = 0x08,
126 fontItalic = 0x04,
127 fontBold = 0x02,
128 fontWideCodes = 0x01
129};
130
131enum TextFlags {
132 isTextControl = 0x80,
133
134 textIsLarge = 0x70,
135 textHasFont = 0x08,
136 textHasColor = 0x04,
137 textHasYOffset= 0x02,
138 textHasXOffset= 0x01
139};
140
141#ifndef NULL
142#define NULL 0
143#endif
144
145// Tag values that represent actions or data in a Flash script.
146enum
147{
148 stagEnd = 0,
149 stagShowFrame = 1,
150 stagDefineShape = 2,
151 stagFreeCharacter = 3,
152 stagPlaceObject = 4,
153 stagRemoveObject = 5,
154 stagDefineBits = 6,
155 stagDefineButton = 7,
156 stagJPEGTables = 8,
157 stagSetBackgroundColor= 9,
158 stagDefineFont = 10,
159 stagDefineText = 11,
160 stagDoAction = 12,
161 stagDefineFontInfo = 13,
162 stagDefineSound = 14,// Event sound tags.
163 stagStartSound = 15,
164 stagStopSound = 16,
165 stagDefineButtonSound= 17,
166 stagSoundStreamHead = 18,
167 stagSoundStreamBlock= 19,
168 stagDefineBitsLossless = 20,// A bitmap using lossless zlib compression.
169 stagDefineBitsJPEG2 = 21,// A bitmap using an internal JPEG compression table.
170 stagDefineShape2 = 22,
171 stagDefineButtonCxform= 23,
172 stagProtect = 24,// This file should not be importable for editing.
173
174 // These are the new tags for Flash 3.
175 stagPlaceObject2 = 26,// The new style place w/ alpha color transform and name.
176 stagRemoveObject2 = 28,// A more compact remove object that omits the character tag (just depth).
177 stagDefineShape3 = 32,// A shape V3 includes alpha values.
178 stagDefineText2 = 33,// A text V2 includes alpha values.
179 stagDefineButton2 = 34,// A button V2 includes color transform, alpha and multiple actions
180 stagDefineBitsJPEG3 = 35,// A JPEG bitmap with alpha info.
181 stagDefineBitsLossless2 = 36,// A lossless bitmap with alpha info.
182 stagDefineSprite = 39,// Define a sequence of tags that describe the behavior of a sprite.
183 stagNameCharacter = 40,// Name a character definition, character id and a string, (used for buttons, bitmaps, sprites and sounds).
184 stagFrameLabel = 43,// A string label for the current frame.
185 stagSoundStreamHead2 = 45,// For lossless streaming sound, should not have needed this...
186 stagDefineMorphShape = 46,// A morph shape definition
187 stagDefineFont2 = 48,
188
189 notEnoughData = 0xffff,// Special code
190};
191
192#ifndef false
193#define false 0
194#endif
195#ifndef true
196#define true 1
197#endif
198
199extern int shape_size,shape_nb,shaperecord_size,shaperecord_nb,style_size,style_nb;
200
201typedef void (*ScanLineFunc)(void *id, long y, long start, long end);
202
203class Bitmap;
204struct FlashMovie;
205
206extern "C" {
207#include "jpeglib.h"
208};
209extern "C" {
210//#include "zlib.h"
211#include "../src/3rdparty/zlib/zlib.h"
212};
213
214#include "graphic.h"
215#include "character.h"
216#include "bitmap.h"
217#include "shape.h"
218#include "displaylist.h"
219#include "sound.h"
220#include "button.h"
221#include "font.h"
222#include "text.h"
223#include "adpcm.h"
224#include "program.h"
225#include "sprite.h"
226#include "script.h"
227#include "movie.h"
228
229#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 @@
1/////////////////////////////////////////////////////////////
2// Flash Plugin and Player
3// Copyright (C) 1998,1999 Olivier Debon
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19///////////////////////////////////////////////////////////////
20// Author : Olivier Debon <odebon@club-internet.fr>
21//
22
23#include "swf.h"
24
25#ifdef RCSID
26static char *rcsid = "$Id$";
27#endif
28
29Text::Text(long id) : Character(TextType, id)
30{
31 textRecords = 0;
32}
33
34Text::~Text()
35{
36 TextRecord *cur,*del;
37
38 for(cur = textRecords; cur;)
39 {
40 del = cur;
41 cur = cur->next;
42 delete del;
43 }
44}
45
46void
47Text::setTextBoundary(Rect rect)
48{
49 boundary = rect;
50}
51
52void
53Text::setTextMatrix(Matrix m)
54{
55 textMatrix = m;
56}
57
58void
59Text::addTextRecord(TextRecord *tr)
60{
61 SwfFont *font = 0;
62 long n;
63
64 tr->next = 0;
65
66 if (textRecords == 0) {
67 textRecords = tr;
68 font = tr->font;
69 } else {
70 TextRecord *current;
71 long fontHeight = 0;
72
73 for(current = textRecords; current->next; current = current->next) {
74 if (current->flags & textHasFont) {
75 font = current->font;
76 fontHeight = current->fontHeight;
77 }
78 }
79
80 current->next = tr;
81 if (current->flags & textHasFont) {
82 font = current->font;
83 fontHeight = current->fontHeight;
84 }
85
86 if (tr->flags & textHasFont) {
87 font = tr->font;
88 } else {
89 tr->font = font;
90 tr->fontHeight = fontHeight;
91 }
92 }
93
94 if (tr->nbGlyphs) {
95 for(n=0; n < tr->nbGlyphs; n++) {
96 tr->glyphs[n].code = font->getGlyphCode(tr->glyphs[n].index);
97 }
98 }
99}
100
101int
102Text::execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform)
103{
104 return doText(gd, matrix, cxform, ShapeDraw, NULL, NULL);
105}
106
107void
108Text::getRegion(GraphicDevice *gd, Matrix *matrix,
109 void *id, ScanLineFunc scan_line_func)
110{
111 doText(gd, matrix, 0, ShapeGetRegion, id, scan_line_func);
112}
113
114void
115Text::getBoundingBox(Rect *bb, DisplayListEntry *e)
116{
117 *bb = boundary;
118}
119
120TextRecord *
121Text::getTextRecords()
122{
123 return textRecords;
124}
125
126int
127Text::doText(GraphicDevice *gd, Matrix *matrix, Cxform *cxform, ShapeAction action,
128 void *id, ScanLineFunc scan_line_func)
129{
130 TextRecord*tr;
131 long x,y; // Current position
132 SwfFont *font = 0;// Current font
133 long fontHeight;
134 Matrix tmat,fmat;
135 long g;
136
137 x = y = 0;
138 fontHeight = 0;
139
140 // Compute final text matrix
141 tmat = (*matrix) * textMatrix;
142
143 for(tr = textRecords; tr; tr = tr ->next)
144 {
145 if (tr->flags & isTextControl) {
146 if (tr->flags & textHasXOffset) {
147 x = tr->xOffset;
148 }
149 if (tr->flags & textHasYOffset) {
150 y = tr->yOffset;
151 }
152 if (tr->flags & textHasColor) {
153 if (action == ShapeDraw) {
154 if (cxform) {
155 gd->setForegroundColor(cxform->getColor(tr->color));
156 } else {
157 gd->setForegroundColor(tr->color);
158 }
159 }
160 }
161 }
162
163 font = tr->font;
164 fontHeight = tr->fontHeight;
165 // Update font matrix
166 fmat.a = fontHeight/1000.0;
167 fmat.d = fontHeight/1000.0;
168
169 assert(font != 0);
170 for (g = 0; g < tr->nbGlyphs; g++)
171 {
172 Shape *shape;
173 Matrix cmat;
174
175 shape = font->getGlyph( tr->glyphs[g].index );
176
177#ifdef PRINT
178 printf("%c", font->getGlyphCode(tr->glyphs[g].index));
179#endif
180
181 // Update font matrix
182 fmat.tx = x;
183 fmat.ty = y;
184
185 // Compute Character matrix
186 cmat = tmat * fmat;
187
188 if (action == ShapeDraw) {
189 shape->execute(gd, &cmat, cxform);
190 } else {
191 shape->getRegion(gd, &cmat, id, scan_line_func);
192 }
193
194 // Advance
195 x += tr->glyphs[g].xAdvance;
196 }
197#ifdef PRINT
198 printf("\n");
199#endif
200 }
201
202 if (gd->showMore) {
203 tmat = (*gd->adjust) * (*matrix);
204
205 long x1,x2,y1,y2;
206
207 x1 = boundary.xmin;
208 y1 = boundary.ymin;
209 x2 = boundary.xmax;
210 y2 = boundary.ymax;
211 gd->drawLine(tmat.getX(x1,y1),tmat.getY(x1,y1),tmat.getX(x2,y1),tmat.getY(x2,y1),FRAC);
212 gd->drawLine(tmat.getX(x2,y1),tmat.getY(x2,y1),tmat.getX(x2,y2),tmat.getY(x2,y2),FRAC);
213 gd->drawLine(tmat.getX(x2,y2),tmat.getY(x2,y2),tmat.getX(x1,y2),tmat.getY(x1,y2),FRAC);
214 gd->drawLine(tmat.getX(x1,y2),tmat.getY(x1,y2),tmat.getX(x1,y1),tmat.getY(x1,y1),FRAC);
215 }
216
217 return 0;
218}
219
220////////// TextRecord Methods
221TextRecord::TextRecord() {
222 flags = (TextFlags)0;
223 font = 0;
224 fontHeight = 0;
225 nbGlyphs = 0;
226 glyphs = 0;
227 xOffset = 0;
228 yOffset = 0;
229}
230
231TextRecord::~TextRecord() {
232 if (nbGlyphs) delete glyphs;
233}
234
235char *
236TextRecord::getText() {
237 static char text[256];
238 long g;
239
240 for(g=0; g < nbGlyphs; g++) {
241 text[g] = glyphs[g].code;
242 }
243 text[g] = 0;
244
245 return text;
246}
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 @@
1/////////////////////////////////////////////////////////////
2// Flash Plugin and Player
3// Copyright (C) 1998,1999 Olivier Debon
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19///////////////////////////////////////////////////////////////
20#ifndef _TEXT_H_
21#define _TEXT_H_
22
23struct Glyph {
24 longindex;
25 longxAdvance;
26 long code;// Ascii code
27};
28
29struct TextRecord {
30
31 // Normal text record
32 Glyph *glyphs;
33 long nbGlyphs;
34
35 // Control text record
36 TextFlags flags;
37 SwfFont *font;
38 long fontHeight;
39 Color color;
40 long xOffset;
41 long yOffset;
42
43 TextRecord *next;
44
45 TextRecord();
46 ~TextRecord();
47
48 char *getText();
49};
50
51class Text : public Character {
52
53 Rect boundary;
54 Matrix textMatrix;
55 TextRecord *textRecords;// List
56
57public:
58 Text(long id);
59 ~Text();
60
61 void setTextBoundary(Rect rect);
62 void setTextMatrix(Matrix m);
63 void addTextRecord(TextRecord *tr);
64 int execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform);
65 void getRegion(GraphicDevice *gd, Matrix *matrix,
66 void *id, ScanLineFunc scan_line_func);
67 int doText(GraphicDevice *gd, Matrix *matrix, Cxform *cxform, ShapeAction action,
68 void *id, ScanLineFunc scan_line_func);
69 void getBoundingBox(Rect *bb, DisplayListEntry *e);
70 TextRecord *getTextRecords();
71
72#ifdef DUMP
73 void dump(BitStream *bs);
74#endif
75};
76
77#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 @@
1moc_*
2Makefile
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 @@
1/*
2 * mad - MPEG audio decoder
3 * Copyright (C) 2000-2001 Robert Leslie
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * $Id$
20 */
21
22/*
23 * These are the coefficients for the subband synthesis window. This is a
24 * reordered version of Table B.3 from ISO/IEC 11172-3.
25 *
26 * Every value is parameterized so that shift optimizations can be made at
27 * compile-time. For example, every value can be right-shifted 12 bits to
28 * minimize multiply instruction times without any loss of accuracy.
29 */
30
31 { PRESHIFT(0x00000000) /* 0.000000000 */,/* 0 */
32 -PRESHIFT(0x0001d000) /* -0.000442505 */,
33 PRESHIFT(0x000d5000) /* 0.003250122 */,
34 -PRESHIFT(0x001cb000) /* -0.007003784 */,
35 PRESHIFT(0x007f5000) /* 0.031082153 */,
36 -PRESHIFT(0x01421000) /* -0.078628540 */,
37 PRESHIFT(0x019ae000) /* 0.100311279 */,
38 -PRESHIFT(0x09271000) /* -0.572036743 */,
39 PRESHIFT(0x1251e000) /* 1.144989014 */,
40 PRESHIFT(0x09271000) /* 0.572036743 */,
41 PRESHIFT(0x019ae000) /* 0.100311279 */,
42 PRESHIFT(0x01421000) /* 0.078628540 */,
43 PRESHIFT(0x007f5000) /* 0.031082153 */,
44 PRESHIFT(0x001cb000) /* 0.007003784 */,
45 PRESHIFT(0x000d5000) /* 0.003250122 */,
46 PRESHIFT(0x0001d000) /* 0.000442505 */,
47
48 PRESHIFT(0x00000000) /* 0.000000000 */,
49 -PRESHIFT(0x0001d000) /* -0.000442505 */,
50 PRESHIFT(0x000d5000) /* 0.003250122 */,
51 -PRESHIFT(0x001cb000) /* -0.007003784 */,
52 PRESHIFT(0x007f5000) /* 0.031082153 */,
53 -PRESHIFT(0x01421000) /* -0.078628540 */,
54 PRESHIFT(0x019ae000) /* 0.100311279 */,
55 -PRESHIFT(0x09271000) /* -0.572036743 */,
56 PRESHIFT(0x1251e000) /* 1.144989014 */,
57 PRESHIFT(0x09271000) /* 0.572036743 */,
58 PRESHIFT(0x019ae000) /* 0.100311279 */,
59 PRESHIFT(0x01421000) /* 0.078628540 */,
60 PRESHIFT(0x007f5000) /* 0.031082153 */,
61 PRESHIFT(0x001cb000) /* 0.007003784 */,
62 PRESHIFT(0x000d5000) /* 0.003250122 */,
63 PRESHIFT(0x0001d000) /* 0.000442505 */ },
64
65 { -PRESHIFT(0x00001000) /* -0.000015259 */,/* 1 */
66 -PRESHIFT(0x0001f000) /* -0.000473022 */,
67 PRESHIFT(0x000da000) /* 0.003326416 */,
68 -PRESHIFT(0x00207000) /* -0.007919312 */,
69 PRESHIFT(0x007d0000) /* 0.030517578 */,
70 -PRESHIFT(0x0158d000) /* -0.084182739 */,
71 PRESHIFT(0x01747000) /* 0.090927124 */,
72 -PRESHIFT(0x099a8000) /* -0.600219727 */,
73 PRESHIFT(0x124f0000) /* 1.144287109 */,
74 PRESHIFT(0x08b38000) /* 0.543823242 */,
75 PRESHIFT(0x01bde000) /* 0.108856201 */,
76 PRESHIFT(0x012b4000) /* 0.073059082 */,
77 PRESHIFT(0x0080f000) /* 0.031478882 */,
78 PRESHIFT(0x00191000) /* 0.006118774 */,
79 PRESHIFT(0x000d0000) /* 0.003173828 */,
80 PRESHIFT(0x0001a000) /* 0.000396729 */,
81
82 -PRESHIFT(0x00001000) /* -0.000015259 */,
83 -PRESHIFT(0x0001f000) /* -0.000473022 */,
84 PRESHIFT(0x000da000) /* 0.003326416 */,
85 -PRESHIFT(0x00207000) /* -0.007919312 */,
86 PRESHIFT(0x007d0000) /* 0.030517578 */,
87 -PRESHIFT(0x0158d000) /* -0.084182739 */,
88 PRESHIFT(0x01747000) /* 0.090927124 */,
89 -PRESHIFT(0x099a8000) /* -0.600219727 */,
90 PRESHIFT(0x124f0000) /* 1.144287109 */,
91 PRESHIFT(0x08b38000) /* 0.543823242 */,
92 PRESHIFT(0x01bde000) /* 0.108856201 */,
93 PRESHIFT(0x012b4000) /* 0.073059082 */,
94 PRESHIFT(0x0080f000) /* 0.031478882 */,
95 PRESHIFT(0x00191000) /* 0.006118774 */,
96 PRESHIFT(0x000d0000) /* 0.003173828 */,
97 PRESHIFT(0x0001a000) /* 0.000396729 */ },
98
99 { -PRESHIFT(0x00001000) /* -0.000015259 */,/* 2 */
100 -PRESHIFT(0x00023000) /* -0.000534058 */,
101 PRESHIFT(0x000de000) /* 0.003387451 */,
102 -PRESHIFT(0x00245000) /* -0.008865356 */,
103 PRESHIFT(0x007a0000) /* 0.029785156 */,
104 -PRESHIFT(0x016f7000) /* -0.089706421 */,
105 PRESHIFT(0x014a8000) /* 0.080688477 */,
106 -PRESHIFT(0x0a0d8000) /* -0.628295898 */,
107 PRESHIFT(0x12468000) /* 1.142211914 */,
108 PRESHIFT(0x083ff000) /* 0.515609741 */,
109 PRESHIFT(0x01dd8000) /* 0.116577148 */,
110 PRESHIFT(0x01149000) /* 0.067520142 */,
111 PRESHIFT(0x00820000) /* 0.031738281 */,
112 PRESHIFT(0x0015b000) /* 0.005294800 */,
113 PRESHIFT(0x000ca000) /* 0.003082275 */,
114 PRESHIFT(0x00018000) /* 0.000366211 */,
115
116 -PRESHIFT(0x00001000) /* -0.000015259 */,
117 -PRESHIFT(0x00023000) /* -0.000534058 */,
118 PRESHIFT(0x000de000) /* 0.003387451 */,
119 -PRESHIFT(0x00245000) /* -0.008865356 */,
120 PRESHIFT(0x007a0000) /* 0.029785156 */,
121 -PRESHIFT(0x016f7000) /* -0.089706421 */,
122 PRESHIFT(0x014a8000) /* 0.080688477 */,
123 -PRESHIFT(0x0a0d8000) /* -0.628295898 */,
124 PRESHIFT(0x12468000) /* 1.142211914 */,
125 PRESHIFT(0x083ff000) /* 0.515609741 */,
126 PRESHIFT(0x01dd8000) /* 0.116577148 */,
127 PRESHIFT(0x01149000) /* 0.067520142 */,
128 PRESHIFT(0x00820000) /* 0.031738281 */,
129 PRESHIFT(0x0015b000) /* 0.005294800 */,
130 PRESHIFT(0x000ca000) /* 0.003082275 */,
131 PRESHIFT(0x00018000) /* 0.000366211 */ },
132
133 { -PRESHIFT(0x00001000) /* -0.000015259 */,/* 3 */
134 -PRESHIFT(0x00026000) /* -0.000579834 */,
135 PRESHIFT(0x000e1000) /* 0.003433228 */,
136 -PRESHIFT(0x00285000) /* -0.009841919 */,
137 PRESHIFT(0x00765000) /* 0.028884888 */,
138 -PRESHIFT(0x0185d000) /* -0.095169067 */,
139 PRESHIFT(0x011d1000) /* 0.069595337 */,
140 -PRESHIFT(0x0a7fe000) /* -0.656219482 */,
141 PRESHIFT(0x12386000) /* 1.138763428 */,
142 PRESHIFT(0x07ccb000) /* 0.487472534 */,
143 PRESHIFT(0x01f9c000) /* 0.123474121 */,
144 PRESHIFT(0x00fdf000) /* 0.061996460 */,
145 PRESHIFT(0x00827000) /* 0.031845093 */,
146 PRESHIFT(0x00126000) /* 0.004486084 */,
147 PRESHIFT(0x000c4000) /* 0.002990723 */,
148 PRESHIFT(0x00015000) /* 0.000320435 */,
149
150 -PRESHIFT(0x00001000) /* -0.000015259 */,
151 -PRESHIFT(0x00026000) /* -0.000579834 */,
152 PRESHIFT(0x000e1000) /* 0.003433228 */,
153 -PRESHIFT(0x00285000) /* -0.009841919 */,
154 PRESHIFT(0x00765000) /* 0.028884888 */,
155 -PRESHIFT(0x0185d000) /* -0.095169067 */,
156 PRESHIFT(0x011d1000) /* 0.069595337 */,
157 -PRESHIFT(0x0a7fe000) /* -0.656219482 */,
158 PRESHIFT(0x12386000) /* 1.138763428 */,
159 PRESHIFT(0x07ccb000) /* 0.487472534 */,
160 PRESHIFT(0x01f9c000) /* 0.123474121 */,
161 PRESHIFT(0x00fdf000) /* 0.061996460 */,
162 PRESHIFT(0x00827000) /* 0.031845093 */,
163 PRESHIFT(0x00126000) /* 0.004486084 */,
164 PRESHIFT(0x000c4000) /* 0.002990723 */,
165 PRESHIFT(0x00015000) /* 0.000320435 */ },
166
167 { -PRESHIFT(0x00001000) /* -0.000015259 */,/* 4 */
168 -PRESHIFT(0x00029000) /* -0.000625610 */,
169 PRESHIFT(0x000e3000) /* 0.003463745 */,
170 -PRESHIFT(0x002c7000) /* -0.010848999 */,
171 PRESHIFT(0x0071e000) /* 0.027801514 */,
172 -PRESHIFT(0x019bd000) /* -0.100540161 */,
173 PRESHIFT(0x00ec0000) /* 0.057617187 */,
174 -PRESHIFT(0x0af15000) /* -0.683914185 */,
175 PRESHIFT(0x12249000) /* 1.133926392 */,
176 PRESHIFT(0x075a0000) /* 0.459472656 */,
177 PRESHIFT(0x0212c000) /* 0.129577637 */,
178 PRESHIFT(0x00e79000) /* 0.056533813 */,
179 PRESHIFT(0x00825000) /* 0.031814575 */,
180 PRESHIFT(0x000f4000) /* 0.003723145 */,
181 PRESHIFT(0x000be000) /* 0.002899170 */,
182 PRESHIFT(0x00013000) /* 0.000289917 */,
183
184 -PRESHIFT(0x00001000) /* -0.000015259 */,
185 -PRESHIFT(0x00029000) /* -0.000625610 */,
186 PRESHIFT(0x000e3000) /* 0.003463745 */,
187 -PRESHIFT(0x002c7000) /* -0.010848999 */,
188 PRESHIFT(0x0071e000) /* 0.027801514 */,
189 -PRESHIFT(0x019bd000) /* -0.100540161 */,
190 PRESHIFT(0x00ec0000) /* 0.057617187 */,
191 -PRESHIFT(0x0af15000) /* -0.683914185 */,
192 PRESHIFT(0x12249000) /* 1.133926392 */,
193 PRESHIFT(0x075a0000) /* 0.459472656 */,
194 PRESHIFT(0x0212c000) /* 0.129577637 */,
195 PRESHIFT(0x00e79000) /* 0.056533813 */,
196 PRESHIFT(0x00825000) /* 0.031814575 */,
197 PRESHIFT(0x000f4000) /* 0.003723145 */,
198 PRESHIFT(0x000be000) /* 0.002899170 */,
199 PRESHIFT(0x00013000) /* 0.000289917 */ },
200
201 { -PRESHIFT(0x00001000) /* -0.000015259 */,/* 5 */
202 -PRESHIFT(0x0002d000) /* -0.000686646 */,
203 PRESHIFT(0x000e4000) /* 0.003479004 */,
204 -PRESHIFT(0x0030b000) /* -0.011886597 */,
205 PRESHIFT(0x006cb000) /* 0.026535034 */,
206 -PRESHIFT(0x01b17000) /* -0.105819702 */,
207 PRESHIFT(0x00b77000) /* 0.044784546 */,
208 -PRESHIFT(0x0b619000) /* -0.711318970 */,
209 PRESHIFT(0x120b4000) /* 1.127746582 */,
210 PRESHIFT(0x06e81000) /* 0.431655884 */,
211 PRESHIFT(0x02288000) /* 0.134887695 */,
212 PRESHIFT(0x00d17000) /* 0.051132202 */,
213 PRESHIFT(0x0081b000) /* 0.031661987 */,
214 PRESHIFT(0x000c5000) /* 0.003005981 */,
215 PRESHIFT(0x000b7000) /* 0.002792358 */,
216 PRESHIFT(0x00011000) /* 0.000259399 */,
217
218 -PRESHIFT(0x00001000) /* -0.000015259 */,
219 -PRESHIFT(0x0002d000) /* -0.000686646 */,
220 PRESHIFT(0x000e4000) /* 0.003479004 */,
221 -PRESHIFT(0x0030b000) /* -0.011886597 */,
222 PRESHIFT(0x006cb000) /* 0.026535034 */,
223 -PRESHIFT(0x01b17000) /* -0.105819702 */,
224 PRESHIFT(0x00b77000) /* 0.044784546 */,
225 -PRESHIFT(0x0b619000) /* -0.711318970 */,
226 PRESHIFT(0x120b4000) /* 1.127746582 */,
227 PRESHIFT(0x06e81000) /* 0.431655884 */,
228 PRESHIFT(0x02288000) /* 0.134887695 */,
229 PRESHIFT(0x00d17000) /* 0.051132202 */,
230 PRESHIFT(0x0081b000) /* 0.031661987 */,
231 PRESHIFT(0x000c5000) /* 0.003005981 */,
232 PRESHIFT(0x000b7000) /* 0.002792358 */,
233 PRESHIFT(0x00011000) /* 0.000259399 */ },
234
235 { -PRESHIFT(0x00001000) /* -0.000015259 */,/* 6 */
236 -PRESHIFT(0x00031000) /* -0.000747681 */,
237 PRESHIFT(0x000e4000) /* 0.003479004 */,
238 -PRESHIFT(0x00350000) /* -0.012939453 */,
239 PRESHIFT(0x0066c000) /* 0.025085449 */,
240 -PRESHIFT(0x01c67000) /* -0.110946655 */,
241 PRESHIFT(0x007f5000) /* 0.031082153 */,
242 -PRESHIFT(0x0bd06000) /* -0.738372803 */,
243 PRESHIFT(0x11ec7000) /* 1.120223999 */,
244 PRESHIFT(0x06772000) /* 0.404083252 */,
245 PRESHIFT(0x023b3000) /* 0.139450073 */,
246 PRESHIFT(0x00bbc000) /* 0.045837402 */,
247 PRESHIFT(0x00809000) /* 0.031387329 */,
248 PRESHIFT(0x00099000) /* 0.002334595 */,
249 PRESHIFT(0x000b0000) /* 0.002685547 */,
250 PRESHIFT(0x00010000) /* 0.000244141 */,
251
252 -PRESHIFT(0x00001000) /* -0.000015259 */,
253 -PRESHIFT(0x00031000) /* -0.000747681 */,
254 PRESHIFT(0x000e4000) /* 0.003479004 */,
255 -PRESHIFT(0x00350000) /* -0.012939453 */,
256 PRESHIFT(0x0066c000) /* 0.025085449 */,
257 -PRESHIFT(0x01c67000) /* -0.110946655 */,
258 PRESHIFT(0x007f5000) /* 0.031082153 */,
259 -PRESHIFT(0x0bd06000) /* -0.738372803 */,
260 PRESHIFT(0x11ec7000) /* 1.120223999 */,
261 PRESHIFT(0x06772000) /* 0.404083252 */,
262 PRESHIFT(0x023b3000) /* 0.139450073 */,
263 PRESHIFT(0x00bbc000) /* 0.045837402 */,
264 PRESHIFT(0x00809000) /* 0.031387329 */,
265 PRESHIFT(0x00099000) /* 0.002334595 */,
266 PRESHIFT(0x000b0000) /* 0.002685547 */,
267 PRESHIFT(0x00010000) /* 0.000244141 */ },
268
269 { -PRESHIFT(0x00002000) /* -0.000030518 */,/* 7 */
270 -PRESHIFT(0x00035000) /* -0.000808716 */,
271 PRESHIFT(0x000e3000) /* 0.003463745 */,
272 -PRESHIFT(0x00397000) /* -0.014022827 */,
273 PRESHIFT(0x005ff000) /* 0.023422241 */,
274 -PRESHIFT(0x01dad000) /* -0.115921021 */,
275 PRESHIFT(0x0043a000) /* 0.016510010 */,
276 -PRESHIFT(0x0c3d9000) /* -0.765029907 */,
277 PRESHIFT(0x11c83000) /* 1.111373901 */,
278 PRESHIFT(0x06076000) /* 0.376800537 */,
279 PRESHIFT(0x024ad000) /* 0.143264771 */,
280 PRESHIFT(0x00a67000) /* 0.040634155 */,
281 PRESHIFT(0x007f0000) /* 0.031005859 */,
282 PRESHIFT(0x0006f000) /* 0.001693726 */,
283 PRESHIFT(0x000a9000) /* 0.002578735 */,
284 PRESHIFT(0x0000e000) /* 0.000213623 */,
285
286 -PRESHIFT(0x00002000) /* -0.000030518 */,
287 -PRESHIFT(0x00035000) /* -0.000808716 */,
288 PRESHIFT(0x000e3000) /* 0.003463745 */,
289 -PRESHIFT(0x00397000) /* -0.014022827 */,
290 PRESHIFT(0x005ff000) /* 0.023422241 */,
291 -PRESHIFT(0x01dad000) /* -0.115921021 */,
292 PRESHIFT(0x0043a000) /* 0.016510010 */,
293 -PRESHIFT(0x0c3d9000) /* -0.765029907 */,
294 PRESHIFT(0x11c83000) /* 1.111373901 */,
295 PRESHIFT(0x06076000) /* 0.376800537 */,
296 PRESHIFT(0x024ad000) /* 0.143264771 */,
297 PRESHIFT(0x00a67000) /* 0.040634155 */,
298 PRESHIFT(0x007f0000) /* 0.031005859 */,
299 PRESHIFT(0x0006f000) /* 0.001693726 */,
300 PRESHIFT(0x000a9000) /* 0.002578735 */,
301 PRESHIFT(0x0000e000) /* 0.000213623 */ },
302
303 { -PRESHIFT(0x00002000) /* -0.000030518 */,/* 8 */
304 -PRESHIFT(0x0003a000) /* -0.000885010 */,
305 PRESHIFT(0x000e0000) /* 0.003417969 */,
306 -PRESHIFT(0x003df000) /* -0.015121460 */,
307 PRESHIFT(0x00586000) /* 0.021575928 */,
308 -PRESHIFT(0x01ee6000) /* -0.120697021 */,
309 PRESHIFT(0x00046000) /* 0.001068115 */,
310 -PRESHIFT(0x0ca8d000) /* -0.791213989 */,
311 PRESHIFT(0x119e9000) /* 1.101211548 */,
312 PRESHIFT(0x05991000) /* 0.349868774 */,
313 PRESHIFT(0x02578000) /* 0.146362305 */,
314 PRESHIFT(0x0091a000) /* 0.035552979 */,
315 PRESHIFT(0x007d1000) /* 0.030532837 */,
316 PRESHIFT(0x00048000) /* 0.001098633 */,
317 PRESHIFT(0x000a1000) /* 0.002456665 */,
318 PRESHIFT(0x0000d000) /* 0.000198364 */,
319
320 -PRESHIFT(0x00002000) /* -0.000030518 */,
321 -PRESHIFT(0x0003a000) /* -0.000885010 */,
322 PRESHIFT(0x000e0000) /* 0.003417969 */,
323 -PRESHIFT(0x003df000) /* -0.015121460 */,
324 PRESHIFT(0x00586000) /* 0.021575928 */,
325 -PRESHIFT(0x01ee6000) /* -0.120697021 */,
326 PRESHIFT(0x00046000) /* 0.001068115 */,
327 -PRESHIFT(0x0ca8d000) /* -0.791213989 */,
328 PRESHIFT(0x119e9000) /* 1.101211548 */,
329 PRESHIFT(0x05991000) /* 0.349868774 */,
330 PRESHIFT(0x02578000) /* 0.146362305 */,
331 PRESHIFT(0x0091a000) /* 0.035552979 */,
332 PRESHIFT(0x007d1000) /* 0.030532837 */,
333 PRESHIFT(0x00048000) /* 0.001098633 */,
334 PRESHIFT(0x000a1000) /* 0.002456665 */,
335 PRESHIFT(0x0000d000) /* 0.000198364 */ },
336
337 { -PRESHIFT(0x00002000) /* -0.000030518 */,/* 9 */
338 -PRESHIFT(0x0003f000) /* -0.000961304 */,
339 PRESHIFT(0x000dd000) /* 0.003372192 */,
340 -PRESHIFT(0x00428000) /* -0.016235352 */,
341 PRESHIFT(0x00500000) /* 0.019531250 */,
342 -PRESHIFT(0x02011000) /* -0.125259399 */,
343 -PRESHIFT(0x003e6000) /* -0.015228271 */,
344 -PRESHIFT(0x0d11e000) /* -0.816864014 */,
345 PRESHIFT(0x116fc000) /* 1.089782715 */,
346 PRESHIFT(0x052c5000) /* 0.323318481 */,
347 PRESHIFT(0x02616000) /* 0.148773193 */,
348 PRESHIFT(0x007d6000) /* 0.030609131 */,
349 PRESHIFT(0x007aa000) /* 0.029937744 */,
350 PRESHIFT(0x00024000) /* 0.000549316 */,
351 PRESHIFT(0x0009a000) /* 0.002349854 */,
352 PRESHIFT(0x0000b000) /* 0.000167847 */,
353
354 -PRESHIFT(0x00002000) /* -0.000030518 */,
355 -PRESHIFT(0x0003f000) /* -0.000961304 */,
356 PRESHIFT(0x000dd000) /* 0.003372192 */,
357 -PRESHIFT(0x00428000) /* -0.016235352 */,
358 PRESHIFT(0x00500000) /* 0.019531250 */,
359 -PRESHIFT(0x02011000) /* -0.125259399 */,
360 -PRESHIFT(0x003e6000) /* -0.015228271 */,
361 -PRESHIFT(0x0d11e000) /* -0.816864014 */,
362 PRESHIFT(0x116fc000) /* 1.089782715 */,
363 PRESHIFT(0x052c5000) /* 0.323318481 */,
364 PRESHIFT(0x02616000) /* 0.148773193 */,
365 PRESHIFT(0x007d6000) /* 0.030609131 */,
366 PRESHIFT(0x007aa000) /* 0.029937744 */,
367 PRESHIFT(0x00024000) /* 0.000549316 */,
368 PRESHIFT(0x0009a000) /* 0.002349854 */,
369 PRESHIFT(0x0000b000) /* 0.000167847 */ },
370
371 { -PRESHIFT(0x00002000) /* -0.000030518 */,/* 10 */
372 -PRESHIFT(0x00044000) /* -0.001037598 */,
373 PRESHIFT(0x000d7000) /* 0.003280640 */,
374 -PRESHIFT(0x00471000) /* -0.017349243 */,
375 PRESHIFT(0x0046b000) /* 0.017257690 */,
376 -PRESHIFT(0x0212b000) /* -0.129562378 */,
377 -PRESHIFT(0x0084a000) /* -0.032379150 */,
378 -PRESHIFT(0x0d78a000) /* -0.841949463 */,
379 PRESHIFT(0x113be000) /* 1.077117920 */,
380 PRESHIFT(0x04c16000) /* 0.297210693 */,
381 PRESHIFT(0x02687000) /* 0.150497437 */,
382 PRESHIFT(0x0069c000) /* 0.025817871 */,
383 PRESHIFT(0x0077f000) /* 0.029281616 */,
384 PRESHIFT(0x00002000) /* 0.000030518 */,
385 PRESHIFT(0x00093000) /* 0.002243042 */,
386 PRESHIFT(0x0000a000) /* 0.000152588 */,
387
388 -PRESHIFT(0x00002000) /* -0.000030518 */,
389 -PRESHIFT(0x00044000) /* -0.001037598 */,
390 PRESHIFT(0x000d7000) /* 0.003280640 */,
391 -PRESHIFT(0x00471000) /* -0.017349243 */,
392 PRESHIFT(0x0046b000) /* 0.017257690 */,
393 -PRESHIFT(0x0212b000) /* -0.129562378 */,
394 -PRESHIFT(0x0084a000) /* -0.032379150 */,
395 -PRESHIFT(0x0d78a000) /* -0.841949463 */,
396 PRESHIFT(0x113be000) /* 1.077117920 */,
397 PRESHIFT(0x04c16000) /* 0.297210693 */,
398 PRESHIFT(0x02687000) /* 0.150497437 */,
399 PRESHIFT(0x0069c000) /* 0.025817871 */,
400 PRESHIFT(0x0077f000) /* 0.029281616 */,
401 PRESHIFT(0x00002000) /* 0.000030518 */,
402 PRESHIFT(0x00093000) /* 0.002243042 */,
403 PRESHIFT(0x0000a000) /* 0.000152588 */ },
404
405 { -PRESHIFT(0x00003000) /* -0.000045776 */,/* 11 */
406 -PRESHIFT(0x00049000) /* -0.001113892 */,
407 PRESHIFT(0x000d0000) /* 0.003173828 */,
408 -PRESHIFT(0x004ba000) /* -0.018463135 */,
409 PRESHIFT(0x003ca000) /* 0.014801025 */,
410 -PRESHIFT(0x02233000) /* -0.133590698 */,
411 -PRESHIFT(0x00ce4000) /* -0.050354004 */,
412 -PRESHIFT(0x0ddca000) /* -0.866363525 */,
413 PRESHIFT(0x1102f000) /* 1.063217163 */,
414 PRESHIFT(0x04587000) /* 0.271591187 */,
415 PRESHIFT(0x026cf000) /* 0.151596069 */,
416 PRESHIFT(0x0056c000) /* 0.021179199 */,
417 PRESHIFT(0x0074e000) /* 0.028533936 */,
418 -PRESHIFT(0x0001d000) /* -0.000442505 */,
419 PRESHIFT(0x0008b000) /* 0.002120972 */,
420 PRESHIFT(0x00009000) /* 0.000137329 */,
421
422 -PRESHIFT(0x00003000) /* -0.000045776 */,
423 -PRESHIFT(0x00049000) /* -0.001113892 */,
424 PRESHIFT(0x000d0000) /* 0.003173828 */,
425 -PRESHIFT(0x004ba000) /* -0.018463135 */,
426 PRESHIFT(0x003ca000) /* 0.014801025 */,
427 -PRESHIFT(0x02233000) /* -0.133590698 */,
428 -PRESHIFT(0x00ce4000) /* -0.050354004 */,
429 -PRESHIFT(0x0ddca000) /* -0.866363525 */,
430 PRESHIFT(0x1102f000) /* 1.063217163 */,
431 PRESHIFT(0x04587000) /* 0.271591187 */,
432 PRESHIFT(0x026cf000) /* 0.151596069 */,
433 PRESHIFT(0x0056c000) /* 0.021179199 */,
434 PRESHIFT(0x0074e000) /* 0.028533936 */,
435 -PRESHIFT(0x0001d000) /* -0.000442505 */,
436 PRESHIFT(0x0008b000) /* 0.002120972 */,
437 PRESHIFT(0x00009000) /* 0.000137329 */ },
438
439 { -PRESHIFT(0x00003000) /* -0.000045776 */,/* 12 */
440 -PRESHIFT(0x0004f000) /* -0.001205444 */,
441 PRESHIFT(0x000c8000) /* 0.003051758 */,
442 -PRESHIFT(0x00503000) /* -0.019577026 */,
443 PRESHIFT(0x0031a000) /* 0.012115479 */,
444 -PRESHIFT(0x02326000) /* -0.137298584 */,
445 -PRESHIFT(0x011b5000) /* -0.069168091 */,
446 -PRESHIFT(0x0e3dd000) /* -0.890090942 */,
447 PRESHIFT(0x10c54000) /* 1.048156738 */,
448 PRESHIFT(0x03f1b000) /* 0.246505737 */,
449 PRESHIFT(0x026ee000) /* 0.152069092 */,
450 PRESHIFT(0x00447000) /* 0.016708374 */,
451 PRESHIFT(0x00719000) /* 0.027725220 */,
452 -PRESHIFT(0x00039000) /* -0.000869751 */,
453 PRESHIFT(0x00084000) /* 0.002014160 */,
454 PRESHIFT(0x00008000) /* 0.000122070 */,
455
456 -PRESHIFT(0x00003000) /* -0.000045776 */,
457 -PRESHIFT(0x0004f000) /* -0.001205444 */,
458 PRESHIFT(0x000c8000) /* 0.003051758 */,
459 -PRESHIFT(0x00503000) /* -0.019577026 */,
460 PRESHIFT(0x0031a000) /* 0.012115479 */,
461 -PRESHIFT(0x02326000) /* -0.137298584 */,
462 -PRESHIFT(0x011b5000) /* -0.069168091 */,
463 -PRESHIFT(0x0e3dd000) /* -0.890090942 */,
464 PRESHIFT(0x10c54000) /* 1.048156738 */,
465 PRESHIFT(0x03f1b000) /* 0.246505737 */,
466 PRESHIFT(0x026ee000) /* 0.152069092 */,
467 PRESHIFT(0x00447000) /* 0.016708374 */,
468 PRESHIFT(0x00719000) /* 0.027725220 */,
469 -PRESHIFT(0x00039000) /* -0.000869751 */,
470 PRESHIFT(0x00084000) /* 0.002014160 */,
471 PRESHIFT(0x00008000) /* 0.000122070 */ },
472
473 { -PRESHIFT(0x00004000) /* -0.000061035 */,/* 13 */
474 -PRESHIFT(0x00055000) /* -0.001296997 */,
475 PRESHIFT(0x000bd000) /* 0.002883911 */,
476 -PRESHIFT(0x0054c000) /* -0.020690918 */,
477 PRESHIFT(0x0025d000) /* 0.009231567 */,
478 -PRESHIFT(0x02403000) /* -0.140670776 */,
479 -PRESHIFT(0x016ba000) /* -0.088775635 */,
480 -PRESHIFT(0x0e9be000) /* -0.913055420 */,
481 PRESHIFT(0x1082d000) /* 1.031936646 */,
482 PRESHIFT(0x038d4000) /* 0.221984863 */,
483 PRESHIFT(0x026e7000) /* 0.151962280 */,
484 PRESHIFT(0x0032e000) /* 0.012420654 */,
485 PRESHIFT(0x006df000) /* 0.026840210 */,
486 -PRESHIFT(0x00053000) /* -0.001266479 */,
487 PRESHIFT(0x0007d000) /* 0.001907349 */,
488 PRESHIFT(0x00007000) /* 0.000106812 */,
489
490 -PRESHIFT(0x00004000) /* -0.000061035 */,
491 -PRESHIFT(0x00055000) /* -0.001296997 */,
492 PRESHIFT(0x000bd000) /* 0.002883911 */,
493 -PRESHIFT(0x0054c000) /* -0.020690918 */,
494 PRESHIFT(0x0025d000) /* 0.009231567 */,
495 -PRESHIFT(0x02403000) /* -0.140670776 */,
496 -PRESHIFT(0x016ba000) /* -0.088775635 */,
497 -PRESHIFT(0x0e9be000) /* -0.913055420 */,
498 PRESHIFT(0x1082d000) /* 1.031936646 */,
499 PRESHIFT(0x038d4000) /* 0.221984863 */,
500 PRESHIFT(0x026e7000) /* 0.151962280 */,
501 PRESHIFT(0x0032e000) /* 0.012420654 */,
502 PRESHIFT(0x006df000) /* 0.026840210 */,
503 -PRESHIFT(0x00053000) /* -0.001266479 */,
504 PRESHIFT(0x0007d000) /* 0.001907349 */,
505 PRESHIFT(0x00007000) /* 0.000106812 */ },
506
507 { -PRESHIFT(0x00004000) /* -0.000061035 */,/* 14 */
508 -PRESHIFT(0x0005b000) /* -0.001388550 */,
509 PRESHIFT(0x000b1000) /* 0.002700806 */,
510 -PRESHIFT(0x00594000) /* -0.021789551 */,
511 PRESHIFT(0x00192000) /* 0.006134033 */,
512 -PRESHIFT(0x024c8000) /* -0.143676758 */,
513 -PRESHIFT(0x01bf2000) /* -0.109161377 */,
514 -PRESHIFT(0x0ef69000) /* -0.935195923 */,
515 PRESHIFT(0x103be000) /* 1.014617920 */,
516 PRESHIFT(0x032b4000) /* 0.198059082 */,
517 PRESHIFT(0x026bc000) /* 0.151306152 */,
518 PRESHIFT(0x00221000) /* 0.008316040 */,
519 PRESHIFT(0x006a2000) /* 0.025909424 */,
520 -PRESHIFT(0x0006a000) /* -0.001617432 */,
521 PRESHIFT(0x00075000) /* 0.001785278 */,
522 PRESHIFT(0x00007000) /* 0.000106812 */,
523
524 -PRESHIFT(0x00004000) /* -0.000061035 */,
525 -PRESHIFT(0x0005b000) /* -0.001388550 */,
526 PRESHIFT(0x000b1000) /* 0.002700806 */,
527 -PRESHIFT(0x00594000) /* -0.021789551 */,
528 PRESHIFT(0x00192000) /* 0.006134033 */,
529 -PRESHIFT(0x024c8000) /* -0.143676758 */,
530 -PRESHIFT(0x01bf2000) /* -0.109161377 */,
531 -PRESHIFT(0x0ef69000) /* -0.935195923 */,
532 PRESHIFT(0x103be000) /* 1.014617920 */,
533 PRESHIFT(0x032b4000) /* 0.198059082 */,
534 PRESHIFT(0x026bc000) /* 0.151306152 */,
535 PRESHIFT(0x00221000) /* 0.008316040 */,
536 PRESHIFT(0x006a2000) /* 0.025909424 */,
537 -PRESHIFT(0x0006a000) /* -0.001617432 */,
538 PRESHIFT(0x00075000) /* 0.001785278 */,
539 PRESHIFT(0x00007000) /* 0.000106812 */ },
540
541 { -PRESHIFT(0x00005000) /* -0.000076294 */,/* 15 */
542 -PRESHIFT(0x00061000) /* -0.001480103 */,
543 PRESHIFT(0x000a3000) /* 0.002487183 */,
544 -PRESHIFT(0x005da000) /* -0.022857666 */,
545 PRESHIFT(0x000b9000) /* 0.002822876 */,
546 -PRESHIFT(0x02571000) /* -0.146255493 */,
547 -PRESHIFT(0x0215c000) /* -0.130310059 */,
548 -PRESHIFT(0x0f4dc000) /* -0.956481934 */,
549 PRESHIFT(0x0ff0a000) /* 0.996246338 */,
550 PRESHIFT(0x02cbf000) /* 0.174789429 */,
551 PRESHIFT(0x0266e000) /* 0.150115967 */,
552 PRESHIFT(0x00120000) /* 0.004394531 */,
553 PRESHIFT(0x00662000) /* 0.024932861 */,
554 -PRESHIFT(0x0007f000) /* -0.001937866 */,
555 PRESHIFT(0x0006f000) /* 0.001693726 */,
556 PRESHIFT(0x00006000) /* 0.000091553 */,
557
558 -PRESHIFT(0x00005000) /* -0.000076294 */,
559 -PRESHIFT(0x00061000) /* -0.001480103 */,
560 PRESHIFT(0x000a3000) /* 0.002487183 */,
561 -PRESHIFT(0x005da000) /* -0.022857666 */,
562 PRESHIFT(0x000b9000) /* 0.002822876 */,
563 -PRESHIFT(0x02571000) /* -0.146255493 */,
564 -PRESHIFT(0x0215c000) /* -0.130310059 */,
565 -PRESHIFT(0x0f4dc000) /* -0.956481934 */,
566 PRESHIFT(0x0ff0a000) /* 0.996246338 */,
567 PRESHIFT(0x02cbf000) /* 0.174789429 */,
568 PRESHIFT(0x0266e000) /* 0.150115967 */,
569 PRESHIFT(0x00120000) /* 0.004394531 */,
570 PRESHIFT(0x00662000) /* 0.024932861 */,
571 -PRESHIFT(0x0007f000) /* -0.001937866 */,
572 PRESHIFT(0x0006f000) /* 0.001693726 */,
573 PRESHIFT(0x00006000) /* 0.000091553 */ },
574
575 { -PRESHIFT(0x00005000) /* -0.000076294 */,/* 16 */
576 -PRESHIFT(0x00068000) /* -0.001586914 */,
577 PRESHIFT(0x00092000) /* 0.002227783 */,
578 -PRESHIFT(0x0061f000) /* -0.023910522 */,
579 -PRESHIFT(0x0002d000) /* -0.000686646 */,
580 -PRESHIFT(0x025ff000) /* -0.148422241 */,
581 -PRESHIFT(0x026f7000) /* -0.152206421 */,
582 -PRESHIFT(0x0fa13000) /* -0.976852417 */,
583 PRESHIFT(0x0fa13000) /* 0.976852417 */,
584 PRESHIFT(0x026f7000) /* 0.152206421 */,
585 PRESHIFT(0x025ff000) /* 0.148422241 */,
586 PRESHIFT(0x0002d000) /* 0.000686646 */,
587 PRESHIFT(0x0061f000) /* 0.023910522 */,
588 -PRESHIFT(0x00092000) /* -0.002227783 */,
589 PRESHIFT(0x00068000) /* 0.001586914 */,
590 PRESHIFT(0x00005000) /* 0.000076294 */,
591
592 -PRESHIFT(0x00005000) /* -0.000076294 */,
593 -PRESHIFT(0x00068000) /* -0.001586914 */,
594 PRESHIFT(0x00092000) /* 0.002227783 */,
595 -PRESHIFT(0x0061f000) /* -0.023910522 */,
596 -PRESHIFT(0x0002d000) /* -0.000686646 */,
597 -PRESHIFT(0x025ff000) /* -0.148422241 */,
598 -PRESHIFT(0x026f7000) /* -0.152206421 */,
599 -PRESHIFT(0x0fa13000) /* -0.976852417 */,
600 PRESHIFT(0x0fa13000) /* 0.976852417 */,
601 PRESHIFT(0x026f7000) /* 0.152206421 */,
602 PRESHIFT(0x025ff000) /* 0.148422241 */,
603 PRESHIFT(0x0002d000) /* 0.000686646 */,
604 PRESHIFT(0x0061f000) /* 0.023910522 */,
605 -PRESHIFT(0x00092000) /* -0.002227783 */,
606 PRESHIFT(0x00068000) /* 0.001586914 */,
607 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 @@
1#############################################################################
2
3####### Compiler, tools and options
4
5 CXX =$(SYSCONF_CXX) $(QT_CXX_MT)
6 CXXFLAGS=$(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS) $(SYSCONF_CXXFLAGS_LIB) -DQCONFIG=\"qpe\"
7 CC =$(SYSCONF_CC) $(QT_C_MT)
8 CFLAGS =$(SYSCONF_CFLAGS) $(SYSCONF_CFLAGS_LIB) -DQCONFIG=\"qpe\"
9 INCPATH =-I$(QPEDIR)/include -I..
10 LFLAGS =$(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
11 LIBS =$(SUBLIBS) -lqpe -lm $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS_QTAPP)
12 MOC =$(SYSCONF_MOC)
13 UIC =$(SYSCONF_UIC)
14
15####### Target
16
17DESTDIR = ../../plugins/codecs/
18VER_MAJ = 1
19VER_MIN = 0
20VER_PATCH = 0
21 TARGET= madplugin
22TARGET1 = lib$(TARGET).so.$(VER_MAJ)
23
24####### Files
25
26 HEADERS =libmad_version.h \
27 fixed.h \
28 bit.h \
29 timer.h \
30 stream.h \
31 frame.h \
32 synth.h \
33 decoder.h \
34 layer12.h \
35 layer3.h \
36 huffman.h \
37 libmad_global.h \
38 mad.h \
39 libmadplugin.h \
40 libmadpluginimpl.h
41 SOURCES =version.c \
42 fixed.c \
43 bit.c \
44 timer.c \
45 stream.c \
46 frame.c \
47 synth.c \
48 decoder.c \
49 layer12.c \
50 layer3.c \
51 huffman.c \
52 libmadplugin.cpp \
53 libmadpluginimpl.cpp
54 OBJECTS =version.o \
55 fixed.o \
56 bit.o \
57 timer.o \
58 stream.o \
59 frame.o \
60 synth.o \
61 decoder.o \
62 layer12.o \
63 layer3.o \
64 huffman.o \
65 libmadplugin.o \
66 libmadpluginimpl.o
67INTERFACES =
68UICDECLS =
69UICIMPLS =
70 SRCMOC =
71 OBJMOC =
72
73
74####### Implicit rules
75
76.SUFFIXES: .cpp .cxx .cc .C .c
77
78.cpp.o:
79 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
80
81.cxx.o:
82 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
83
84.cc.o:
85 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
86
87.C.o:
88 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
89
90.c.o:
91 $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
92
93####### Build rules
94
95
96all: $(DESTDIR)$(SYSCONF_LINK_TARGET)
97
98$(DESTDIR)$(SYSCONF_LINK_TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
99 $(SYSCONF_LINK_LIB)
100
101moc: $(SRCMOC)
102
103tmake:
104 tmake libmad.pro
105
106clean:
107 -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
108 -rm -f *~ core
109 -rm -f allmoc.cpp
110
111####### Extension Modules
112
113listpromodules:
114 @echo
115
116listallmodules:
117 @echo
118
119listaddonpromodules:
120 @echo
121
122listaddonentmodules:
123 @echo
124
125
126REQUIRES=
127
128####### Sub-libraries
129
130
131###### Combined headers
132
133
134
135####### Compile
136
137version.o: version.c \
138 libmad_global.h \
139 libmad_version.h
140
141fixed.o: fixed.c \
142 libmad_global.h \
143 fixed.h
144
145bit.o: bit.c \
146 libmad_global.h \
147 bit.h
148
149timer.o: timer.c \
150 libmad_global.h \
151 timer.h
152
153stream.o: stream.c \
154 libmad_global.h \
155 bit.h \
156 stream.h
157
158frame.o: frame.c \
159 libmad_global.h \
160 bit.h \
161 stream.h \
162 frame.h \
163 fixed.h \
164 timer.h \
165 layer12.h \
166 layer3.h
167
168synth.o: synth.c \
169 libmad_global.h \
170 fixed.h \
171 frame.h \
172 timer.h \
173 stream.h \
174 bit.h \
175 synth.h \
176 D.dat
177
178decoder.o: decoder.c \
179 libmad_global.h \
180 stream.h \
181 bit.h \
182 frame.h \
183 fixed.h \
184 timer.h \
185 synth.h \
186 decoder.h
187
188layer12.o: layer12.c \
189 libmad_global.h \
190 fixed.h \
191 bit.h \
192 stream.h \
193 frame.h \
194 timer.h \
195 layer12.h \
196 sf_table.dat \
197 qc_table.dat
198
199layer3.o: layer3.c \
200 libmad_global.h \
201 fixed.h \
202 bit.h \
203 stream.h \
204 frame.h \
205 timer.h \
206 huffman.h \
207 layer3.h \
208 rq_table.dat \
209 imdct_s.dat
210
211huffman.o: huffman.c \
212 libmad_global.h \
213 huffman.h
214
215libmadplugin.o: libmadplugin.cpp \
216 libmadplugin.h \
217 ../mediaplayerplugininterface.h \
218 mad.h
219
220libmadpluginimpl.o: libmadpluginimpl.cpp \
221 libmadplugin.h \
222 ../mediaplayerplugininterface.h \
223 libmadpluginimpl.h \
224 ../mediaplayerplugininterface.h
225
226
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 @@
1/*
2 * mad - MPEG audio decoder
3 * Copyright (C) 2000-2001 Robert Leslie
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * $Id$
20 */
21
22# ifdef HAVE_CONFIG_H
23# include "libmad_config.h"
24# endif
25
26# include "libmad_global.h"
27
28# ifdef HAVE_LIMITS_H
29# include <limits.h>
30# else
31# define CHAR_BIT 8
32# endif
33
34# include "bit.h"
35
36/*
37 * This is the lookup table for computing the CRC-check word.
38 * As described in section 2.4.3.1 and depicted in Figure A.9
39 * of ISO/IEC 11172-3, the generator polynomial is:
40 *
41 * G(X) = X^16 + X^15 + X^2 + 1
42 */
43static
44unsigned short const crc_table[256] = {
45 0x0000, 0x8005, 0x800f, 0x000a, 0x801b, 0x001e, 0x0014, 0x8011,
46 0x8033, 0x0036, 0x003c, 0x8039, 0x0028, 0x802d, 0x8027, 0x0022,
47 0x8063, 0x0066, 0x006c, 0x8069, 0x0078, 0x807d, 0x8077, 0x0072,
48 0x0050, 0x8055, 0x805f, 0x005a, 0x804b, 0x004e, 0x0044, 0x8041,
49 0x80c3, 0x00c6, 0x00cc, 0x80c9, 0x00d8, 0x80dd, 0x80d7, 0x00d2,
50 0x00f0, 0x80f5, 0x80ff, 0x00fa, 0x80eb, 0x00ee, 0x00e4, 0x80e1,
51 0x00a0, 0x80a5, 0x80af, 0x00aa, 0x80bb, 0x00be, 0x00b4, 0x80b1,
52 0x8093, 0x0096, 0x009c, 0x8099, 0x0088, 0x808d, 0x8087, 0x0082,
53
54 0x8183, 0x0186, 0x018c, 0x8189, 0x0198, 0x819d, 0x8197, 0x0192,
55 0x01b0, 0x81b5, 0x81bf, 0x01ba, 0x81ab, 0x01ae, 0x01a4, 0x81a1,
56 0x01e0, 0x81e5, 0x81ef, 0x01ea, 0x81fb, 0x01fe, 0x01f4, 0x81f1,
57 0x81d3, 0x01d6, 0x01dc, 0x81d9, 0x01c8, 0x81cd, 0x81c7, 0x01c2,
58 0x0140, 0x8145, 0x814f, 0x014a, 0x815b, 0x015e, 0x0154, 0x8151,
59 0x8173, 0x0176, 0x017c, 0x8179, 0x0168, 0x816d, 0x8167, 0x0162,
60 0x8123, 0x0126, 0x012c, 0x8129, 0x0138, 0x813d, 0x8137, 0x0132,
61 0x0110, 0x8115, 0x811f, 0x011a, 0x810b, 0x010e, 0x0104, 0x8101,
62
63 0x8303, 0x0306, 0x030c, 0x8309, 0x0318, 0x831d, 0x8317, 0x0312,
64 0x0330, 0x8335, 0x833f, 0x033a, 0x832b, 0x032e, 0x0324, 0x8321,
65 0x0360, 0x8365, 0x836f, 0x036a, 0x837b, 0x037e, 0x0374, 0x8371,
66 0x8353, 0x0356, 0x035c, 0x8359, 0x0348, 0x834d, 0x8347, 0x0342,
67 0x03c0, 0x83c5, 0x83cf, 0x03ca, 0x83db, 0x03de, 0x03d4, 0x83d1,
68 0x83f3, 0x03f6, 0x03fc, 0x83f9, 0x03e8, 0x83ed, 0x83e7, 0x03e2,
69 0x83a3, 0x03a6, 0x03ac, 0x83a9, 0x03b8, 0x83bd, 0x83b7, 0x03b2,
70 0x0390, 0x8395, 0x839f, 0x039a, 0x838b, 0x038e, 0x0384, 0x8381,
71
72 0x0280, 0x8285, 0x828f, 0x028a, 0x829b, 0x029e, 0x0294, 0x8291,
73 0x82b3, 0x02b6, 0x02bc, 0x82b9, 0x02a8, 0x82ad, 0x82a7, 0x02a2,
74 0x82e3, 0x02e6, 0x02ec, 0x82e9, 0x02f8, 0x82fd, 0x82f7, 0x02f2,
75 0x02d0, 0x82d5, 0x82df, 0x02da, 0x82cb, 0x02ce, 0x02c4, 0x82c1,
76 0x8243, 0x0246, 0x024c, 0x8249, 0x0258, 0x825d, 0x8257, 0x0252,
77 0x0270, 0x8275, 0x827f, 0x027a, 0x826b, 0x026e, 0x0264, 0x8261,
78 0x0220, 0x8225, 0x822f, 0x022a, 0x823b, 0x023e, 0x0234, 0x8231,
79 0x8213, 0x0216, 0x021c, 0x8219, 0x0208, 0x820d, 0x8207, 0x0202
80};
81
82# define CRC_POLY 0x8005
83
84/*
85 * NAME:bit->init()
86 * DESCRIPTION:initialize bit pointer struct
87 */
88void mad_bit_init(struct mad_bitptr *bitptr, unsigned char const *byte)
89{
90 bitptr->byte = byte;
91 bitptr->cache = 0;
92 bitptr->left = CHAR_BIT;
93}
94
95/*
96 * NAME:bit->length()
97 * DESCRIPTION:return number of bits between start and end points
98 */
99unsigned int mad_bit_length(struct mad_bitptr const *begin,
100 struct mad_bitptr const *end)
101{
102 return begin->left +
103 CHAR_BIT * (end->byte - (begin->byte + 1)) + (CHAR_BIT - end->left);
104}
105
106/*
107 * NAME:bit->nextbyte()
108 * DESCRIPTION:return pointer to next unprocessed byte
109 */
110unsigned char const *mad_bit_nextbyte(struct mad_bitptr const *bitptr)
111{
112 return bitptr->left == CHAR_BIT ? bitptr->byte : bitptr->byte + 1;
113}
114
115/*
116 * NAME:bit->skip()
117 * DESCRIPTION:advance bit pointer
118 */
119void mad_bit_skip(struct mad_bitptr *bitptr, unsigned int len)
120{
121 bitptr->byte += len / CHAR_BIT;
122 bitptr->left -= len % CHAR_BIT;
123
124 if (bitptr->left > CHAR_BIT) {
125 bitptr->byte++;
126 bitptr->left += CHAR_BIT;
127 }
128
129 if (bitptr->left < CHAR_BIT)
130 bitptr->cache = *bitptr->byte;
131}
132
133/*
134 * NAME:bit->read()
135 * DESCRIPTION:read an arbitrary number of bits and return their UIMSBF value
136 */
137unsigned long mad_bit_read(struct mad_bitptr *bitptr, unsigned int len)
138{
139 register unsigned long value;
140
141 if (bitptr->left == CHAR_BIT)
142 bitptr->cache = *bitptr->byte;
143
144 if (len < bitptr->left) {
145 value = (bitptr->cache & ((1 << bitptr->left) - 1)) >>
146 (bitptr->left - len);
147 bitptr->left -= len;
148
149 return value;
150 }
151
152 /* remaining bits in current byte */
153
154 value = bitptr->cache & ((1 << bitptr->left) - 1);
155 len -= bitptr->left;
156
157 bitptr->byte++;
158 bitptr->left = CHAR_BIT;
159
160 /* more bytes */
161
162 while (len >= CHAR_BIT) {
163 value = (value << CHAR_BIT) | *bitptr->byte++;
164 len -= CHAR_BIT;
165 }
166
167 if (len > 0) {
168 bitptr->cache = *bitptr->byte;
169
170 value = (value << len) | (bitptr->cache >> (CHAR_BIT - len));
171 bitptr->left -= len;
172 }
173
174 return value;
175}
176
177# if 0
178/*
179 * NAME:bit->write()
180 * DESCRIPTION:write an arbitrary number of bits
181 */
182void mad_bit_write(struct mad_bitptr *bitptr, unsigned int len,
183 unsigned long value)
184{
185 unsigned char *ptr;
186
187 ptr = (unsigned char *) bitptr->byte;
188
189 /* ... */
190}
191# endif
192
193/*
194 * NAME:bit->crc()
195 * DESCRIPTION:compute CRC-check word
196 */
197unsigned short mad_bit_crc(struct mad_bitptr bitptr, unsigned int len,
198 unsigned short init)
199{
200 register unsigned int crc, data;
201
202# if CHAR_BIT == 8
203 for (crc = init; len >= 8; len -= 8) {
204 crc = (crc << 8) ^
205 crc_table[((crc >> 8) ^ mad_bit_read(&bitptr, 8)) & 0xff];
206 }
207# else
208 crc = init;
209# endif
210
211 while (len--) {
212 data = mad_bit_read(&bitptr, 1) ^ (crc >> 15);
213
214 crc <<= 1;
215 if (data & 1)
216 crc ^= CRC_POLY;
217 }
218
219 return crc & 0xffff;
220}
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 @@
1/*
2 * mad - MPEG audio decoder
3 * Copyright (C) 2000-2001 Robert Leslie
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * $Id$
20 */
21
22# ifndef LIBMAD_BIT_H
23# define LIBMAD_BIT_H
24
25struct mad_bitptr {
26 unsigned char const *byte;
27 unsigned short cache;
28 unsigned short left;
29};
30
31void mad_bit_init(struct mad_bitptr *, unsigned char const *);
32
33 # define mad_bit_finish(bitptr) /* nothing */
34
35unsigned int mad_bit_length(struct mad_bitptr const *,
36 struct mad_bitptr const *);
37
38# define mad_bit_bitsleft(bitptr) ((bitptr)->left)
39unsigned char const *mad_bit_nextbyte(struct mad_bitptr const *);
40
41void mad_bit_skip(struct mad_bitptr *, unsigned int);
42unsigned long mad_bit_read(struct mad_bitptr *, unsigned int);
43void mad_bit_write(struct mad_bitptr *, unsigned int, unsigned long);
44
45unsigned short mad_bit_crc(struct mad_bitptr, unsigned int, unsigned short);
46
47# 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 @@
1/*
2 * mad - MPEG audio decoder
3 * Copyright (C) 2000-2001 Robert Leslie
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * $Id$
20 */
21
22# ifdef HAVE_CONFIG_H
23# include "libmad_config.h"
24# else
25# ifndef WEXITSTATUS
26# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
27# endif
28# ifndef WIFEXITED
29# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
30# endif
31# endif
32
33# include "libmad_global.h"
34
35# include <sys/types.h>
36
37# ifdef HAVE_SYS_WAIT_H
38# include <sys/wait.h>
39# endif
40
41# ifdef HAVE_UNISTD_H
42# include <unistd.h>
43# endif
44
45# include <fcntl.h>
46# include <stdlib.h>
47# include <errno.h>
48
49# include "stream.h"
50# include "frame.h"
51# include "synth.h"
52# include "decoder.h"
53
54void mad_decoder_init(struct mad_decoder *decoder, void *data,
55 enum mad_flow (*input_func)(void *, struct mad_stream *),
56 enum mad_flow (*header_func)(void *,
57 struct mad_header const *),
58 enum mad_flow (*filter_func)(void *, struct mad_frame *),
59 enum mad_flow (*output_func)(void *,
60 struct mad_header const *,
61 struct mad_pcm *),
62 enum mad_flow (*error_func)(void *, struct mad_stream *,
63 struct mad_frame *),
64 enum mad_flow (*message_func)(void *,
65 void *, unsigned int *))
66{
67 decoder->mode = -1;
68
69 decoder->options = 0;
70
71 decoder->async.pid = 0;
72 decoder->async.in = -1;
73 decoder->async.out = -1;
74
75 decoder->sync = 0;
76
77 decoder->cb_data = data;
78
79 decoder->input_func = input_func;
80 decoder->header_func = header_func;
81 decoder->filter_func = filter_func;
82 decoder->output_func = output_func;
83 decoder->error_func = error_func;
84 decoder->message_func = message_func;
85}
86
87int mad_decoder_finish(struct mad_decoder *decoder)
88{
89 if (decoder->mode == MAD_DECODER_MODE_ASYNC && decoder->async.pid) {
90 pid_t pid;
91 int status;
92
93 close(decoder->async.in);
94
95 do {
96 pid = waitpid(decoder->async.pid, &status, 0);
97 }
98 while (pid == -1 && errno == EINTR);
99
100 decoder->mode = -1;
101
102 close(decoder->async.out);
103
104 decoder->async.pid = 0;
105 decoder->async.in = -1;
106 decoder->async.out = -1;
107
108 if (pid == -1)
109 return -1;
110
111 return (!WIFEXITED(status) || WEXITSTATUS(status)) ? -1 : 0;
112 }
113
114 return 0;
115}
116
117static
118enum mad_flow send_io(int fd, void const *data, size_t len)
119{
120 char const *ptr = data;
121 ssize_t count;
122
123 while (len) {
124 do {
125 count = write(fd, ptr, len);
126 }
127 while (count == -1 && errno == EINTR);
128
129 if (count == -1)
130 return MAD_FLOW_BREAK;
131
132 len -= count;
133 ptr += count;
134 }
135
136 return MAD_FLOW_CONTINUE;
137}
138
139static
140enum mad_flow receive_io(int fd, void *buffer, size_t len)
141{
142 char *ptr = buffer;
143 ssize_t count;
144
145 while (len) {
146 do {
147 count = read(fd, ptr, len);
148 }
149 while (count == -1 && errno == EINTR);
150
151 if (count == -1)
152 return (errno == EAGAIN) ? MAD_FLOW_IGNORE : MAD_FLOW_BREAK;
153 else if (count == 0)
154 return MAD_FLOW_STOP;
155
156 len -= count;
157 ptr += count;
158 }
159
160 return MAD_FLOW_CONTINUE;
161}
162
163static
164enum mad_flow receive_io_blocking(int fd, void *buffer, size_t len)
165{
166 int flags, blocking;
167 enum mad_flow result;
168
169 flags = fcntl(fd, F_GETFL);
170 if (flags == -1)
171 return MAD_FLOW_BREAK;
172
173 blocking = flags & ~O_NONBLOCK;
174
175 if (blocking != flags &&
176 fcntl(fd, F_SETFL, blocking) == -1)
177 return MAD_FLOW_BREAK;
178
179 result = receive_io(fd, buffer, len);
180
181 if (flags != blocking &&
182 fcntl(fd, F_SETFL, flags) == -1)
183 return MAD_FLOW_BREAK;
184
185 return result;
186}
187
188static
189enum mad_flow send(int fd, void const *message, unsigned int size)
190{
191 enum mad_flow result;
192
193 /* send size */
194
195 result = send_io(fd, &size, sizeof(size));
196
197 /* send message */
198
199 if (result == MAD_FLOW_CONTINUE)
200 result = send_io(fd, message, size);
201
202 return result;
203}
204
205static
206enum mad_flow receive(int fd, void **message, unsigned int *size)
207{
208 enum mad_flow result;
209 unsigned int actual;
210
211 if (*message == 0)
212 *size = 0;
213
214 /* receive size */
215
216 result = receive_io(fd, &actual, sizeof(actual));
217
218 /* receive message */
219
220 if (result == MAD_FLOW_CONTINUE) {
221 if (actual > *size)
222 actual -= *size;
223 else {
224 *size = actual;
225 actual = 0;
226 }
227
228 if (*size > 0) {
229 if (*message == 0) {
230 *message = malloc(*size);
231 if (*message == 0)
232 return MAD_FLOW_BREAK;
233 }
234
235 result = receive_io_blocking(fd, *message, *size);
236 }
237
238 /* throw away remainder of message */
239
240 while (actual && result == MAD_FLOW_CONTINUE) {
241 char sink[256];
242 unsigned int len;
243
244 len = actual > sizeof(sink) ? sizeof(sink) : actual;
245
246 result = receive_io_blocking(fd, sink, len);
247
248 actual -= len;
249 }
250 }
251
252 return result;
253}
254
255static
256enum mad_flow check_message(struct mad_decoder *decoder)
257{
258 enum mad_flow result;
259 void *message = 0;
260 unsigned int size;
261
262 result = receive(decoder->async.in, &message, &size);
263
264 if (result == MAD_FLOW_CONTINUE) {
265 if (decoder->message_func == 0)
266 size = 0;
267 else {
268 result = decoder->message_func(decoder->cb_data, message, &size);
269
270 if (result == MAD_FLOW_IGNORE ||
271 result == MAD_FLOW_BREAK)
272 size = 0;
273 }
274
275 if (send(decoder->async.out, message, size) != MAD_FLOW_CONTINUE)
276 result = MAD_FLOW_BREAK;
277 }
278
279 if (message)
280 free(message);
281
282 return result;
283}
284
285static
286enum mad_flow error_default(void *data, struct mad_stream *stream,
287 struct mad_frame *frame)
288{
289 int *bad_last_frame = data;
290
291 switch (stream->error) {
292 case MAD_ERROR_BADCRC:
293 if (*bad_last_frame)
294 mad_frame_mute(frame);
295 else
296 *bad_last_frame = 1;
297
298 return MAD_FLOW_IGNORE;
299
300 default:
301 return MAD_FLOW_CONTINUE;
302 }
303}
304
305static
306int run_sync(struct mad_decoder *decoder)
307{
308 enum mad_flow (*error_func)(void *, struct mad_stream *, struct mad_frame *);
309 void *error_data;
310 int bad_last_frame = 0;
311 struct mad_stream *stream;
312 struct mad_frame *frame;
313 struct mad_synth *synth;
314 int result = 0;
315
316 if (decoder->input_func == 0)
317 return 0;
318
319 if (decoder->error_func) {
320 error_func = decoder->error_func;
321 error_data = decoder->cb_data;
322 }
323 else {
324 error_func = error_default;
325 error_data = &bad_last_frame;
326 }
327
328 stream = &decoder->sync->stream;
329 frame = &decoder->sync->frame;
330 synth = &decoder->sync->synth;
331
332 mad_stream_init(stream);
333 mad_frame_init(frame);
334 mad_synth_init(synth);
335
336 mad_stream_options(stream, decoder->options);
337
338 do {
339 switch (decoder->input_func(decoder->cb_data, stream)) {
340 case MAD_FLOW_STOP:
341 goto done;
342 case MAD_FLOW_BREAK:
343 goto fail;
344 case MAD_FLOW_IGNORE:
345 continue;
346 case MAD_FLOW_CONTINUE:
347 break;
348 }
349
350 while (1) {
351 if (decoder->mode == MAD_DECODER_MODE_ASYNC) {
352 switch (check_message(decoder)) {
353 case MAD_FLOW_IGNORE:
354 case MAD_FLOW_CONTINUE:
355 break;
356 case MAD_FLOW_BREAK:
357 goto fail;
358 case MAD_FLOW_STOP:
359 goto done;
360 }
361 }
362
363 if (decoder->header_func) {
364 if (mad_header_decode(&frame->header, stream) == -1) {
365 if (!MAD_RECOVERABLE(stream->error))
366 break;
367
368 switch (error_func(error_data, stream, frame)) {
369 case MAD_FLOW_STOP:
370 goto done;
371 case MAD_FLOW_BREAK:
372 goto fail;
373 case MAD_FLOW_IGNORE:
374 case MAD_FLOW_CONTINUE:
375 default:
376 continue;
377 }
378 }
379
380 switch (decoder->header_func(decoder->cb_data, &frame->header)) {
381 case MAD_FLOW_STOP:
382 goto done;
383 case MAD_FLOW_BREAK:
384 goto fail;
385 case MAD_FLOW_IGNORE:
386 continue;
387 case MAD_FLOW_CONTINUE:
388 break;
389 }
390 }
391
392 if (mad_frame_decode(frame, stream) == -1) {
393 if (!MAD_RECOVERABLE(stream->error))
394 break;
395
396 switch (error_func(error_data, stream, frame)) {
397 case MAD_FLOW_STOP:
398 goto done;
399 case MAD_FLOW_BREAK:
400 goto fail;
401 case MAD_FLOW_IGNORE:
402 break;
403 case MAD_FLOW_CONTINUE:
404 default:
405 continue;
406 }
407 }
408 else
409 bad_last_frame = 0;
410
411 if (decoder->filter_func) {
412 switch (decoder->filter_func(decoder->cb_data, frame)) {
413 case MAD_FLOW_STOP:
414 goto done;
415 case MAD_FLOW_BREAK:
416 goto fail;
417 case MAD_FLOW_IGNORE:
418 continue;
419 case MAD_FLOW_CONTINUE:
420 break;
421 }
422 }
423
424 mad_synth_frame(synth, frame);
425
426 if (decoder->output_func) {
427 switch (decoder->output_func(decoder->cb_data,
428 &frame->header, &synth->pcm)) {
429 case MAD_FLOW_STOP:
430 goto done;
431 case MAD_FLOW_BREAK:
432 goto fail;
433 case MAD_FLOW_IGNORE:
434 case MAD_FLOW_CONTINUE:
435 break;
436 }
437 }
438 }
439 }
440 while (stream->error == MAD_ERROR_BUFLEN);
441
442 fail:
443 result = -1;
444
445 done:
446 mad_synth_finish(synth);
447 mad_frame_finish(frame);
448 mad_stream_finish(stream);
449
450 return result;
451}
452
453static
454int run_async(struct mad_decoder *decoder)
455{
456 pid_t pid;
457 int ptoc[2], ctop[2], flags;
458
459 if (pipe(ptoc) == -1)
460 return -1;
461
462 if (pipe(ctop) == -1) {
463 close(ptoc[0]);
464 close(ptoc[1]);
465 return -1;
466 }
467
468 flags = fcntl(ptoc[0], F_GETFL);
469 if (flags == -1 ||
470 fcntl(ptoc[0], F_SETFL, flags | O_NONBLOCK) == -1) {
471 close(ctop[0]);
472 close(ctop[1]);
473 close(ptoc[0]);
474 close(ptoc[1]);
475 return -1;
476 }
477
478 pid = fork();
479 if (pid == -1) {
480 close(ctop[0]);
481 close(ctop[1]);
482 close(ptoc[0]);
483 close(ptoc[1]);
484 return -1;
485 }
486
487 decoder->async.pid = pid;
488
489 if (pid) {
490 /* parent */
491
492 close(ptoc[0]);
493 close(ctop[1]);
494
495 decoder->async.in = ctop[0];
496 decoder->async.out = ptoc[1];
497
498 return 0;
499 }
500
501 /* child */
502
503 close(ptoc[1]);
504 close(ctop[0]);
505
506 decoder->async.in = ptoc[0];
507 decoder->async.out = ctop[1];
508
509 _exit(run_sync(decoder));
510
511 /* not reached */
512 return -1;
513}
514
515int mad_decoder_run(struct mad_decoder *decoder, enum mad_decoder_mode mode)
516{
517 int result;
518 int (*run)(struct mad_decoder *) = 0;
519
520 switch (decoder->mode = mode) {
521 case MAD_DECODER_MODE_SYNC:
522 run = run_sync;
523 break;
524
525 case MAD_DECODER_MODE_ASYNC:
526 run = run_async;
527 break;
528 }
529
530 if (run == 0)
531 return -1;
532
533 decoder->sync = malloc(sizeof(*decoder->sync));
534 if (decoder->sync == 0)
535 return -1;
536
537 result = run(decoder);
538
539 free(decoder->sync);
540 decoder->sync = 0;
541
542 return result;
543}
544
545int mad_decoder_message(struct mad_decoder *decoder,
546 void *message, unsigned int *len)
547{
548 if (decoder->mode != MAD_DECODER_MODE_ASYNC ||
549 send(decoder->async.out, message, *len) != MAD_FLOW_CONTINUE ||
550 receive(decoder->async.in, &message, len) != MAD_FLOW_CONTINUE)
551 return -1;
552
553 return 0;
554}
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 @@
1/*
2 * mad - MPEG audio decoder
3 * Copyright (C) 2000-2001 Robert Leslie
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * $Id$
20 */
21
22# ifndef LIBMAD_DECODER_H
23# define LIBMAD_DECODER_H
24
25# include "stream.h"
26# include "frame.h"
27# include "synth.h"
28
29enum mad_decoder_mode {
30 MAD_DECODER_MODE_SYNC = 0,
31 MAD_DECODER_MODE_ASYNC
32};
33
34enum mad_flow {
35 MAD_FLOW_CONTINUE = 0x0000,
36 MAD_FLOW_STOP = 0x0010,
37 MAD_FLOW_BREAK = 0x0011,
38 MAD_FLOW_IGNORE = 0x0020
39};
40
41struct mad_decoder {
42 enum mad_decoder_mode mode;
43
44 int options;
45
46 struct {
47 long pid;
48 int in;
49 int out;
50 } async;
51
52 struct {
53 struct mad_stream stream;
54 struct mad_frame frame;
55 struct mad_synth synth;
56 } *sync;
57
58 void *cb_data;
59
60 enum mad_flow (*input_func)(void *, struct mad_stream *);
61 enum mad_flow (*header_func)(void *, struct mad_header const *);
62 enum mad_flow (*filter_func)(void *, struct mad_frame *);
63 enum mad_flow (*output_func)(void *,
64 struct mad_header const *, struct mad_pcm *);
65 enum mad_flow (*error_func)(void *, struct mad_stream *, struct mad_frame *);
66 enum mad_flow (*message_func)(void *, void *, unsigned int *);
67};
68
69void mad_decoder_init(struct mad_decoder *, void *,
70 enum mad_flow (*)(void *, struct mad_stream *),
71 enum mad_flow (*)(void *, struct mad_header const *),
72 enum mad_flow (*)(void *, struct mad_frame *),
73 enum mad_flow (*)(void *,
74 struct mad_header const *,
75 struct mad_pcm *),
76 enum mad_flow (*)(void *,
77 struct mad_stream *,
78 struct mad_frame *),
79 enum mad_flow (*)(void *, void *, unsigned int *));
80int mad_decoder_finish(struct mad_decoder *);
81
82# define mad_decoder_options(decoder, opts) ((decoder)->options = (opts))
83
84int mad_decoder_run(struct mad_decoder *, enum mad_decoder_mode);
85int mad_decoder_message(struct mad_decoder *, void *, unsigned int *);
86
87# 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 @@
1#!/bin/sh
2
3#
4# This is needed to ensure the single build will work
5# The names of the header files clash with names of other headers in Qt/Palmtop
6#
7
8
9for file in *.c
10do
11
12 echo "fixing $file"
13 sed "s/global.h/libmad_global.h/" $file > $file.tmp
14 sed "s/version.h/libmad_version.h/" $file.tmp > $file
15 sed "s/config.h/libmad_config.h/" $file > $file.tmp
16 mv $file.tmp $file
17
18done
19
20
21mv global.h libmad_global.h
22mv version.h libmad_version.h
23mv config.h libmad_config.h
24
25
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 @@
1/*
2 * mad - MPEG audio decoder
3 * Copyright (C) 2000-2001 Robert Leslie
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * $Id$
20 */
21
22# ifdef HAVE_CONFIG_H
23# include "libmad_config.h"
24# endif
25
26# include "libmad_global.h"
27
28# include "fixed.h"
29
30/*
31 * NAME:fixed->abs()
32 * DESCRIPTION:return absolute value of a fixed-point number
33 */
34mad_fixed_t mad_f_abs(mad_fixed_t x)
35{
36 return x < 0 ? -x : x;
37}
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 @@
1/*
2 * mad - MPEG audio decoder
3 * Copyright (C) 2000-2001 Robert Leslie
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * $Id$
20 */
21
22# ifndef LIBMAD_FIXED_H
23# define LIBMAD_FIXED_H
24
25# if SIZEOF_INT >= 4
26typedef signed int mad_fixed_t;
27
28typedef signed int mad_fixed64hi_t;
29typedef unsigned int mad_fixed64lo_t;
30# else
31typedef signed long mad_fixed_t;
32
33typedef signed long mad_fixed64hi_t;
34typedef unsigned long mad_fixed64lo_t;
35# endif
36
37/*
38 * Fixed-point format: 0xABBBBBBB
39 * A == whole part (sign + 3 bits)
40 * B == fractional part (28 bits)
41 *
42 * Values are signed two's complement, so the effective range is:
43 * 0x80000000 to 0x7fffffff
44 * -8.0 to +7.9999999962747097015380859375
45 *
46 * The smallest representable value is:
47 * 0x00000001 == 0.0000000037252902984619140625 (i.e. about 3.725e-9)
48 *
49 * 28 bits of fractional accuracy represent about
50 * 8.6 digits of decimal accuracy.
51 *
52 * Fixed-point numbers can be added or subtracted as normal
53 * integers, but multiplication requires shifting the 64-bit result
54 * from 56 fractional bits back to 28 (and rounding.)
55 *
56 * Changing the definition of MAD_F_FRACBITS is only partially
57 * supported, and must be done with care.
58 */
59
60 # define MAD_F_FRACBITS 28
61
62# if MAD_F_FRACBITS == 28
63 # define MAD_F(x) ((mad_fixed_t) (x##L))
64# else
65# if MAD_F_FRACBITS < 28
66# warning "MAD_F_FRACBITS < 28"
67 # define MAD_F(x) ((mad_fixed_t) \
68 (((x##L) + \
69 (1L << (28 - MAD_F_FRACBITS - 1))) >> \
70 (28 - MAD_F_FRACBITS)))
71# elif MAD_F_FRACBITS > 28
72# error "MAD_F_FRACBITS > 28 not currently supported"
73 # define MAD_F(x) ((mad_fixed_t) \
74 ((x##L) << (MAD_F_FRACBITS - 28)))
75# endif
76# endif
77
78 # define MAD_F_MIN ((mad_fixed_t) -0x80000000L)
79 # define MAD_F_MAX ((mad_fixed_t) +0x7fffffffL)
80
81 # define MAD_F_ONE MAD_F(0x10000000)
82
83 # define mad_f_tofixed(x)((mad_fixed_t) \
84 ((x) * (double) (1L << MAD_F_FRACBITS) + 0.5))
85 # define mad_f_todouble(x)((double) \
86 ((x) / (double) (1L << MAD_F_FRACBITS)))
87
88 # define mad_f_intpart(x)((x) >> MAD_F_FRACBITS)
89 # define mad_f_fracpart(x)((x) & ((1L << MAD_F_FRACBITS) - 1))
90 /* (x should be positive) */
91
92 # define mad_f_fromint(x)((x) << MAD_F_FRACBITS)
93
94 # define mad_f_add(x, y)((x) + (y))
95 # define mad_f_sub(x, y)((x) - (y))
96
97# if defined(FPM_64BIT)
98
99/*
100 * This version should be the most accurate if 64-bit (long long) types are
101 * supported by the compiler, although it may not be the most efficient.
102 */
103# if defined(OPT_ACCURACY)
104# define mad_f_mul(x, y) \
105 ((mad_fixed_t) \
106 ((((signed long long) (x) * (y)) + \
107 (1L << (MAD_F_SCALEBITS - 1))) >> MAD_F_SCALEBITS))
108# else
109# define mad_f_mul(x, y) \
110 ((mad_fixed_t) (((signed long long) (x) * (y)) >> MAD_F_SCALEBITS))
111# endif
112
113# define MAD_F_SCALEBITS MAD_F_FRACBITS
114
115/* --- Intel --------------------------------------------------------------- */
116
117# elif defined(FPM_INTEL)
118
119/*
120 * This Intel version is fast and accurate; the disposition of the least
121 * significant bit depends on OPT_ACCURACY via mad_f_scale64().
122 */
123# define MAD_F_MLX(hi, lo, x, y) \
124 asm ("imull %3" \
125 : "=a" (lo), "=d" (hi) \
126 : "%a" (x), "rm" (y) \
127 : "cc")
128
129# if defined(OPT_ACCURACY)
130/*
131 * This gives best accuracy but is not very fast.
132 */
133# define MAD_F_MLA(hi, lo, x, y) \
134 ({ mad_fixed64hi_t __hi; \
135 mad_fixed64lo_t __lo; \
136 MAD_F_MLX(__hi, __lo, (x), (y)); \
137 asm ("addl %2,%0\n\t" \
138 "adcl %3,%1" \
139 : "=rm" (lo), "=rm" (hi) \
140 : "r" (__lo), "r" (__hi), "0" (lo), "1" (hi) \
141 : "cc"); \
142 })
143# endif /* OPT_ACCURACY */
144
145# if defined(OPT_ACCURACY)
146/*
147 * Surprisingly, this is faster than SHRD followed by ADC.
148 */
149# define mad_f_scale64(hi, lo) \
150 ({ mad_fixed64hi_t __hi_; \
151 mad_fixed64lo_t __lo_; \
152 mad_fixed_t __result; \
153 asm ("addl %4,%2\n\t" \
154 "adcl %5,%3" \
155 : "=rm" (__lo_), "=rm" (__hi_) \
156 : "0" (lo), "1" (hi), \
157 "ir" (1L << (MAD_F_SCALEBITS - 1)), "ir" (0) \
158 : "cc"); \
159 asm ("shrdl %3,%2,%1" \
160 : "=rm" (__result) \
161 : "0" (__lo_), "r" (__hi_), "I" (MAD_F_SCALEBITS) \
162 : "cc"); \
163 __result; \
164 })
165# else
166# define mad_f_scale64(hi, lo) \
167 ({ mad_fixed_t __result; \
168 asm ("shrdl %3,%2,%1" \
169 : "=rm" (__result) \
170 : "0" (lo), "r" (hi), "I" (MAD_F_SCALEBITS) \
171 : "cc"); \
172 __result; \
173 })
174# endif /* OPT_ACCURACY */
175
176# define MAD_F_SCALEBITS MAD_F_FRACBITS
177
178/* --- ARM ----------------------------------------------------------------- */
179
180# elif defined(FPM_ARM)
181
182/*
183 * This ARM V4 version is as accurate as FPM_64BIT but much faster. The
184 * least significant bit is properly rounded at no CPU cycle cost!
185 */
186# if 1
187/*
188 * There's a bug somewhere, possibly in the compiler, that sometimes makes
189 * this necessary instead of the default implementation via MAD_F_MLX and
190 * mad_f_scale64. It may be related to the use (or lack) of
191 * -finline-functions and/or -fstrength-reduce.
192 *
193 * This is also apparently faster than MAD_F_MLX/mad_f_scale64.
194 */
195# define mad_f_mul(x, y) \
196 ({ mad_fixed64hi_t __hi; \
197 mad_fixed64lo_t __lo; \
198 mad_fixed_t __result; \
199 asm ("smull%0, %1, %3, %4\n\t" \
200 "movs%0, %0, lsr %5\n\t" \
201 "adc%2, %0, %1, lsl %6" \
202 : "=&r" (__lo), "=&r" (__hi), "=r" (__result) \
203 : "%r" (x), "r" (y), \
204 "M" (MAD_F_SCALEBITS), "M" (32 - MAD_F_SCALEBITS) \
205 : "cc"); \
206 __result; \
207 })
208# endif
209
210# define MAD_F_MLX(hi, lo, x, y) \
211 asm ("smull%0, %1, %2, %3" \
212 : "=&r" (lo), "=&r" (hi) \
213 : "%r" (x), "r" (y))
214
215# define MAD_F_MLA(hi, lo, x, y) \
216 asm ("smlal%0, %1, %2, %3" \
217 : "+r" (lo), "+r" (hi) \
218 : "%r" (x), "r" (y))
219
220# define mad_f_scale64(hi, lo) \
221 ({ mad_fixed_t __result; \
222 asm ("movs%0, %1, lsr %3\n\t" \
223 "adc%0, %0, %2, lsl %4" \
224 : "=r" (__result) \
225 : "r" (lo), "r" (hi), \
226 "M" (MAD_F_SCALEBITS), "M" (32 - MAD_F_SCALEBITS) \
227 : "cc"); \
228 __result; \
229 })
230
231# define MAD_F_SCALEBITS MAD_F_FRACBITS
232
233/* --- MIPS ---------------------------------------------------------------- */
234
235# elif defined(FPM_MIPS)
236
237/*
238 * This MIPS version is fast and accurate; the disposition of the least
239 * significant bit depends on OPT_ACCURACY via mad_f_scale64().
240 */
241# define MAD_F_MLX(hi, lo, x, y) \
242 asm ("mult%2,%3" \
243 : "=l" (lo), "=h" (hi) \
244 : "%r" (x), "r" (y))
245
246# if defined(HAVE_MADD_ASM)
247# define MAD_F_MLA(hi, lo, x, y) \
248 asm ("madd%2,%3" \
249 : "+l" (lo), "+h" (hi) \
250 : "%r" (x), "r" (y))
251# elif defined(HAVE_MADD16_ASM)
252/*
253 * This loses significant accuracy due to the 16-bit integer limit in the
254 * multiply/accumulate instruction.
255 */
256# define MAD_F_ML0(hi, lo, x, y) \
257 asm ("mult%2,%3" \
258 : "=l" (lo), "=h" (hi) \
259 : "%r" ((x) >> 12), "r" ((y) >> 16))
260# define MAD_F_MLA(hi, lo, x, y) \
261 asm ("madd16%2,%3" \
262 : "+l" (lo), "+h" (hi) \
263 : "%r" ((x) >> 12), "r" ((y) >> 16))
264# define MAD_F_MLZ(hi, lo) ((mad_fixed_t) (lo))
265# endif
266
267# if defined(OPT_SPEED)
268# define mad_f_scale64(hi, lo) \
269 ((mad_fixed_t) ((hi) << (32 - MAD_F_SCALEBITS)))
270# define MAD_F_SCALEBITS MAD_F_FRACBITS
271# endif
272
273/* --- SPARC --------------------------------------------------------------- */
274
275# elif defined(FPM_SPARC)
276
277/*
278 * This SPARC V8 version is fast and accurate; the disposition of the least
279 * significant bit depends on OPT_ACCURACY via mad_f_scale64().
280 */
281# define MAD_F_MLX(hi, lo, x, y) \
282 asm ("smul %2, %3, %0\n\t" \
283 "rd %%y, %1" \
284 : "=r" (lo), "=r" (hi) \
285 : "%r" (x), "rI" (y))
286
287/* --- PowerPC ------------------------------------------------------------- */
288
289# elif defined(FPM_PPC)
290
291/*
292 * This PowerPC version is tuned for the 4xx embedded processors. It is
293 * effectively a tuned version of FPM_64BIT. It is a little faster and just
294 * as accurate. The disposition of the least significant bit depends on
295 * OPT_ACCURACY via mad_f_scale64().
296 */
297# define MAD_F_MLX(hi, lo, x, y) \
298 asm ("mulhw %1, %2, %3\n\t" \
299 "mullw %0, %2, %3" \
300 : "=&r" (lo), "=&r" (hi) \
301 : "%r" (x), "r" (y))
302
303# define MAD_F_MLA(hi, lo, x, y) \
304 ({ mad_fixed64hi_t __hi; \
305 mad_fixed64lo_t __lo; \
306 MAD_F_MLX(__hi, __lo, (x), (y)); \
307 asm ("addc %0, %2, %3\n\t" \
308 "adde %1, %4, %5" \
309 : "=r" (lo), "=r" (hi) \
310 : "%r" (__lo), "0" (lo), "%r" (__hi), "1" (hi)); \
311 })
312
313# if defined(OPT_ACCURACY)
314/*
315 * This is accurate and ~2 - 2.5 times slower than the unrounded version.
316 *
317 * The __volatile__ improves the generated code by another 5% (fewer spills
318 * to memory); eventually they should be removed.
319 */
320# define mad_f_scale64(hi, lo) \
321 ({ mad_fixed_t __result; \
322 mad_fixed64hi_t __hi_; \
323 mad_fixed64lo_t __lo_; \
324 asm __volatile__ ("addc %0, %2, %4\n\t" \
325 "addze %1, %3" \
326 : "=r" (__lo_), "=r" (__hi_) \
327 : "r" (lo), "r" (hi), "r" (1 << (MAD_F_SCALEBITS - 1))); \
328 asm __volatile__ ("rlwinm %0, %2,32-%3,0,%3-1\n\t" \
329 "rlwimi %0, %1,32-%3,%3,31" \
330 : "=&r" (__result) \
331 : "r" (__lo_), "r" (__hi_), "I" (MAD_F_SCALEBITS)); \
332 __result; \
333 })
334# else
335# define mad_f_scale64(hi, lo) \
336 ({ mad_fixed_t __result; \
337 asm ("rlwinm %0, %2,32-%3,0,%3-1\n\t" \
338 "rlwimi %0, %1,32-%3,%3,31" \
339 : "=r" (__result) \
340 : "r" (lo), "r" (hi), "I" (MAD_F_SCALEBITS)); \
341 __result; \
342 })
343# endif /* OPT_ACCURACY */
344
345# define MAD_F_SCALEBITS MAD_F_FRACBITS
346
347/* --- Default ------------------------------------------------------------- */
348
349# elif defined(FPM_DEFAULT)
350
351/*
352 * This version is the most portable but it loses significant accuracy.
353 * Furthermore, accuracy is biased against the second argument, so care
354 * should be taken when ordering operands.
355 *
356 * The scale factors are constant as this is not used with SSO.
357 *
358 * Pre-rounding is required to stay within the limits of compliance.
359 */
360 # define mad_f_mul(x, y)((((x) + (1L << 11)) >> 12) * \
361 (((y) + (1L << 15)) >> 16))
362
363/* ------------------------------------------------------------------------- */
364
365# else
366# error "no FPM selected"
367# endif
368
369/* default implementations */
370
371# if !defined(mad_f_mul)
372# define mad_f_mul(x, y) \
373 ({ mad_fixed64hi_t __hi; \
374 mad_fixed64lo_t __lo; \
375 MAD_F_MLX(__hi, __lo, (x), (y)); \
376 mad_f_scale64(__hi, __lo); \
377 })
378# endif
379
380# if !defined(MAD_F_MLA)
381 # define MAD_F_ML0(hi, lo, x, y)((lo) = mad_f_mul((x), (y)))
382 # define MAD_F_MLA(hi, lo, x, y)((lo) += mad_f_mul((x), (y)))
383 # define MAD_F_MLZ(hi, lo) ((void) (hi), (mad_fixed_t) (lo))
384# endif
385
386# if !defined(MAD_F_ML0)
387 # define MAD_F_ML0(hi, lo, x, y)MAD_F_MLX((hi), (lo), (x), (y))
388# endif
389
390# if !defined(MAD_F_MLZ)
391 # define MAD_F_MLZ(hi, lo) mad_f_scale64((hi), (lo))
392# endif
393
394# if !defined(mad_f_scale64)
395# if defined(OPT_ACCURACY)
396# define mad_f_scale64(hi, lo) \
397 ((((mad_fixed_t) \
398 (((hi) << (32 - (MAD_F_SCALEBITS - 1))) | \
399 ((lo) >> (MAD_F_SCALEBITS - 1)))) + 1) >> 1)
400# else
401# define mad_f_scale64(hi, lo) \
402 ((mad_fixed_t) \
403 (((hi) << (32 - MAD_F_SCALEBITS)) | \
404 ((lo) >> MAD_F_SCALEBITS)))
405# endif
406# define MAD_F_SCALEBITS MAD_F_FRACBITS
407# endif
408
409/* miscellaneous C routines */
410
411mad_fixed_t mad_f_abs(mad_fixed_t);
412
413# 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 @@
1/*
2 * mad - MPEG audio decoder
3 * Copyright (C) 2000-2001 Robert Leslie
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * $Id$
20 */
21
22# ifdef HAVE_CONFIG_H
23# include "libmad_config.h"
24# endif
25
26# include "libmad_global.h"
27
28# include <stdlib.h>
29
30# include "bit.h"
31# include "stream.h"
32# include "frame.h"
33# include "timer.h"
34# include "layer12.h"
35# include "layer3.h"
36
37static
38unsigned long const bitrate_table[5][15] = {
39 /* MPEG-1 */
40 { 0, 32000, 64000, 96000, 128000, 160000, 192000, 224000, /* Layer I */
41 256000, 288000, 320000, 352000, 384000, 416000, 448000 },
42 { 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, /* Layer II */
43 128000, 160000, 192000, 224000, 256000, 320000, 384000 },
44 { 0, 32000, 40000, 48000, 56000, 64000, 80000, 96000, /* Layer III */
45 112000, 128000, 160000, 192000, 224000, 256000, 320000 },
46
47 /* MPEG-2 LSF */
48 { 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, /* Layer I */
49 128000, 144000, 160000, 176000, 192000, 224000, 256000 },
50 { 0, 8000, 16000, 24000, 32000, 40000, 48000, 56000, /* Layers */
51 64000, 80000, 96000, 112000, 128000, 144000, 160000 } /* II & III */
52};
53
54static
55unsigned int const samplerate_table[3] = { 44100, 48000, 32000 };
56
57static
58int (*const decoder_table[3])(struct mad_stream *, struct mad_frame *) = {
59 mad_layer_I,
60 mad_layer_II,
61 mad_layer_III
62};
63
64/*
65 * NAME:header->init()
66 * DESCRIPTION:initialize header struct
67 */
68void mad_header_init(struct mad_header *header)
69{
70 header->layer = 0;
71 header->mode = 0;
72 header->mode_extension = 0;
73 header->emphasis = 0;
74
75 header->bitrate = 0;
76 header->samplerate = 0;
77
78 header->crc_check = 0;
79 header->crc_target = 0;
80
81 header->flags = 0;
82 header->private_bits = 0;
83
84 header->duration = mad_timer_zero;
85}
86
87/*
88 * NAME:frame->init()
89 * DESCRIPTION:initialize frame struct
90 */
91void mad_frame_init(struct mad_frame *frame)
92{
93 mad_header_init(&frame->header);
94
95 frame->options = 0;
96
97 frame->overlap = 0;
98 mad_frame_mute(frame);
99}
100
101/*
102 * NAME:frame->finish()
103 * DESCRIPTION:deallocate any dynamic memory associated with frame
104 */
105void mad_frame_finish(struct mad_frame *frame)
106{
107 mad_header_finish(&frame->header);
108
109 if (frame->overlap) {
110 free(frame->overlap);
111 frame->overlap = 0;
112 }
113}
114
115/*
116 * NAME:decode_header()
117 * DESCRIPTION:read header data and following CRC word
118 */
119static
120int decode_header(struct mad_header *header, struct mad_stream *stream)
121{
122 unsigned int index;
123
124 header->flags = 0;
125 header->private_bits = 0;
126
127 /* header() */
128
129 /* syncword */
130 mad_bit_skip(&stream->ptr, 11);
131
132 /* MPEG 2.5 indicator (really part of syncword) */
133 if (mad_bit_read(&stream->ptr, 1) == 0)
134 header->flags |= MAD_FLAG_MPEG_2_5_EXT;
135
136 /* ID */
137 if (mad_bit_read(&stream->ptr, 1) == 0)
138 header->flags |= MAD_FLAG_LSF_EXT;
139 else if (header->flags & MAD_FLAG_MPEG_2_5_EXT) {
140 stream->error = MAD_ERROR_LOSTSYNC;
141 return -1;
142 }
143
144 /* layer */
145 header->layer = 4 - mad_bit_read(&stream->ptr, 2);
146
147 if (header->layer == 4) {
148 stream->error = MAD_ERROR_BADLAYER;
149 return -1;
150 }
151
152 /* protection_bit */
153 if (mad_bit_read(&stream->ptr, 1) == 0) {
154 header->flags |= MAD_FLAG_PROTECTION;
155 header->crc_check = mad_bit_crc(stream->ptr, 16, 0xffff);
156 }
157
158 /* bitrate_index */
159 index = mad_bit_read(&stream->ptr, 4);
160
161 if (index == 15) {
162 stream->error = MAD_ERROR_BADBITRATE;
163 return -1;
164 }
165
166 if (header->flags & MAD_FLAG_LSF_EXT)
167 header->bitrate = bitrate_table[3 + (header->layer >> 1)][index];
168 else
169 header->bitrate = bitrate_table[header->layer - 1][index];
170
171 /* sampling_frequency */
172 index = mad_bit_read(&stream->ptr, 2);
173
174 if (index == 3) {
175 stream->error = MAD_ERROR_BADSAMPLERATE;
176 return -1;
177 }
178
179 header->samplerate = samplerate_table[index];
180
181 if (header->flags & MAD_FLAG_LSF_EXT) {
182 header->samplerate /= 2;
183
184 if (header->flags & MAD_FLAG_MPEG_2_5_EXT)
185 header->samplerate /= 2;
186 }
187
188 /* padding_bit */
189 if (mad_bit_read(&stream->ptr, 1))
190 header->flags |= MAD_FLAG_PADDING;
191
192 /* private_bit */
193 if (mad_bit_read(&stream->ptr, 1))
194 header->private_bits |= MAD_PRIVATE_HEADER;
195
196 /* mode */
197 header->mode = 3 - mad_bit_read(&stream->ptr, 2);
198
199 /* mode_extension */
200 header->mode_extension = mad_bit_read(&stream->ptr, 2);
201
202 /* copyright */
203 if (mad_bit_read(&stream->ptr, 1))
204 header->flags |= MAD_FLAG_COPYRIGHT;
205
206 /* original/copy */
207 if (mad_bit_read(&stream->ptr, 1))
208 header->flags |= MAD_FLAG_ORIGINAL;
209
210 /* emphasis */
211 header->emphasis = mad_bit_read(&stream->ptr, 2);
212
213 if (header->emphasis == 2) {
214 stream->error = MAD_ERROR_BADEMPHASIS;
215 return -1;
216 }
217
218 /* error_check() */
219
220 /* crc_check */
221 if (header->flags & MAD_FLAG_PROTECTION)
222 header->crc_target = mad_bit_read(&stream->ptr, 16);
223
224 return 0;
225}
226
227/*
228 * NAME:free_bitrate()
229 * DESCRIPTION:attempt to discover the bitstream's free bitrate
230 */
231static
232int free_bitrate(struct mad_stream *stream, struct mad_header const *header)
233{
234 struct mad_bitptr keep_ptr;
235 unsigned long rate = 0;
236 unsigned int pad_slot, slots_per_frame;
237 unsigned char const *ptr = 0;
238
239 keep_ptr = stream->ptr;
240
241 pad_slot = (header->flags & MAD_FLAG_PADDING) ? 1 : 0;
242 slots_per_frame = (header->layer == MAD_LAYER_III &&
243 (header->flags & MAD_FLAG_LSF_EXT)) ? 72 : 144;
244
245 while (mad_stream_sync(stream) == 0) {
246 struct mad_stream peek_stream;
247 struct mad_header peek_header;
248
249 peek_stream = *stream;
250 peek_header = *header;
251
252 if (decode_header(&peek_header, &peek_stream) == 0 &&
253 peek_header.layer == header->layer &&
254 peek_header.samplerate == header->samplerate) {
255 unsigned int N;
256
257 ptr = mad_bit_nextbyte(&stream->ptr);
258
259 N = ptr - stream->this_frame;
260
261 if (header->layer == MAD_LAYER_I) {
262 rate = (unsigned long) header->samplerate *
263 (N - 4 * pad_slot + 4) / 48 / 1000;
264 }
265 else {
266 rate = (unsigned long) header->samplerate *
267 (N - pad_slot + 1) / slots_per_frame / 1000;
268 }
269
270 if (rate >= 8)
271 break;
272 }
273
274 mad_bit_skip(&stream->ptr, 8);
275 }
276
277 stream->ptr = keep_ptr;
278
279 if (rate < 8 || (header->layer == MAD_LAYER_III && rate > 640)) {
280 stream->error = MAD_ERROR_LOSTSYNC;
281 return -1;
282 }
283
284 stream->freerate = rate * 1000;
285
286# if 0 && defined(DEBUG)
287 fprintf(stderr, "free bitrate == %lu\n", stream->freerate);
288# endif
289
290 return 0;
291}
292
293/*
294 * NAME:header->decode()
295 * DESCRIPTION:read the next frame header from the stream
296 */
297int mad_header_decode(struct mad_header *header, struct mad_stream *stream)
298{
299 register unsigned char const *ptr, *end;
300 unsigned int pad_slot, N;
301
302 ptr = stream->next_frame;
303 end = stream->bufend;
304
305 if (ptr == 0) {
306 stream->error = MAD_ERROR_BUFPTR;
307 goto fail;
308 }
309
310 /* stream skip */
311 if (stream->skiplen) {
312 if (!stream->sync)
313 ptr = stream->this_frame;
314
315 if (end - ptr < stream->skiplen) {
316 stream->skiplen -= end - ptr;
317 stream->next_frame = end;
318
319 stream->error = MAD_ERROR_BUFLEN;
320 goto fail;
321 }
322
323 ptr += stream->skiplen;
324 stream->skiplen = 0;
325
326 stream->sync = 1;
327 }
328
329 sync:
330 /* synchronize */
331 if (stream->sync) {
332 if (end - ptr < MAD_BUFFER_GUARD) {
333 stream->next_frame = ptr;
334
335 stream->error = MAD_ERROR_BUFLEN;
336 goto fail;
337 }
338 else if (!(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) {
339 /* mark point where frame sync word was expected */
340 stream->this_frame = ptr;
341 stream->next_frame = ptr + 1;
342
343 stream->error = MAD_ERROR_LOSTSYNC;
344 goto fail;
345 }
346 }
347 else {
348 mad_bit_init(&stream->ptr, ptr);
349
350 if (mad_stream_sync(stream) == -1) {
351 if (end - stream->next_frame >= MAD_BUFFER_GUARD)
352 stream->next_frame = end - MAD_BUFFER_GUARD;
353
354 stream->error = MAD_ERROR_BUFLEN;
355 goto fail;
356 }
357
358 ptr = mad_bit_nextbyte(&stream->ptr);
359 }
360
361 /* begin processing */
362 stream->this_frame = ptr;
363 stream->next_frame = ptr + 1; /* possibly bogus sync word */
364
365 mad_bit_init(&stream->ptr, stream->this_frame);
366
367 if (decode_header(header, stream) == -1)
368 goto fail;
369
370 /* calculate frame duration */
371 mad_timer_set(&header->duration, 0,
372 32 * MAD_NSBSAMPLES(header), header->samplerate);
373
374 /* calculate free bit rate */
375 if (header->bitrate == 0) {
376 if ((!stream->sync || !stream->freerate) &&
377 free_bitrate(stream, header) == -1)
378 goto fail;
379
380 header->bitrate = stream->freerate;
381 header->flags |= MAD_FLAG_FREEFORMAT;
382 }
383
384 /* calculate beginning of next frame */
385 pad_slot = (header->flags & MAD_FLAG_PADDING) ? 1 : 0;
386
387 if (header->layer == MAD_LAYER_I)
388 N = ((12 * header->bitrate / header->samplerate) + pad_slot) * 4;
389 else {
390 unsigned int slots_per_frame;
391
392 slots_per_frame = (header->layer == MAD_LAYER_III &&
393 (header->flags & MAD_FLAG_LSF_EXT)) ? 72 : 144;
394
395 N = (slots_per_frame * header->bitrate / header->samplerate) + pad_slot;
396 }
397
398 /* verify there is enough data left in buffer to decode this frame */
399 if (N + MAD_BUFFER_GUARD > end - stream->this_frame) {
400 stream->next_frame = stream->this_frame;
401
402 stream->error = MAD_ERROR_BUFLEN;
403 goto fail;
404 }
405
406 stream->next_frame = stream->this_frame + N;
407
408 if (!stream->sync) {
409 /* check that a valid frame header follows this frame */
410
411 ptr = stream->next_frame;
412 if (!(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) {
413 ptr = stream->next_frame = stream->this_frame + 1;
414 goto sync;
415 }
416
417 stream->sync = 1;
418 }
419
420 header->flags |= MAD_FLAG_INCOMPLETE;
421
422 return 0;
423
424 fail:
425 stream->sync = 0;
426
427 return -1;
428}
429
430/*
431 * NAME:frame->decode()
432 * DESCRIPTION:decode a single frame from a bitstream
433 */
434int mad_frame_decode(struct mad_frame *frame, struct mad_stream *stream)
435{
436 frame->options = stream->options;
437
438 /* header() */
439 /* error_check() */
440
441 if (!(frame->header.flags & MAD_FLAG_INCOMPLETE) &&
442 mad_header_decode(&frame->header, stream) == -1)
443 goto fail;
444
445 /* audio_data() */
446
447 frame->header.flags &= ~MAD_FLAG_INCOMPLETE;
448
449 if (decoder_table[frame->header.layer - 1](stream, frame) == -1) {
450 if (!MAD_RECOVERABLE(stream->error))
451 stream->next_frame = stream->this_frame;
452
453 goto fail;
454 }
455
456 /* ancillary_data() */
457
458 if (frame->header.layer != MAD_LAYER_III) {
459 struct mad_bitptr next_frame;
460
461 mad_bit_init(&next_frame, stream->next_frame);
462
463 stream->anc_ptr = stream->ptr;
464 stream->anc_bitlen = mad_bit_length(&stream->ptr, &next_frame);
465
466 mad_bit_finish(&next_frame);
467 }
468
469 return 0;
470
471 fail:
472 stream->anc_bitlen = 0;
473 return -1;
474}
475
476/*
477 * NAME:frame->mute()
478 * DESCRIPTION:zero all subband values so the frame becomes silent
479 */
480void mad_frame_mute(struct mad_frame *frame)
481{
482 unsigned int s, sb;
483
484 for (s = 0; s < 36; ++s) {
485 for (sb = 0; sb < 32; ++sb) {
486 frame->sbsample[0][s][sb] =
487 frame->sbsample[1][s][sb] = 0;
488 }
489 }
490
491 if (frame->overlap) {
492 for (s = 0; s < 18; ++s) {
493 for (sb = 0; sb < 32; ++sb) {
494 (*frame->overlap)[0][sb][s] =
495 (*frame->overlap)[1][sb][s] = 0;
496 }
497 }
498 }
499}
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 @@
1/*
2 * mad - MPEG audio decoder
3 * Copyright (C) 2000-2001 Robert Leslie
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * $Id$
20 */
21
22# ifndef LIBMAD_FRAME_H
23# define LIBMAD_FRAME_H
24
25# include "fixed.h"
26# include "timer.h"
27# include "stream.h"
28
29enum mad_layer {
30 MAD_LAYER_I = 1, /* Layer I */
31 MAD_LAYER_II = 2, /* Layer II */
32 MAD_LAYER_III = 3 /* Layer III */
33};
34
35enum mad_mode {
36 MAD_MODE_SINGLE_CHANNEL = 0, /* single channel */
37 MAD_MODE_DUAL_CHANNEL = 1, /* dual channel */
38 MAD_MODE_JOINT_STEREO = 2, /* joint (MS/intensity) stereo */
39 MAD_MODE_STEREO = 3 /* normal LR stereo */
40};
41
42enum mad_emphasis {
43 MAD_EMPHASIS_NONE = 0, /* no emphasis */
44 MAD_EMPHASIS_50_15_US = 1, /* 50/15 microseconds emphasis */
45 MAD_EMPHASIS_CCITT_J_17 = 3 /* CCITT J.17 emphasis */
46};
47
48struct mad_frame {
49 struct mad_header {
50 enum mad_layer layer; /* audio layer (1, 2, or 3) */
51 enum mad_mode mode; /* channel mode (see above) */
52 int mode_extension; /* additional mode info */
53 enum mad_emphasis emphasis; /* de-emphasis to use (see above) */
54
55 unsigned long bitrate; /* stream bitrate (bps) */
56 unsigned int samplerate; /* sampling frequency (Hz) */
57
58 unsigned short crc_check; /* frame CRC accumulator */
59 unsigned short crc_target; /* final target CRC checksum */
60
61 int flags; /* flags (see below) */
62 int private_bits; /* private bits (see below) */
63
64 mad_timer_t duration; /* audio playing time of frame */
65 } header;
66
67 int options; /* decoding options (from stream) */
68
69 mad_fixed_t sbsample[2][36][32];/* synthesis subband filter samples */
70 mad_fixed_t (*overlap)[2][32][18];/* Layer III block overlap data */
71};
72
73 # define MAD_NCHANNELS(header) ((header)->mode ? 2 : 1)
74# define MAD_NSBSAMPLES(header) \
75 ((header)->layer == MAD_LAYER_I ? 12 : \
76 (((header)->layer == MAD_LAYER_III && \
77 ((header)->flags & MAD_FLAG_LSF_EXT)) ? 18 : 36))
78
79enum {
80 MAD_FLAG_NPRIVATE_III = 0x0007,/* number of Layer III private bits */
81 MAD_FLAG_INCOMPLETE = 0x0008,/* header but not data is decoded */
82
83 MAD_FLAG_PROTECTION = 0x0010,/* frame has CRC protection */
84 MAD_FLAG_COPYRIGHT = 0x0020,/* frame is copyright */
85 MAD_FLAG_ORIGINAL = 0x0040,/* frame is original (else copy) */
86 MAD_FLAG_PADDING = 0x0080,/* frame has additional slot */
87
88 MAD_FLAG_I_STEREO = 0x0100,/* uses intensity joint stereo */
89 MAD_FLAG_MS_STEREO = 0x0200,/* uses middle/side joint stereo */
90 MAD_FLAG_FREEFORMAT = 0x0400,/* uses free format bitrate */
91
92 MAD_FLAG_LSF_EXT = 0x1000,/* lower sampling freq. extension */
93 MAD_FLAG_MC_EXT = 0x2000,/* multichannel audio extension */
94 MAD_FLAG_MPEG_2_5_EXT = 0x4000/* MPEG 2.5 (unofficial) extension */
95};
96
97enum {
98 MAD_PRIVATE_HEADER = 0x0100,/* header private bit */
99 MAD_PRIVATE_III = 0x001f/* Layer III private bits (up to 5) */
100};
101
102void mad_header_init(struct mad_header *);
103
104# define mad_header_finish(header) /* nothing */
105
106int mad_header_decode(struct mad_header *, struct mad_stream *);
107
108void mad_frame_init(struct mad_frame *);
109void mad_frame_finish(struct mad_frame *);
110
111int mad_frame_decode(struct mad_frame *, struct mad_stream *);
112
113void mad_frame_mute(struct mad_frame *);
114
115# 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 @@
1/*
2 * mad - MPEG audio decoder
3 * Copyright (C) 2000-2001 Robert Leslie
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * $Id$
20 */
21
22# ifdef HAVE_CONFIG_H
23# include "libmad_config.h"
24# endif
25
26# include "libmad_global.h"
27
28# include "huffman.h"
29
30/*
31 * These are the Huffman code words for Layer III.
32 * The data for these tables are derived from Table B.7 of ISO/IEC 11172-3.
33 *
34 * These tables support decoding up to 4 Huffman code bits at a time.
35 */
36
37 # define V(v, w, x, y, hlen){ { 1, hlen, v, w, x, y } }
38 # define PTR(offs, bits){ ptr: { 0, bits, offs } }
39
40static
41union huffquad const hufftabA[] = {
42 /* 0000 */ PTR(16, 2),
43 /* 0001 */ PTR(20, 2),
44 /* 0010 */ PTR(24, 1),
45 /* 0011 */ PTR(26, 1),
46 /* 0100 */ V(0, 0, 1, 0, 4),
47 /* 0101 */ V(0, 0, 0, 1, 4),
48 /* 0110 */ V(0, 1, 0, 0, 4),
49 /* 0111 */ V(1, 0, 0, 0, 4),
50 /* 1000 */ V(0, 0, 0, 0, 1),
51 /* 1001 */ V(0, 0, 0, 0, 1),
52 /* 1010 */ V(0, 0, 0, 0, 1),
53 /* 1011 */ V(0, 0, 0, 0, 1),
54 /* 1100 */ V(0, 0, 0, 0, 1),
55 /* 1101 */ V(0, 0, 0, 0, 1),
56 /* 1110 */ V(0, 0, 0, 0, 1),
57 /* 1111 */ V(0, 0, 0, 0, 1),
58
59 /* 0000 ... */
60 /* 00 */ V(1, 0, 1, 1, 2),/* 16 */
61 /* 01 */ V(1, 1, 1, 1, 2),
62 /* 10 */ V(1, 1, 0, 1, 2),
63 /* 11 */ V(1, 1, 1, 0, 2),
64
65 /* 0001 ... */
66 /* 00 */ V(0, 1, 1, 1, 2),/* 20 */
67 /* 01 */ V(0, 1, 0, 1, 2),
68 /* 10 */ V(1, 0, 0, 1, 1),
69 /* 11 */ V(1, 0, 0, 1, 1),
70
71 /* 0010 ... */
72 /* 0 */ V(0, 1, 1, 0, 1),/* 24 */
73 /* 1 */ V(0, 0, 1, 1, 1),
74
75 /* 0011 ... */
76 /* 0 */ V(1, 0, 1, 0, 1),/* 26 */
77 /* 1 */ V(1, 1, 0, 0, 1)
78};
79
80static
81union huffquad const hufftabB[] = {
82 /* 0000 */ V(1, 1, 1, 1, 4),
83 /* 0001 */ V(1, 1, 1, 0, 4),
84 /* 0010 */ V(1, 1, 0, 1, 4),
85 /* 0011 */ V(1, 1, 0, 0, 4),
86 /* 0100 */ V(1, 0, 1, 1, 4),
87 /* 0101 */ V(1, 0, 1, 0, 4),
88 /* 0110 */ V(1, 0, 0, 1, 4),
89 /* 0111 */ V(1, 0, 0, 0, 4),
90 /* 1000 */ V(0, 1, 1, 1, 4),
91 /* 1001 */ V(0, 1, 1, 0, 4),
92 /* 1010 */ V(0, 1, 0, 1, 4),
93 /* 1011 */ V(0, 1, 0, 0, 4),
94 /* 1100 */ V(0, 0, 1, 1, 4),
95 /* 1101 */ V(0, 0, 1, 0, 4),
96 /* 1110 */ V(0, 0, 0, 1, 4),
97 /* 1111 */ V(0, 0, 0, 0, 4)
98};
99
100# undef V
101# undef PTR
102
103 # define V(x, y, hlen) { { 1, hlen, x, y } }
104 # define PTR(offs, bits){ ptr: { 0, bits, offs } }
105
106static
107union huffpair const hufftab0[] = {
108 /* */ V(0, 0, 0)
109};
110
111static
112union huffpair const hufftab1[] = {
113 /* 000 */ V(1, 1, 3),
114 /* 001 */ V(0, 1, 3),
115 /* 010 */ V(1, 0, 2),
116 /* 011 */ V(1, 0, 2),
117 /* 100 */ V(0, 0, 1),
118 /* 101 */ V(0, 0, 1),
119 /* 110 */ V(0, 0, 1),
120 /* 111 */ V(0, 0, 1)
121};
122
123static
124union huffpair const hufftab2[] = {
125 /* 000 */ PTR(8, 3),
126 /* 001 */ V(1, 1, 3),
127 /* 010 */ V(0, 1, 3),
128 /* 011 */ V(1, 0, 3),
129 /* 100 */ V(0, 0, 1),
130 /* 101 */ V(0, 0, 1),
131 /* 110 */ V(0, 0, 1),
132 /* 111 */ V(0, 0, 1),
133
134 /* 000 ... */
135 /* 000 */ V(2, 2, 3),/* 8 */
136 /* 001 */ V(0, 2, 3),
137 /* 010 */ V(1, 2, 2),
138 /* 011 */ V(1, 2, 2),
139 /* 100 */ V(2, 1, 2),
140 /* 101 */ V(2, 1, 2),
141 /* 110 */ V(2, 0, 2),
142 /* 111 */ V(2, 0, 2)
143};
144
145static
146union huffpair const hufftab3[] = {
147 /* 000 */ PTR(8, 3),
148 /* 001 */ V(1, 0, 3),
149 /* 010 */ V(1, 1, 2),
150 /* 011 */ V(1, 1, 2),
151 /* 100 */ V(0, 1, 2),
152 /* 101 */ V(0, 1, 2),
153 /* 110 */ V(0, 0, 2),
154 /* 111 */ V(0, 0, 2),
155
156 /* 000 ... */
157 /* 000 */ V(2, 2, 3),/* 8 */
158 /* 001 */ V(0, 2, 3),
159 /* 010 */ V(1, 2, 2),
160 /* 011 */ V(1, 2, 2),
161 /* 100 */ V(2, 1, 2),
162 /* 101 */ V(2, 1, 2),
163 /* 110 */ V(2, 0, 2),
164 /* 111 */ V(2, 0, 2)
165};
166
167static
168union huffpair const hufftab5[] = {
169 /* 000 */ PTR(8, 4),
170 /* 001 */ V(1, 1, 3),
171 /* 010 */ V(0, 1, 3),
172 /* 011 */ V(1, 0, 3),
173 /* 100 */ V(0, 0, 1),
174 /* 101 */ V(0, 0, 1),
175 /* 110 */ V(0, 0, 1),
176 /* 111 */ V(0, 0, 1),
177
178 /* 000 ... */
179 /* 0000 */ PTR(24, 1),/* 8 */
180 /* 0001 */ V(3, 2, 4),
181 /* 0010 */ V(3, 1, 3),
182 /* 0011 */ V(3, 1, 3),
183 /* 0100 */ V(1, 3, 4),
184 /* 0101 */ V(0, 3, 4),
185 /* 0110 */ V(3, 0, 4),
186 /* 0111 */ V(2, 2, 4),
187 /* 1000 */ V(1, 2, 3),
188 /* 1001 */ V(1, 2, 3),
189 /* 1010 */ V(2, 1, 3),
190 /* 1011 */ V(2, 1, 3),
191 /* 1100 */ V(0, 2, 3),
192 /* 1101 */ V(0, 2, 3),
193 /* 1110 */ V(2, 0, 3),
194 /* 1111 */ V(2, 0, 3),
195
196 /* 000 0000 ... */
197 /* 0 */ V(3, 3, 1),/* 24 */
198 /* 1 */ V(2, 3, 1)
199};
200
201static
202union huffpair const hufftab6[] = {
203 /* 0000 */ PTR(16, 3),
204 /* 0001 */ PTR(24, 1),
205 /* 0010 */ PTR(26, 1),
206 /* 0011 */ V(1, 2, 4),
207 /* 0100 */ V(2, 1, 4),
208 /* 0101 */ V(2, 0, 4),
209 /* 0110 */ V(0, 1, 3),
210 /* 0111 */ V(0, 1, 3),
211 /* 1000 */ V(1, 1, 2),
212 /* 1001 */ V(1, 1, 2),
213 /* 1010 */ V(1, 1, 2),
214 /* 1011 */ V(1, 1, 2),
215 /* 1100 */ V(1, 0, 3),
216 /* 1101 */ V(1, 0, 3),
217 /* 1110 */ V(0, 0, 3),
218 /* 1111 */ V(0, 0, 3),
219
220 /* 0000 ... */
221 /* 000 */ V(3, 3, 3),/* 16 */
222 /* 001 */ V(0, 3, 3),
223 /* 010 */ V(2, 3, 2),
224 /* 011 */ V(2, 3, 2),
225 /* 100 */ V(3, 2, 2),
226 /* 101 */ V(3, 2, 2),
227 /* 110 */ V(3, 0, 2),
228 /* 111 */ V(3, 0, 2),
229
230 /* 0001 ... */
231 /* 0 */ V(1, 3, 1),/* 24 */
232 /* 1 */ V(3, 1, 1),
233
234 /* 0010 ... */
235 /* 0 */ V(2, 2, 1),/* 26 */
236 /* 1 */ V(0, 2, 1)
237};
238
239static
240union huffpair const hufftab7[] = {
241 /* 0000 */ PTR(16, 4),
242 /* 0001 */ PTR(32, 4),
243 /* 0010 */ PTR(48, 2),
244 /* 0011 */ V(1, 1, 4),
245 /* 0100 */ V(0, 1, 3),
246 /* 0101 */ V(0, 1, 3),
247 /* 0110 */ V(1, 0, 3),
248 /* 0111 */ V(1, 0, 3),
249 /* 1000 */ V(0, 0, 1),
250 /* 1001 */ V(0, 0, 1),
251 /* 1010 */ V(0, 0, 1),
252 /* 1011 */ V(0, 0, 1),
253 /* 1100 */ V(0, 0, 1),
254 /* 1101 */ V(0, 0, 1),
255 /* 1110 */ V(0, 0, 1),
256 /* 1111 */ V(0, 0, 1),
257
258 /* 0000 ... */
259 /* 0000 */ PTR(52, 2),/* 16 */
260 /* 0001 */ PTR(56, 1),
261 /* 0010 */ PTR(58, 1),
262 /* 0011 */ V(1, 5, 4),
263 /* 0100 */ V(5, 1, 4),
264 /* 0101 */ PTR(60, 1),
265 /* 0110 */ V(5, 0, 4),
266 /* 0111 */ PTR(62, 1),
267 /* 1000 */ V(2, 4, 4),
268 /* 1001 */ V(4, 2, 4),
269 /* 1010 */ V(1, 4, 3),
270 /* 1011 */ V(1, 4, 3),
271 /* 1100 */ V(4, 1, 3),
272 /* 1101 */ V(4, 1, 3),
273 /* 1110 */ V(4, 0, 3),
274 /* 1111 */ V(4, 0, 3),
275
276 /* 0001 ... */
277 /* 0000 */ V(0, 4, 4),/* 32 */
278 /* 0001 */ V(2, 3, 4),
279 /* 0010 */ V(3, 2, 4),
280 /* 0011 */ V(0, 3, 4),
281 /* 0100 */ V(1, 3, 3),
282 /* 0101 */ V(1, 3, 3),
283 /* 0110 */ V(3, 1, 3),
284 /* 0111 */ V(3, 1, 3),
285 /* 1000 */ V(3, 0, 3),
286 /* 1001 */ V(3, 0, 3),
287 /* 1010 */ V(2, 2, 3),
288 /* 1011 */ V(2, 2, 3),
289 /* 1100 */ V(1, 2, 2),
290 /* 1101 */ V(1, 2, 2),
291 /* 1110 */ V(1, 2, 2),
292 /* 1111 */ V(1, 2, 2),
293
294 /* 0010 ... */
295 /* 00 */ V(2, 1, 1),/* 48 */
296 /* 01 */ V(2, 1, 1),
297 /* 10 */ V(0, 2, 2),
298 /* 11 */ V(2, 0, 2),
299
300 /* 0000 0000 ... */
301 /* 00 */ V(5, 5, 2),/* 52 */
302 /* 01 */ V(4, 5, 2),
303 /* 10 */ V(5, 4, 2),
304 /* 11 */ V(5, 3, 2),
305
306 /* 0000 0001 ... */
307 /* 0 */ V(3, 5, 1),/* 56 */
308 /* 1 */ V(4, 4, 1),
309
310 /* 0000 0010 ... */
311 /* 0 */ V(2, 5, 1),/* 58 */
312 /* 1 */ V(5, 2, 1),
313
314 /* 0000 0101 ... */
315 /* 0 */ V(0, 5, 1),/* 60 */
316 /* 1 */ V(3, 4, 1),
317
318 /* 0000 0111 ... */
319 /* 0 */ V(4, 3, 1),/* 62 */
320 /* 1 */ V(3, 3, 1)
321};
322
323# if 0
324/* this version saves 8 entries (16 bytes) at the expense of
325 an extra lookup in 4 out of 36 cases */
326static
327union huffpair const hufftab8[] = {
328 /* 0000 */ PTR(16, 4),
329 /* 0001 */ PTR(32, 2),
330 /* 0010 */ V(1, 2, 4),
331 /* 0011 */ V(2, 1, 4),
332 /* 0100 */ V(1, 1, 2),
333 /* 0101 */ V(1, 1, 2),
334 /* 0110 */ V(1, 1, 2),
335 /* 0111 */ V(1, 1, 2),
336 /* 1000 */ V(0, 1, 3),
337 /* 1001 */ V(0, 1, 3),
338 /* 1010 */ V(1, 0, 3),
339 /* 1011 */ V(1, 0, 3),
340 /* 1100 */ V(0, 0, 2),
341 /* 1101 */ V(0, 0, 2),
342 /* 1110 */ V(0, 0, 2),
343 /* 1111 */ V(0, 0, 2),
344
345 /* 0000 ... */
346 /* 0000 */ PTR(36, 3),/* 16 */
347 /* 0001 */ PTR(44, 2),
348 /* 0010 */ PTR(48, 1),
349 /* 0011 */ V(1, 5, 4),
350 /* 0100 */ V(5, 1, 4),
351 /* 0101 */ PTR(50, 1),
352 /* 0110 */ PTR(52, 1),
353 /* 0111 */ V(2, 4, 4),
354 /* 1000 */ V(4, 2, 4),
355 /* 1001 */ V(1, 4, 4),
356 /* 1010 */ V(4, 1, 3),
357 /* 1011 */ V(4, 1, 3),
358 /* 1100 */ V(0, 4, 4),
359 /* 1101 */ V(4, 0, 4),
360 /* 1110 */ V(2, 3, 4),
361 /* 1111 */ V(3, 2, 4),
362
363 /* 0001 ... */
364 /* 00 */ PTR(54, 2),/* 32 */
365 /* 01 */ V(2, 2, 2),
366 /* 10 */ V(0, 2, 2),
367 /* 11 */ V(2, 0, 2),
368
369 /* 0000 0000 ... */
370 /* 000 */ V(5, 5, 3),/* 36 */
371 /* 001 */ V(5, 4, 3),
372 /* 010 */ V(4, 5, 2),
373 /* 011 */ V(4, 5, 2),
374 /* 100 */ V(5, 3, 1),
375 /* 101 */ V(5, 3, 1),
376 /* 110 */ V(5, 3, 1),
377 /* 111 */ V(5, 3, 1),
378
379 /* 0000 0001 ... */
380 /* 00 */ V(3, 5, 2),/* 44 */
381 /* 01 */ V(4, 4, 2),
382 /* 10 */ V(2, 5, 1),
383 /* 11 */ V(2, 5, 1),
384
385 /* 0000 0010 ... */
386 /* 0 */ V(5, 2, 1),/* 48 */
387 /* 1 */ V(0, 5, 1),
388
389 /* 0000 0101 ... */
390 /* 0 */ V(3, 4, 1),/* 50 */
391 /* 1 */ V(4, 3, 1),
392
393 /* 0000 0110 ... */
394 /* 0 */ V(5, 0, 1),/* 52 */
395 /* 1 */ V(3, 3, 1),
396
397 /* 0001 00 ... */
398 /* 00 */ V(1, 3, 2),/* 54 */
399 /* 01 */ V(3, 1, 2),
400 /* 10 */ V(0, 3, 2),
401 /* 11 */ V(3, 0, 2),
402};
403# else
404static
405union huffpair const hufftab8[] = {
406 /* 0000 */ PTR(16, 4),
407 /* 0001 */ PTR(32, 4),
408 /* 0010 */ V(1, 2, 4),
409 /* 0011 */ V(2, 1, 4),
410 /* 0100 */ V(1, 1, 2),
411 /* 0101 */ V(1, 1, 2),
412 /* 0110 */ V(1, 1, 2),
413 /* 0111 */ V(1, 1, 2),
414 /* 1000 */ V(0, 1, 3),
415 /* 1001 */ V(0, 1, 3),
416 /* 1010 */ V(1, 0, 3),
417 /* 1011 */ V(1, 0, 3),
418 /* 1100 */ V(0, 0, 2),
419 /* 1101 */ V(0, 0, 2),
420 /* 1110 */ V(0, 0, 2),
421 /* 1111 */ V(0, 0, 2),
422
423 /* 0000 ... */
424 /* 0000 */ PTR(48, 3),/* 16 */
425 /* 0001 */ PTR(56, 2),
426 /* 0010 */ PTR(60, 1),
427 /* 0011 */ V(1, 5, 4),
428 /* 0100 */ V(5, 1, 4),
429 /* 0101 */ PTR(62, 1),
430 /* 0110 */ PTR(64, 1),
431 /* 0111 */ V(2, 4, 4),
432 /* 1000 */ V(4, 2, 4),
433 /* 1001 */ V(1, 4, 4),
434 /* 1010 */ V(4, 1, 3),
435 /* 1011 */ V(4, 1, 3),
436 /* 1100 */ V(0, 4, 4),
437 /* 1101 */ V(4, 0, 4),
438 /* 1110 */ V(2, 3, 4),
439 /* 1111 */ V(3, 2, 4),
440
441 /* 0001 ... */
442 /* 0000 */ V(1, 3, 4),/* 32 */
443 /* 0001 */ V(3, 1, 4),
444 /* 0010 */ V(0, 3, 4),
445 /* 0011 */ V(3, 0, 4),
446 /* 0100 */ V(2, 2, 2),
447 /* 0101 */ V(2, 2, 2),
448 /* 0110 */ V(2, 2, 2),
449 /* 0111 */ V(2, 2, 2),
450 /* 1000 */ V(0, 2, 2),
451 /* 1001 */ V(0, 2, 2),
452 /* 1010 */ V(0, 2, 2),
453 /* 1011 */ V(0, 2, 2),
454 /* 1100 */ V(2, 0, 2),
455 /* 1101 */ V(2, 0, 2),
456 /* 1110 */ V(2, 0, 2),
457 /* 1111 */ V(2, 0, 2),
458
459 /* 0000 0000 ... */
460 /* 000 */ V(5, 5, 3),/* 48 */
461 /* 001 */ V(5, 4, 3),
462 /* 010 */ V(4, 5, 2),
463 /* 011 */ V(4, 5, 2),
464 /* 100 */ V(5, 3, 1),
465 /* 101 */ V(5, 3, 1),
466 /* 110 */ V(5, 3, 1),
467 /* 111 */ V(5, 3, 1),
468
469 /* 0000 0001 ... */
470 /* 00 */ V(3, 5, 2),/* 56 */
471 /* 01 */ V(4, 4, 2),
472 /* 10 */ V(2, 5, 1),
473 /* 11 */ V(2, 5, 1),
474
475 /* 0000 0010 ... */
476 /* 0 */ V(5, 2, 1),/* 60 */
477 /* 1 */ V(0, 5, 1),
478
479 /* 0000 0101 ... */
480 /* 0 */ V(3, 4, 1),/* 62 */
481 /* 1 */ V(4, 3, 1),
482
483 /* 0000 0110 ... */
484 /* 0 */ V(5, 0, 1),/* 64 */
485 /* 1 */ V(3, 3, 1)
486};
487# endif
488
489static
490union huffpair const hufftab9[] = {
491 /* 0000 */ PTR(16, 4),
492 /* 0001 */ PTR(32, 3),
493 /* 0010 */ PTR(40, 2),
494 /* 0011 */ PTR(44, 2),
495 /* 0100 */ PTR(48, 1),
496 /* 0101 */ V(1, 2, 4),
497 /* 0110 */ V(2, 1, 4),
498 /* 0111 */ V(2, 0, 4),
499 /* 1000 */ V(1, 1, 3),
500 /* 1001 */ V(1, 1, 3),
501 /* 1010 */ V(0, 1, 3),
502 /* 1011 */ V(0, 1, 3),
503 /* 1100 */ V(1, 0, 3),
504 /* 1101 */ V(1, 0, 3),
505 /* 1110 */ V(0, 0, 3),
506 /* 1111 */ V(0, 0, 3),
507
508 /* 0000 ... */
509 /* 0000 */ PTR(50, 1),/* 16 */
510 /* 0001 */ V(3, 5, 4),
511 /* 0010 */ V(5, 3, 4),
512 /* 0011 */ PTR(52, 1),
513 /* 0100 */ V(4, 4, 4),
514 /* 0101 */ V(2, 5, 4),
515 /* 0110 */ V(5, 2, 4),
516 /* 0111 */ V(1, 5, 4),
517 /* 1000 */ V(5, 1, 3),
518 /* 1001 */ V(5, 1, 3),
519 /* 1010 */ V(3, 4, 3),
520 /* 1011 */ V(3, 4, 3),
521 /* 1100 */ V(4, 3, 3),
522 /* 1101 */ V(4, 3, 3),
523 /* 1110 */ V(5, 0, 4),
524 /* 1111 */ V(0, 4, 4),
525
526 /* 0001 ... */
527 /* 000 */ V(2, 4, 3),/* 32 */
528 /* 001 */ V(4, 2, 3),
529 /* 010 */ V(3, 3, 3),
530 /* 011 */ V(4, 0, 3),
531 /* 100 */ V(1, 4, 2),
532 /* 101 */ V(1, 4, 2),
533 /* 110 */ V(4, 1, 2),
534 /* 111 */ V(4, 1, 2),
535
536 /* 0010 ... */
537 /* 00 */ V(2, 3, 2),/* 40 */
538 /* 01 */ V(3, 2, 2),
539 /* 10 */ V(1, 3, 1),
540 /* 11 */ V(1, 3, 1),
541
542 /* 0011 ... */
543 /* 00 */ V(3, 1, 1),/* 44 */
544 /* 01 */ V(3, 1, 1),
545 /* 10 */ V(0, 3, 2),
546 /* 11 */ V(3, 0, 2),
547
548 /* 0100 ... */
549 /* 0 */ V(2, 2, 1),/* 48 */
550 /* 1 */ V(0, 2, 1),
551
552 /* 0000 0000 ... */
553 /* 0 */ V(5, 5, 1),/* 50 */
554 /* 1 */ V(4, 5, 1),
555
556 /* 0000 0011 ... */
557 /* 0 */ V(5, 4, 1),/* 52 */
558 /* 1 */ V(0, 5, 1)
559};
560
561static
562union huffpair const hufftab10[] = {
563 /* 0000 */ PTR(16, 4),
564 /* 0001 */ PTR(32, 4),
565 /* 0010 */ PTR(48, 2),
566 /* 0011 */ V(1, 1, 4),
567 /* 0100 */ V(0, 1, 3),
568 /* 0101 */ V(0, 1, 3),
569 /* 0110 */ V(1, 0, 3),
570 /* 0111 */ V(1, 0, 3),
571 /* 1000 */ V(0, 0, 1),
572 /* 1001 */ V(0, 0, 1),
573 /* 1010 */ V(0, 0, 1),
574 /* 1011 */ V(0, 0, 1),
575 /* 1100 */ V(0, 0, 1),
576 /* 1101 */ V(0, 0, 1),
577 /* 1110 */ V(0, 0, 1),
578 /* 1111 */ V(0, 0, 1),
579
580 /* 0000 ... */
581 /* 0000 */ PTR(52, 3),/* 16 */
582 /* 0001 */ PTR(60, 2),
583 /* 0010 */ PTR(64, 3),
584 /* 0011 */ PTR(72, 1),
585 /* 0100 */ PTR(74, 2),
586 /* 0101 */ PTR(78, 2),
587 /* 0110 */ PTR(82, 2),
588 /* 0111 */ V(1, 7, 4),
589 /* 1000 */ V(7, 1, 4),
590 /* 1001 */ PTR(86, 1),
591 /* 1010 */ PTR(88, 2),
592 /* 1011 */ PTR(92, 2),
593 /* 1100 */ V(1, 6, 4),
594 /* 1101 */ V(6, 1, 4),
595 /* 1110 */ V(6, 0, 4),
596 /* 1111 */ PTR(96, 1),
597
598 /* 0001 ... */
599 /* 0000 */ PTR(98, 1),/* 32 */
600 /* 0001 */ PTR(100, 1),
601 /* 0010 */ V(1, 4, 4),
602 /* 0011 */ V(4, 1, 4),
603 /* 0100 */ V(4, 0, 4),
604 /* 0101 */ V(2, 3, 4),
605 /* 0110 */ V(3, 2, 4),
606 /* 0111 */ V(0, 3, 4),
607 /* 1000 */ V(1, 3, 3),
608 /* 1001 */ V(1, 3, 3),
609 /* 1010 */ V(3, 1, 3),
610 /* 1011 */ V(3, 1, 3),
611 /* 1100 */ V(3, 0, 3),
612 /* 1101 */ V(3, 0, 3),
613 /* 1110 */ V(2, 2, 3),
614 /* 1111 */ V(2, 2, 3),
615
616 /* 0010 ... */
617 /* 00 */ V(1, 2, 2),/* 48 */
618 /* 01 */ V(2, 1, 2),
619 /* 10 */ V(0, 2, 2),
620 /* 11 */ V(2, 0, 2),
621
622 /* 0000 0000 ... */
623 /* 000 */ V(7, 7, 3),/* 52 */
624 /* 001 */ V(6, 7, 3),
625 /* 010 */ V(7, 6, 3),
626 /* 011 */ V(5, 7, 3),
627 /* 100 */ V(7, 5, 3),
628 /* 101 */ V(6, 6, 3),
629 /* 110 */ V(4, 7, 2),
630 /* 111 */ V(4, 7, 2),
631
632 /* 0000 0001 ... */
633 /* 00 */ V(7, 4, 2),/* 60 */
634 /* 01 */ V(5, 6, 2),
635 /* 10 */ V(6, 5, 2),
636 /* 11 */ V(3, 7, 2),
637
638 /* 0000 0010 ... */
639 /* 000 */ V(7, 3, 2),/* 64 */
640 /* 001 */ V(7, 3, 2),
641 /* 010 */ V(4, 6, 2),
642 /* 011 */ V(4, 6, 2),
643 /* 100 */ V(5, 5, 3),
644 /* 101 */ V(5, 4, 3),
645 /* 110 */ V(6, 3, 2),
646 /* 111 */ V(6, 3, 2),
647
648 /* 0000 0011 ... */
649 /* 0 */ V(2, 7, 1),/* 72 */
650 /* 1 */ V(7, 2, 1),
651
652 /* 0000 0100 ... */
653 /* 00 */ V(6, 4, 2),/* 74 */
654 /* 01 */ V(0, 7, 2),
655 /* 10 */ V(7, 0, 1),
656 /* 11 */ V(7, 0, 1),
657
658 /* 0000 0101 ... */
659 /* 00 */ V(6, 2, 1),/* 78 */
660 /* 01 */ V(6, 2, 1),
661 /* 10 */ V(4, 5, 2),
662 /* 11 */ V(3, 5, 2),
663
664 /* 0000 0110 ... */
665 /* 00 */ V(0, 6, 1),/* 82 */
666 /* 01 */ V(0, 6, 1),
667 /* 10 */ V(5, 3, 2),
668 /* 11 */ V(4, 4, 2),
669
670 /* 0000 1001 ... */
671 /* 0 */ V(3, 6, 1),/* 86 */
672 /* 1 */ V(2, 6, 1),
673
674 /* 0000 1010 ... */
675 /* 00 */ V(2, 5, 2),/* 88 */
676 /* 01 */ V(5, 2, 2),
677 /* 10 */ V(1, 5, 1),
678 /* 11 */ V(1, 5, 1),
679
680 /* 0000 1011 ... */
681 /* 00 */ V(5, 1, 1),/* 92 */
682 /* 01 */ V(5, 1, 1),
683 /* 10 */ V(3, 4, 2),
684 /* 11 */ V(4, 3, 2),
685
686 /* 0000 1111 ... */
687 /* 0 */ V(0, 5, 1),/* 96 */
688 /* 1 */ V(5, 0, 1),
689
690 /* 0001 0000 ... */
691 /* 0 */ V(2, 4, 1),/* 98 */
692 /* 1 */ V(4, 2, 1),
693
694 /* 0001 0001 ... */
695 /* 0 */ V(3, 3, 1),/* 100 */
696 /* 1 */ V(0, 4, 1)
697};
698
699static
700union huffpair const hufftab11[] = {
701 /* 0000 */ PTR(16, 4),
702 /* 0001 */ PTR(32, 4),
703 /* 0010 */ PTR(48, 4),
704 /* 0011 */ PTR(64, 3),
705 /* 0100 */ V(1, 2, 4),
706 /* 0101 */ PTR(72, 1),
707 /* 0110 */ V(1, 1, 3),
708 /* 0111 */ V(1, 1, 3),
709 /* 1000 */ V(0, 1, 3),
710 /* 1001 */ V(0, 1, 3),
711 /* 1010 */ V(1, 0, 3),
712 /* 1011 */ V(1, 0, 3),
713 /* 1100 */ V(0, 0, 2),
714 /* 1101 */ V(0, 0, 2),
715 /* 1110 */ V(0, 0, 2),
716 /* 1111 */ V(0, 0, 2),
717
718 /* 0000 ... */
719 /* 0000 */ PTR(74, 2),/* 16 */
720 /* 0001 */ PTR(78, 3),
721 /* 0010 */ PTR(86, 2),
722 /* 0011 */ PTR(90, 1),
723 /* 0100 */ PTR(92, 2),
724 /* 0101 */ V(2, 7, 4),
725 /* 0110 */ V(7, 2, 4),
726 /* 0111 */ PTR(96, 1),
727 /* 1000 */ V(7, 1, 3),
728 /* 1001 */ V(7, 1, 3),
729 /* 1010 */ V(1, 7, 4),
730 /* 1011 */ V(7, 0, 4),
731 /* 1100 */ V(3, 6, 4),
732 /* 1101 */ V(6, 3, 4),
733 /* 1110 */ V(6, 0, 4),
734 /* 1111 */ PTR(98, 1),
735
736 /* 0001 ... */
737 /* 0000 */ PTR(100, 1),/* 32 */
738 /* 0001 */ V(1, 5, 4),
739 /* 0010 */ V(6, 2, 3),
740 /* 0011 */ V(6, 2, 3),
741 /* 0100 */ V(2, 6, 4),
742 /* 0101 */ V(0, 6, 4),
743 /* 0110 */ V(1, 6, 3),
744 /* 0111 */ V(1, 6, 3),
745 /* 1000 */ V(6, 1, 3),
746 /* 1001 */ V(6, 1, 3),
747 /* 1010 */ V(5, 1, 4),
748 /* 1011 */ V(3, 4, 4),
749 /* 1100 */ V(5, 0, 4),
750 /* 1101 */ PTR(102, 1),
751 /* 1110 */ V(2, 4, 4),
752 /* 1111 */ V(4, 2, 4),
753
754 /* 0010 ... */
755 /* 0000 */ V(1, 4, 4),/* 48 */
756 /* 0001 */ V(4, 1, 4),
757 /* 0010 */ V(0, 4, 4),
758 /* 0011 */ V(4, 0, 4),
759 /* 0100 */ V(2, 3, 3),
760 /* 0101 */ V(2, 3, 3),
761 /* 0110 */ V(3, 2, 3),
762 /* 0111 */ V(3, 2, 3),
763 /* 1000 */ V(1, 3, 2),
764 /* 1001 */ V(1, 3, 2),
765 /* 1010 */ V(1, 3, 2),
766 /* 1011 */ V(1, 3, 2),
767 /* 1100 */ V(3, 1, 2),
768 /* 1101 */ V(3, 1, 2),
769 /* 1110 */ V(3, 1, 2),
770 /* 1111 */ V(3, 1, 2),
771
772 /* 0011 ... */
773 /* 000 */ V(0, 3, 3),/* 64 */
774 /* 001 */ V(3, 0, 3),
775 /* 010 */ V(2, 2, 2),
776 /* 011 */ V(2, 2, 2),
777 /* 100 */ V(2, 1, 1),
778 /* 101 */ V(2, 1, 1),
779 /* 110 */ V(2, 1, 1),
780 /* 111 */ V(2, 1, 1),
781
782 /* 0101 ... */
783 /* 0 */ V(0, 2, 1),/* 72 */
784 /* 1 */ V(2, 0, 1),
785
786 /* 0000 0000 ... */
787 /* 00 */ V(7, 7, 2),/* 74 */
788 /* 01 */ V(6, 7, 2),
789 /* 10 */ V(7, 6, 2),
790 /* 11 */ V(7, 5, 2),
791
792 /* 0000 0001 ... */
793 /* 000 */ V(6, 6, 2),/* 78 */
794 /* 001 */ V(6, 6, 2),
795 /* 010 */ V(4, 7, 2),
796 /* 011 */ V(4, 7, 2),
797 /* 100 */ V(7, 4, 2),
798 /* 101 */ V(7, 4, 2),
799 /* 110 */ V(5, 7, 3),
800 /* 111 */ V(5, 5, 3),
801
802 /* 0000 0010 ... */
803 /* 00 */ V(5, 6, 2),/* 86 */
804 /* 01 */ V(6, 5, 2),
805 /* 10 */ V(3, 7, 1),
806 /* 11 */ V(3, 7, 1),
807
808 /* 0000 0011 ... */
809 /* 0 */ V(7, 3, 1),/* 90 */
810 /* 1 */ V(4, 6, 1),
811
812 /* 0000 0100 ... */
813 /* 00 */ V(4, 5, 2),/* 92 */
814 /* 01 */ V(5, 4, 2),
815 /* 10 */ V(3, 5, 2),
816 /* 11 */ V(5, 3, 2),
817
818 /* 0000 0111 ... */
819 /* 0 */ V(6, 4, 1),/* 96 */
820 /* 1 */ V(0, 7, 1),
821
822 /* 0000 1111 ... */
823 /* 0 */ V(4, 4, 1),/* 98 */
824 /* 1 */ V(2, 5, 1),
825
826 /* 0001 0000 ... */
827 /* 0 */ V(5, 2, 1),/* 100 */
828 /* 1 */ V(0, 5, 1),
829
830 /* 0001 1101 ... */
831 /* 0 */ V(4, 3, 1),/* 102 */
832 /* 1 */ V(3, 3, 1)
833};
834
835static
836union huffpair const hufftab12[] = {
837 /* 0000 */ PTR(16, 4),
838 /* 0001 */ PTR(32, 4),
839 /* 0010 */ PTR(48, 4),
840 /* 0011 */ PTR(64, 2),
841 /* 0100 */ PTR(68, 3),
842 /* 0101 */ PTR(76, 1),
843 /* 0110 */ V(1, 2, 4),
844 /* 0111 */ V(2, 1, 4),
845 /* 1000 */ PTR(78, 1),
846 /* 1001 */ V(0, 0, 4),
847 /* 1010 */ V(1, 1, 3),
848 /* 1011 */ V(1, 1, 3),
849 /* 1100 */ V(0, 1, 3),
850 /* 1101 */ V(0, 1, 3),
851 /* 1110 */ V(1, 0, 3),
852 /* 1111 */ V(1, 0, 3),
853
854 /* 0000 ... */
855 /* 0000 */ PTR(80, 2),/* 16 */
856 /* 0001 */ PTR(84, 1),
857 /* 0010 */ PTR(86, 1),
858 /* 0011 */ PTR(88, 1),
859 /* 0100 */ V(5, 6, 4),
860 /* 0101 */ V(3, 7, 4),
861 /* 0110 */ PTR(90, 1),
862 /* 0111 */ V(2, 7, 4),
863 /* 1000 */ V(7, 2, 4),
864 /* 1001 */ V(4, 6, 4),
865 /* 1010 */ V(6, 4, 4),
866 /* 1011 */ V(1, 7, 4),
867 /* 1100 */ V(7, 1, 4),
868 /* 1101 */ PTR(92, 1),
869 /* 1110 */ V(3, 6, 4),
870 /* 1111 */ V(6, 3, 4),
871
872 /* 0001 ... */
873 /* 0000 */ V(4, 5, 4),/* 32 */
874 /* 0001 */ V(5, 4, 4),
875 /* 0010 */ V(4, 4, 4),
876 /* 0011 */ PTR(94, 1),
877 /* 0100 */ V(2, 6, 3),
878 /* 0101 */ V(2, 6, 3),
879 /* 0110 */ V(6, 2, 3),
880 /* 0111 */ V(6, 2, 3),
881 /* 1000 */ V(6, 1, 3),
882 /* 1001 */ V(6, 1, 3),
883 /* 1010 */ V(1, 6, 4),
884 /* 1011 */ V(6, 0, 4),
885 /* 1100 */ V(3, 5, 4),
886 /* 1101 */ V(5, 3, 4),
887 /* 1110 */ V(2, 5, 4),
888 /* 1111 */ V(5, 2, 4),
889
890 /* 0010 ... */
891 /* 0000 */ V(1, 5, 3),/* 48 */
892 /* 0001 */ V(1, 5, 3),
893 /* 0010 */ V(5, 1, 3),
894 /* 0011 */ V(5, 1, 3),
895 /* 0100 */ V(3, 4, 3),
896 /* 0101 */ V(3, 4, 3),
897 /* 0110 */ V(4, 3, 3),
898 /* 0111 */ V(4, 3, 3),
899 /* 1000 */ V(5, 0, 4),
900 /* 1001 */ V(0, 4, 4),
901 /* 1010 */ V(2, 4, 3),
902 /* 1011 */ V(2, 4, 3),
903 /* 1100 */ V(4, 2, 3),
904 /* 1101 */ V(4, 2, 3),
905 /* 1110 */ V(1, 4, 3),
906 /* 1111 */ V(1, 4, 3),
907
908 /* 0011 ... */
909 /* 00 */ V(3, 3, 2),/* 64 */
910 /* 01 */ V(4, 1, 2),
911 /* 10 */ V(2, 3, 2),
912 /* 11 */ V(3, 2, 2),
913
914 /* 0100 ... */
915 /* 000 */ V(4, 0, 3),/* 68 */
916 /* 001 */ V(0, 3, 3),
917 /* 010 */ V(3, 0, 2),
918 /* 011 */ V(3, 0, 2),
919 /* 100 */ V(1, 3, 1),
920 /* 101 */ V(1, 3, 1),
921 /* 110 */ V(1, 3, 1),
922 /* 111 */ V(1, 3, 1),
923
924 /* 0101 ... */
925 /* 0 */ V(3, 1, 1),/* 76 */
926 /* 1 */ V(2, 2, 1),
927
928 /* 1000 ... */
929 /* 0 */ V(0, 2, 1),/* 78 */
930 /* 1 */ V(2, 0, 1),
931
932 /* 0000 0000 ... */
933 /* 00 */ V(7, 7, 2),/* 80 */
934 /* 01 */ V(6, 7, 2),
935 /* 10 */ V(7, 6, 1),
936 /* 11 */ V(7, 6, 1),
937
938 /* 0000 0001 ... */
939 /* 0 */ V(5, 7, 1),/* 84 */
940 /* 1 */ V(7, 5, 1),
941
942 /* 0000 0010 ... */
943 /* 0 */ V(6, 6, 1),/* 86 */
944 /* 1 */ V(4, 7, 1),
945
946 /* 0000 0011 ... */
947 /* 0 */ V(7, 4, 1),/* 88 */
948 /* 1 */ V(6, 5, 1),
949
950 /* 0000 0110 ... */
951 /* 0 */ V(7, 3, 1),/* 90 */
952 /* 1 */ V(5, 5, 1),
953
954 /* 0000 1101 ... */
955 /* 0 */ V(0, 7, 1),/* 92 */
956 /* 1 */ V(7, 0, 1),
957
958 /* 0001 0011 ... */
959 /* 0 */ V(0, 6, 1),/* 94 */
960 /* 1 */ V(0, 5, 1)
961};
962
963static
964union huffpair const hufftab13[] = {
965 /* 0000 */ PTR(16, 4),
966 /* 0001 */ PTR(32, 4),
967 /* 0010 */ PTR(48, 4),
968 /* 0011 */ PTR(64, 2),
969 /* 0100 */ V(1, 1, 4),
970 /* 0101 */ V(0, 1, 4),
971 /* 0110 */ V(1, 0, 3),
972 /* 0111 */ V(1, 0, 3),
973 /* 1000 */ V(0, 0, 1),
974 /* 1001 */ V(0, 0, 1),
975 /* 1010 */ V(0, 0, 1),
976 /* 1011 */ V(0, 0, 1),
977 /* 1100 */ V(0, 0, 1),
978 /* 1101 */ V(0, 0, 1),
979 /* 1110 */ V(0, 0, 1),
980 /* 1111 */ V(0, 0, 1),
981
982 /* 0000 ... */
983 /* 0000 */ PTR(68, 4),/* 16 */
984 /* 0001 */ PTR(84, 4),
985 /* 0010 */ PTR(100, 4),
986 /* 0011 */ PTR(116, 4),
987 /* 0100 */ PTR(132, 4),
988 /* 0101 */ PTR(148, 4),
989 /* 0110 */ PTR(164, 3),
990 /* 0111 */ PTR(172, 3),
991 /* 1000 */ PTR(180, 3),
992 /* 1001 */ PTR(188, 3),
993 /* 1010 */ PTR(196, 3),
994 /* 1011 */ PTR(204, 3),
995 /* 1100 */ PTR(212, 1),
996 /* 1101 */ PTR(214, 2),
997 /* 1110 */ PTR(218, 3),
998 /* 1111 */ PTR(226, 1),
999
1000 /* 0001 ... */
1001 /* 0000 */ PTR(228, 2),/* 32 */
1002 /* 0001 */ PTR(232, 2),
1003 /* 0010 */ PTR(236, 2),
1004 /* 0011 */ PTR(240, 2),
1005 /* 0100 */ V(8, 1, 4),
1006 /* 0101 */ PTR(244, 1),
1007 /* 0110 */ PTR(246, 1),
1008 /* 0111 */ PTR(248, 1),
1009 /* 1000 */ PTR(250, 2),
1010 /* 1001 */ PTR(254, 1),
1011 /* 1010 */ V(1, 5, 4),
1012 /* 1011 */ V(5, 1, 4),
1013 /* 1100 */ PTR(256, 1),
1014 /* 1101 */ PTR(258, 1),
1015 /* 1110 */ PTR(260, 1),
1016 /* 1111 */ V(1, 4, 4),
1017
1018 /* 0010 ... */
1019 /* 0000 */ V(4, 1, 3),/* 48 */
1020 /* 0001 */ V(4, 1, 3),
1021 /* 0010 */ V(0, 4, 4),
1022 /* 0011 */ V(4, 0, 4),
1023 /* 0100 */ V(2, 3, 4),
1024 /* 0101 */ V(3, 2, 4),
1025 /* 0110 */ V(1, 3, 3),
1026 /* 0111 */ V(1, 3, 3),
1027 /* 1000 */ V(3, 1, 3),
1028 /* 1001 */ V(3, 1, 3),
1029 /* 1010 */ V(0, 3, 3),
1030 /* 1011 */ V(0, 3, 3),
1031 /* 1100 */ V(3, 0, 3),
1032 /* 1101 */ V(3, 0, 3),
1033 /* 1110 */ V(2, 2, 3),
1034 /* 1111 */ V(2, 2, 3),
1035
1036 /* 0011 ... */
1037 /* 00 */ V(1, 2, 2),/* 64 */
1038 /* 01 */ V(2, 1, 2),
1039 /* 10 */ V(0, 2, 2),
1040 /* 11 */ V(2, 0, 2),
1041
1042 /* 0000 0000 ... */
1043 /* 0000 */ PTR(262, 4),/* 68 */
1044 /* 0001 */ PTR(278, 4),
1045 /* 0010 */ PTR(294, 4),
1046 /* 0011 */ PTR(310, 3),
1047 /* 0100 */ PTR(318, 2),
1048 /* 0101 */ PTR(322, 2),
1049 /* 0110 */ PTR(326, 3),
1050 /* 0111 */ PTR(334, 2),
1051 /* 1000 */ PTR(338, 1),
1052 /* 1001 */ PTR(340, 2),
1053 /* 1010 */ PTR(344, 2),
1054 /* 1011 */ PTR(348, 2),
1055 /* 1100 */ PTR(352, 2),
1056 /* 1101 */ PTR(356, 2),
1057 /* 1110 */ V(1, 15, 4),
1058 /* 1111 */ V(15, 1, 4),
1059
1060 /* 0000 0001 ... */
1061 /* 0000 */ V(15, 0, 4),/* 84 */
1062 /* 0001 */ PTR(360, 1),
1063 /* 0010 */ PTR(362, 1),
1064 /* 0011 */ PTR(364, 1),
1065 /* 0100 */ V(14, 2, 4),
1066 /* 0101 */ PTR(366, 1),
1067 /* 0110 */ V(1, 14, 4),
1068 /* 0111 */ V(14, 1, 4),
1069 /* 1000 */ PTR(368, 1),
1070 /* 1001 */ PTR(370, 1),
1071 /* 1010 */ PTR(372, 1),
1072 /* 1011 */ PTR(374, 1),
1073 /* 1100 */ PTR(376, 1),
1074 /* 1101 */ PTR(378, 1),
1075 /* 1110 */ V(12, 6, 4),
1076 /* 1111 */ V(3, 13, 4),
1077
1078 /* 0000 0010 ... */
1079 /* 0000 */ PTR(380, 1),/* 100 */
1080 /* 0001 */ V(2, 13, 4),
1081 /* 0010 */ V(13, 2, 4),
1082 /* 0011 */ V(1, 13, 4),
1083 /* 0100 */ V(11, 7, 4),
1084 /* 0101 */ PTR(382, 1),
1085 /* 0110 */ PTR(384, 1),
1086 /* 0111 */ V(12, 3, 4),
1087 /* 1000 */ PTR(386, 1),
1088 /* 1001 */ V(4, 11, 4),
1089 /* 1010 */ V(13, 1, 3),
1090 /* 1011 */ V(13, 1, 3),
1091 /* 1100 */ V(0, 13, 4),
1092 /* 1101 */ V(13, 0, 4),
1093 /* 1110 */ V(8, 10, 4),
1094 /* 1111 */ V(10, 8, 4),
1095
1096 /* 0000 0011 ... */
1097 /* 0000 */ V(4, 12, 4),/* 116 */
1098 /* 0001 */ V(12, 4, 4),
1099 /* 0010 */ V(6, 11, 4),
1100 /* 0011 */ V(11, 6, 4),
1101 /* 0100 */ V(3, 12, 3),
1102 /* 0101 */ V(3, 12, 3),
1103 /* 0110 */ V(2, 12, 3),
1104 /* 0111 */ V(2, 12, 3),
1105 /* 1000 */ V(12, 2, 3),
1106 /* 1001 */ V(12, 2, 3),
1107 /* 1010 */ V(5, 11, 3),
1108 /* 1011 */ V(5, 11, 3),
1109 /* 1100 */ V(11, 5, 4),
1110 /* 1101 */ V(8, 9, 4),
1111 /* 1110 */ V(1, 12, 3),
1112 /* 1111 */ V(1, 12, 3),
1113
1114 /* 0000 0100 ... */
1115 /* 0000 */ V(12, 1, 3),/* 132 */
1116 /* 0001 */ V(12, 1, 3),
1117 /* 0010 */ V(9, 8, 4),
1118 /* 0011 */ V(0, 12, 4),
1119 /* 0100 */ V(12, 0, 3),
1120 /* 0101 */ V(12, 0, 3),
1121 /* 0110 */ V(11, 4, 4),
1122 /* 0111 */ V(6, 10, 4),
1123 /* 1000 */ V(10, 6, 4),
1124 /* 1001 */ V(7, 9, 4),
1125 /* 1010 */ V(3, 11, 3),
1126 /* 1011 */ V(3, 11, 3),
1127 /* 1100 */ V(11, 3, 3),
1128 /* 1101 */ V(11, 3, 3),
1129 /* 1110 */ V(8, 8, 4),
1130 /* 1111 */ V(5, 10, 4),
1131
1132 /* 0000 0101 ... */
1133 /* 0000 */ V(2, 11, 3),/* 148 */
1134 /* 0001 */ V(2, 11, 3),
1135 /* 0010 */ V(10, 5, 4),
1136 /* 0011 */ V(6, 9, 4),
1137 /* 0100 */ V(10, 4, 3),
1138 /* 0101 */ V(10, 4, 3),
1139 /* 0110 */ V(7, 8, 4),
1140 /* 0111 */ V(8, 7, 4),
1141 /* 1000 */ V(9, 4, 3),
1142 /* 1001 */ V(9, 4, 3),
1143 /* 1010 */ V(7, 7, 4),
1144 /* 1011 */ V(7, 6, 4),
1145 /* 1100 */ V(11, 2, 2),
1146 /* 1101 */ V(11, 2, 2),
1147 /* 1110 */ V(11, 2, 2),
1148 /* 1111 */ V(11, 2, 2),
1149
1150 /* 0000 0110 ... */
1151 /* 000 */ V(1, 11, 2),/* 164 */
1152 /* 001 */ V(1, 11, 2),
1153 /* 010 */ V(11, 1, 2),
1154 /* 011 */ V(11, 1, 2),
1155 /* 100 */ V(0, 11, 3),
1156 /* 101 */ V(11, 0, 3),
1157 /* 110 */ V(9, 6, 3),
1158 /* 111 */ V(4, 10, 3),
1159
1160 /* 0000 0111 ... */
1161 /* 000 */ V(3, 10, 3),/* 172 */
1162 /* 001 */ V(10, 3, 3),
1163 /* 010 */ V(5, 9, 3),
1164 /* 011 */ V(9, 5, 3),
1165 /* 100 */ V(2, 10, 2),
1166 /* 101 */ V(2, 10, 2),
1167 /* 110 */ V(10, 2, 2),
1168 /* 111 */ V(10, 2, 2),
1169
1170 /* 0000 1000 ... */
1171 /* 000 */ V(1, 10, 2),/* 180 */
1172 /* 001 */ V(1, 10, 2),
1173 /* 010 */ V(10, 1, 2),
1174 /* 011 */ V(10, 1, 2),
1175 /* 100 */ V(0, 10, 3),
1176 /* 101 */ V(6, 8, 3),
1177 /* 110 */ V(10, 0, 2),
1178 /* 111 */ V(10, 0, 2),
1179
1180 /* 0000 1001 ... */
1181 /* 000 */ V(8, 6, 3),/* 188 */
1182 /* 001 */ V(4, 9, 3),
1183 /* 010 */ V(9, 3, 2),
1184 /* 011 */ V(9, 3, 2),
1185 /* 100 */ V(3, 9, 3),
1186 /* 101 */ V(5, 8, 3),
1187 /* 110 */ V(8, 5, 3),
1188 /* 111 */ V(6, 7, 3),
1189
1190 /* 0000 1010 ... */
1191 /* 000 */ V(2, 9, 2),/* 196 */
1192 /* 001 */ V(2, 9, 2),
1193 /* 010 */ V(9, 2, 2),
1194 /* 011 */ V(9, 2, 2),
1195 /* 100 */ V(5, 7, 3),
1196 /* 101 */ V(7, 5, 3),
1197 /* 110 */ V(3, 8, 2),
1198 /* 111 */ V(3, 8, 2),
1199
1200 /* 0000 1011 ... */
1201 /* 000 */ V(8, 3, 2),/* 204 */
1202 /* 001 */ V(8, 3, 2),
1203 /* 010 */ V(6, 6, 3),
1204 /* 011 */ V(4, 7, 3),
1205 /* 100 */ V(7, 4, 3),
1206 /* 101 */ V(5, 6, 3),
1207 /* 110 */ V(6, 5, 3),
1208 /* 111 */ V(7, 3, 3),
1209
1210 /* 0000 1100 ... */
1211 /* 0 */ V(1, 9, 1),/* 212 */
1212 /* 1 */ V(9, 1, 1),
1213
1214 /* 0000 1101 ... */
1215 /* 00 */ V(0, 9, 2),/* 214 */
1216 /* 01 */ V(9, 0, 2),
1217 /* 10 */ V(4, 8, 2),
1218 /* 11 */ V(8, 4, 2),
1219
1220 /* 0000 1110 ... */
1221 /* 000 */ V(7, 2, 2),/* 218 */
1222 /* 001 */ V(7, 2, 2),
1223 /* 010 */ V(4, 6, 3),
1224 /* 011 */ V(6, 4, 3),
1225 /* 100 */ V(2, 8, 1),
1226 /* 101 */ V(2, 8, 1),
1227 /* 110 */ V(2, 8, 1),
1228 /* 111 */ V(2, 8, 1),
1229
1230 /* 0000 1111 ... */
1231 /* 0 */ V(8, 2, 1),/* 226 */
1232 /* 1 */ V(1, 8, 1),
1233
1234 /* 0001 0000 ... */
1235 /* 00 */ V(3, 7, 2),/* 228 */
1236 /* 01 */ V(2, 7, 2),
1237 /* 10 */ V(1, 7, 1),
1238 /* 11 */ V(1, 7, 1),
1239
1240 /* 0001 0001 ... */
1241 /* 00 */ V(7, 1, 1),/* 232 */
1242 /* 01 */ V(7, 1, 1),
1243 /* 10 */ V(5, 5, 2),
1244 /* 11 */ V(0, 7, 2),
1245
1246 /* 0001 0010 ... */
1247 /* 00 */ V(7, 0, 2),/* 236 */
1248 /* 01 */ V(3, 6, 2),
1249 /* 10 */ V(6, 3, 2),
1250 /* 11 */ V(4, 5, 2),
1251
1252 /* 0001 0011 ... */
1253 /* 00 */ V(5, 4, 2),/* 240 */
1254 /* 01 */ V(2, 6, 2),
1255 /* 10 */ V(6, 2, 2),
1256 /* 11 */ V(3, 5, 2),
1257
1258 /* 0001 0101 ... */
1259 /* 0 */ V(0, 8, 1),/* 244 */
1260 /* 1 */ V(8, 0, 1),
1261
1262 /* 0001 0110 ... */
1263 /* 0 */ V(1, 6, 1),/* 246 */
1264 /* 1 */ V(6, 1, 1),
1265
1266 /* 0001 0111 ... */
1267 /* 0 */ V(0, 6, 1),/* 248 */
1268 /* 1 */ V(6, 0, 1),
1269
1270 /* 0001 1000 ... */
1271 /* 00 */ V(5, 3, 2),/* 250 */
1272 /* 01 */ V(4, 4, 2),
1273 /* 10 */ V(2, 5, 1),
1274 /* 11 */ V(2, 5, 1),
1275
1276 /* 0001 1001 ... */
1277 /* 0 */ V(5, 2, 1),/* 254 */
1278 /* 1 */ V(0, 5, 1),
1279
1280 /* 0001 1100 ... */
1281 /* 0 */ V(3, 4, 1),/* 256 */
1282 /* 1 */ V(4, 3, 1),
1283
1284 /* 0001 1101 ... */
1285 /* 0 */ V(5, 0, 1),/* 258 */
1286 /* 1 */ V(2, 4, 1),
1287
1288 /* 0001 1110 ... */
1289 /* 0 */ V(4, 2, 1),/* 260 */
1290 /* 1 */ V(3, 3, 1),
1291
1292 /* 0000 0000 0000 ... */
1293 /* 0000 */ PTR(388, 3),/* 262 */
1294 /* 0001 */ V(15, 15, 4),
1295 /* 0010 */ V(14, 15, 4),
1296 /* 0011 */ V(13, 15, 4),
1297 /* 0100 */ V(14, 14, 4),
1298 /* 0101 */ V(12, 15, 4),
1299 /* 0110 */ V(13, 14, 4),
1300 /* 0111 */ V(11, 15, 4),
1301 /* 1000 */ V(15, 11, 4),
1302 /* 1001 */ V(12, 14, 4),
1303 /* 1010 */ V(13, 12, 4),
1304 /* 1011 */ PTR(396, 1),
1305 /* 1100 */ V(14, 12, 3),
1306 /* 1101 */ V(14, 12, 3),
1307 /* 1110 */ V(13, 13, 3),
1308 /* 1111 */ V(13, 13, 3),
1309
1310 /* 0000 0000 0001 ... */
1311 /* 0000 */ V(15, 10, 4),/* 278 */
1312 /* 0001 */ V(12, 13, 4),
1313 /* 0010 */ V(11, 14, 3),
1314 /* 0011 */ V(11, 14, 3),
1315 /* 0100 */ V(14, 11, 3),
1316 /* 0101 */ V(14, 11, 3),
1317 /* 0110 */ V(9, 15, 3),
1318 /* 0111 */ V(9, 15, 3),
1319 /* 1000 */ V(15, 9, 3),
1320 /* 1001 */ V(15, 9, 3),
1321 /* 1010 */ V(14, 10, 3),
1322 /* 1011 */ V(14, 10, 3),
1323 /* 1100 */ V(11, 13, 3),
1324 /* 1101 */ V(11, 13, 3),
1325 /* 1110 */ V(13, 11, 3),
1326 /* 1111 */ V(13, 11, 3),
1327
1328 /* 0000 0000 0010 ... */
1329 /* 0000 */ V(8, 15, 3),/* 294 */
1330 /* 0001 */ V(8, 15, 3),
1331 /* 0010 */ V(15, 8, 3),
1332 /* 0011 */ V(15, 8, 3),
1333 /* 0100 */ V(12, 12, 3),
1334 /* 0101 */ V(12, 12, 3),
1335 /* 0110 */ V(10, 14, 4),
1336 /* 0111 */ V(9, 14, 4),
1337 /* 1000 */ V(8, 14, 3),
1338 /* 1001 */ V(8, 14, 3),
1339 /* 1010 */ V(7, 15, 4),
1340 /* 1011 */ V(7, 14, 4),
1341 /* 1100 */ V(15, 7, 2),
1342 /* 1101 */ V(15, 7, 2),
1343 /* 1110 */ V(15, 7, 2),
1344 /* 1111 */ V(15, 7, 2),
1345
1346 /* 0000 0000 0011 ... */
1347 /* 000 */ V(13, 10, 2),/* 310 */
1348 /* 001 */ V(13, 10, 2),
1349 /* 010 */ V(10, 13, 3),
1350 /* 011 */ V(11, 12, 3),
1351 /* 100 */ V(12, 11, 3),
1352 /* 101 */ V(15, 6, 3),
1353 /* 110 */ V(6, 15, 2),
1354 /* 111 */ V(6, 15, 2),
1355
1356 /* 0000 0000 0100 ... */
1357 /* 00 */ V(14, 8, 2),/* 318 */
1358 /* 01 */ V(5, 15, 2),
1359 /* 10 */ V(9, 13, 2),
1360 /* 11 */ V(13, 9, 2),
1361
1362 /* 0000 0000 0101 ... */
1363 /* 00 */ V(15, 5, 2),/* 322 */
1364 /* 01 */ V(14, 7, 2),
1365 /* 10 */ V(10, 12, 2),
1366 /* 11 */ V(11, 11, 2),
1367
1368 /* 0000 0000 0110 ... */
1369 /* 000 */ V(4, 15, 2),/* 326 */
1370 /* 001 */ V(4, 15, 2),
1371 /* 010 */ V(15, 4, 2),
1372 /* 011 */ V(15, 4, 2),
1373 /* 100 */ V(12, 10, 3),
1374 /* 101 */ V(14, 6, 3),
1375 /* 110 */ V(15, 3, 2),
1376 /* 111 */ V(15, 3, 2),
1377
1378 /* 0000 0000 0111 ... */
1379 /* 00 */ V(3, 15, 1),/* 334 */
1380 /* 01 */ V(3, 15, 1),
1381 /* 10 */ V(8, 13, 2),
1382 /* 11 */ V(13, 8, 2),
1383
1384 /* 0000 0000 1000 ... */
1385 /* 0 */ V(2, 15, 1),/* 338 */
1386 /* 1 */ V(15, 2, 1),
1387
1388 /* 0000 0000 1001 ... */
1389 /* 00 */ V(6, 14, 2),/* 340 */
1390 /* 01 */ V(9, 12, 2),
1391 /* 10 */ V(0, 15, 1),
1392 /* 11 */ V(0, 15, 1),
1393
1394 /* 0000 0000 1010 ... */
1395 /* 00 */ V(12, 9, 2),/* 344 */
1396 /* 01 */ V(5, 14, 2),
1397 /* 10 */ V(10, 11, 1),
1398 /* 11 */ V(10, 11, 1),
1399
1400 /* 0000 0000 1011 ... */
1401 /* 00 */ V(7, 13, 2),/* 348 */
1402 /* 01 */ V(13, 7, 2),
1403 /* 10 */ V(4, 14, 1),
1404 /* 11 */ V(4, 14, 1),
1405
1406 /* 0000 0000 1100 ... */
1407 /* 00 */ V(12, 8, 2),/* 352 */
1408 /* 01 */ V(13, 6, 2),
1409 /* 10 */ V(3, 14, 1),
1410 /* 11 */ V(3, 14, 1),
1411
1412 /* 0000 0000 1101 ... */
1413 /* 00 */ V(11, 9, 1),/* 356 */
1414 /* 01 */ V(11, 9, 1),
1415 /* 10 */ V(9, 11, 2),
1416 /* 11 */ V(10, 10, 2),
1417
1418 /* 0000 0001 0001 ... */
1419 /* 0 */ V(11, 10, 1),/* 360 */
1420 /* 1 */ V(14, 5, 1),
1421
1422 /* 0000 0001 0010 ... */
1423 /* 0 */ V(14, 4, 1),/* 362 */
1424 /* 1 */ V(8, 12, 1),
1425
1426 /* 0000 0001 0011 ... */
1427 /* 0 */ V(6, 13, 1),/* 364 */
1428 /* 1 */ V(14, 3, 1),
1429
1430 /* 0000 0001 0101 ... */
1431 /* 0 */ V(2, 14, 1),/* 366 */
1432 /* 1 */ V(0, 14, 1),
1433
1434 /* 0000 0001 1000 ... */
1435 /* 0 */ V(14, 0, 1),/* 368 */
1436 /* 1 */ V(5, 13, 1),
1437
1438 /* 0000 0001 1001 ... */
1439 /* 0 */ V(13, 5, 1),/* 370 */
1440 /* 1 */ V(7, 12, 1),
1441
1442 /* 0000 0001 1010 ... */
1443 /* 0 */ V(12, 7, 1),/* 372 */
1444 /* 1 */ V(4, 13, 1),
1445
1446 /* 0000 0001 1011 ... */
1447 /* 0 */ V(8, 11, 1),/* 374 */
1448 /* 1 */ V(11, 8, 1),
1449
1450 /* 0000 0001 1100 ... */
1451 /* 0 */ V(13, 4, 1),/* 376 */
1452 /* 1 */ V(9, 10, 1),
1453
1454 /* 0000 0001 1101 ... */
1455 /* 0 */ V(10, 9, 1),/* 378 */
1456 /* 1 */ V(6, 12, 1),
1457
1458 /* 0000 0010 0000 ... */
1459 /* 0 */ V(13, 3, 1),/* 380 */
1460 /* 1 */ V(7, 11, 1),
1461
1462 /* 0000 0010 0101 ... */
1463 /* 0 */ V(5, 12, 1),/* 382 */
1464 /* 1 */ V(12, 5, 1),
1465
1466 /* 0000 0010 0110 ... */
1467 /* 0 */ V(9, 9, 1),/* 384 */
1468 /* 1 */ V(7, 10, 1),
1469
1470 /* 0000 0010 1000 ... */
1471 /* 0 */ V(10, 7, 1),/* 386 */
1472 /* 1 */ V(9, 7, 1),
1473
1474 /* 0000 0000 0000 0000 ... */
1475 /* 000 */ V(15, 14, 3),/* 388 */
1476 /* 001 */ V(15, 12, 3),
1477 /* 010 */ V(15, 13, 2),
1478 /* 011 */ V(15, 13, 2),
1479 /* 100 */ V(14, 13, 1),
1480 /* 101 */ V(14, 13, 1),
1481 /* 110 */ V(14, 13, 1),
1482 /* 111 */ V(14, 13, 1),
1483
1484 /* 0000 0000 0000 1011 ... */
1485 /* 0 */ V(10, 15, 1),/* 396 */
1486 /* 1 */ V(14, 9, 1)
1487};
1488
1489static
1490union huffpair const hufftab15[] = {
1491 /* 0000 */ PTR(16, 4),
1492 /* 0001 */ PTR(32, 4),
1493 /* 0010 */ PTR(48, 4),
1494 /* 0011 */ PTR(64, 4),
1495 /* 0100 */ PTR(80, 4),
1496 /* 0101 */ PTR(96, 3),
1497 /* 0110 */ PTR(104, 3),
1498 /* 0111 */ PTR(112, 2),
1499 /* 1000 */ PTR(116, 1),
1500 /* 1001 */ PTR(118, 1),
1501 /* 1010 */ V(1, 1, 3),
1502 /* 1011 */ V(1, 1, 3),
1503 /* 1100 */ V(0, 1, 4),
1504 /* 1101 */ V(1, 0, 4),
1505 /* 1110 */ V(0, 0, 3),
1506 /* 1111 */ V(0, 0, 3),
1507
1508 /* 0000 ... */
1509 /* 0000 */ PTR(120, 4),/* 16 */
1510 /* 0001 */ PTR(136, 4),
1511 /* 0010 */ PTR(152, 4),
1512 /* 0011 */ PTR(168, 4),
1513 /* 0100 */ PTR(184, 4),
1514 /* 0101 */ PTR(200, 3),
1515 /* 0110 */ PTR(208, 3),
1516 /* 0111 */ PTR(216, 4),
1517 /* 1000 */ PTR(232, 3),
1518 /* 1001 */ PTR(240, 3),
1519 /* 1010 */ PTR(248, 3),
1520 /* 1011 */ PTR(256, 3),
1521 /* 1100 */ PTR(264, 2),
1522 /* 1101 */ PTR(268, 3),
1523 /* 1110 */ PTR(276, 3),
1524 /* 1111 */ PTR(284, 2),
1525
1526 /* 0001 ... */
1527 /* 0000 */ PTR(288, 2),/* 32 */
1528 /* 0001 */ PTR(292, 2),
1529 /* 0010 */ PTR(296, 2),
1530 /* 0011 */ PTR(300, 2),
1531 /* 0100 */ PTR(304, 2),
1532 /* 0101 */ PTR(308, 2),
1533 /* 0110 */ PTR(312, 2),
1534 /* 0111 */ PTR(316, 2),
1535 /* 1000 */ PTR(320, 1),
1536 /* 1001 */ PTR(322, 1),
1537 /* 1010 */ PTR(324, 1),
1538 /* 1011 */ PTR(326, 2),
1539 /* 1100 */ PTR(330, 1),
1540 /* 1101 */ PTR(332, 1),
1541 /* 1110 */ PTR(334, 2),
1542 /* 1111 */ PTR(338, 1),
1543
1544 /* 0010 ... */
1545 /* 0000 */ PTR(340, 1),/* 48 */
1546 /* 0001 */ PTR(342, 1),
1547 /* 0010 */ V(9, 1, 4),
1548 /* 0011 */ PTR(344, 1),
1549 /* 0100 */ PTR(346, 1),
1550 /* 0101 */ PTR(348, 1),
1551 /* 0110 */ PTR(350, 1),
1552 /* 0111 */ PTR(352, 1),
1553 /* 1000 */ V(2, 8, 4),
1554 /* 1001 */ V(8, 2, 4),
1555 /* 1010 */ V(1, 8, 4),
1556 /* 1011 */ V(8, 1, 4),
1557 /* 1100 */ PTR(354, 1),
1558 /* 1101 */ PTR(356, 1),
1559 /* 1110 */ PTR(358, 1),
1560 /* 1111 */ PTR(360, 1),
1561
1562 /* 0011 ... */
1563 /* 0000 */ V(2, 7, 4),/* 64 */
1564 /* 0001 */ V(7, 2, 4),
1565 /* 0010 */ V(6, 4, 4),
1566 /* 0011 */ V(1, 7, 4),
1567 /* 0100 */ V(5, 5, 4),
1568 /* 0101 */ V(7, 1, 4),
1569 /* 0110 */ PTR(362, 1),
1570 /* 0111 */ V(3, 6, 4),
1571 /* 1000 */ V(6, 3, 4),
1572 /* 1001 */ V(4, 5, 4),
1573 /* 1010 */ V(5, 4, 4),
1574 /* 1011 */ V(2, 6, 4),
1575 /* 1100 */ V(6, 2, 4),
1576 /* 1101 */ V(1, 6, 4),
1577 /* 1110 */ PTR(364, 1),
1578 /* 1111 */ V(3, 5, 4),
1579
1580 /* 0100 ... */
1581 /* 0000 */ V(6, 1, 3),/* 80 */
1582 /* 0001 */ V(6, 1, 3),
1583 /* 0010 */ V(5, 3, 4),
1584 /* 0011 */ V(4, 4, 4),
1585 /* 0100 */ V(2, 5, 3),
1586 /* 0101 */ V(2, 5, 3),
1587 /* 0110 */ V(5, 2, 3),
1588 /* 0111 */ V(5, 2, 3),
1589 /* 1000 */ V(1, 5, 3),
1590 /* 1001 */ V(1, 5, 3),
1591 /* 1010 */ V(5, 1, 3),
1592 /* 1011 */ V(5, 1, 3),
1593 /* 1100 */ V(0, 5, 4),
1594 /* 1101 */ V(5, 0, 4),
1595 /* 1110 */ V(3, 4, 3),
1596 /* 1111 */ V(3, 4, 3),
1597
1598 /* 0101 ... */
1599 /* 000 */ V(4, 3, 3),/* 96 */
1600 /* 001 */ V(2, 4, 3),
1601 /* 010 */ V(4, 2, 3),
1602 /* 011 */ V(3, 3, 3),
1603 /* 100 */ V(4, 1, 2),
1604 /* 101 */ V(4, 1, 2),
1605 /* 110 */ V(1, 4, 3),
1606 /* 111 */ V(0, 4, 3),
1607
1608 /* 0110 ... */
1609 /* 000 */ V(2, 3, 2),/* 104 */
1610 /* 001 */ V(2, 3, 2),
1611 /* 010 */ V(3, 2, 2),
1612 /* 011 */ V(3, 2, 2),
1613 /* 100 */ V(4, 0, 3),
1614 /* 101 */ V(0, 3, 3),
1615 /* 110 */ V(1, 3, 2),
1616 /* 111 */ V(1, 3, 2),
1617
1618 /* 0111 ... */
1619 /* 00 */ V(3, 1, 2),/* 112 */
1620 /* 01 */ V(3, 0, 2),
1621 /* 10 */ V(2, 2, 1),
1622 /* 11 */ V(2, 2, 1),
1623
1624 /* 1000 ... */
1625 /* 0 */ V(1, 2, 1),/* 116 */
1626 /* 1 */ V(2, 1, 1),
1627
1628 /* 1001 ... */
1629 /* 0 */ V(0, 2, 1),/* 118 */
1630 /* 1 */ V(2, 0, 1),
1631
1632 /* 0000 0000 ... */
1633 /* 0000 */ PTR(366, 1),/* 120 */
1634 /* 0001 */ PTR(368, 1),
1635 /* 0010 */ V(14, 14, 4),
1636 /* 0011 */ PTR(370, 1),
1637 /* 0100 */ PTR(372, 1),
1638 /* 0101 */ PTR(374, 1),
1639 /* 0110 */ V(15, 11, 4),
1640 /* 0111 */ PTR(376, 1),
1641 /* 1000 */ V(13, 13, 4),
1642 /* 1001 */ V(10, 15, 4),
1643 /* 1010 */ V(15, 10, 4),
1644 /* 1011 */ V(11, 14, 4),
1645 /* 1100 */ V(14, 11, 4),
1646 /* 1101 */ V(12, 13, 4),
1647 /* 1110 */ V(13, 12, 4),
1648 /* 1111 */ V(9, 15, 4),
1649
1650 /* 0000 0001 ... */
1651 /* 0000 */ V(15, 9, 4),/* 136 */
1652 /* 0001 */ V(14, 10, 4),
1653 /* 0010 */ V(11, 13, 4),
1654 /* 0011 */ V(13, 11, 4),
1655 /* 0100 */ V(8, 15, 4),
1656 /* 0101 */ V(15, 8, 4),
1657 /* 0110 */ V(12, 12, 4),
1658 /* 0111 */ V(9, 14, 4),
1659 /* 1000 */ V(14, 9, 4),
1660 /* 1001 */ V(7, 15, 4),
1661 /* 1010 */ V(15, 7, 4),
1662 /* 1011 */ V(10, 13, 4),
1663 /* 1100 */ V(13, 10, 4),
1664 /* 1101 */ V(11, 12, 4),
1665 /* 1110 */ V(6, 15, 4),
1666 /* 1111 */ PTR(378, 1),
1667
1668 /* 0000 0010 ... */
1669 /* 0000 */ V(12, 11, 3),/* 152 */
1670 /* 0001 */ V(12, 11, 3),
1671 /* 0010 */ V(15, 6, 3),
1672 /* 0011 */ V(15, 6, 3),
1673 /* 0100 */ V(8, 14, 4),
1674 /* 0101 */ V(14, 8, 4),
1675 /* 0110 */ V(5, 15, 4),
1676 /* 0111 */ V(9, 13, 4),
1677 /* 1000 */ V(15, 5, 3),
1678 /* 1001 */ V(15, 5, 3),
1679 /* 1010 */ V(7, 14, 3),
1680 /* 1011 */ V(7, 14, 3),
1681 /* 1100 */ V(14, 7, 3),
1682 /* 1101 */ V(14, 7, 3),
1683 /* 1110 */ V(10, 12, 3),
1684 /* 1111 */ V(10, 12, 3),
1685
1686 /* 0000 0011 ... */
1687 /* 0000 */ V(12, 10, 3),/* 168 */
1688 /* 0001 */ V(12, 10, 3),
1689 /* 0010 */ V(11, 11, 3),
1690 /* 0011 */ V(11, 11, 3),
1691 /* 0100 */ V(13, 9, 4),
1692 /* 0101 */ V(8, 13, 4),
1693 /* 0110 */ V(4, 15, 3),
1694 /* 0111 */ V(4, 15, 3),
1695 /* 1000 */ V(15, 4, 3),
1696 /* 1001 */ V(15, 4, 3),
1697 /* 1010 */ V(3, 15, 3),
1698 /* 1011 */ V(3, 15, 3),
1699 /* 1100 */ V(15, 3, 3),
1700 /* 1101 */ V(15, 3, 3),
1701 /* 1110 */ V(13, 8, 3),
1702 /* 1111 */ V(13, 8, 3),
1703
1704 /* 0000 0100 ... */
1705 /* 0000 */ V(14, 6, 3),/* 184 */
1706 /* 0001 */ V(14, 6, 3),
1707 /* 0010 */ V(2, 15, 3),
1708 /* 0011 */ V(2, 15, 3),
1709 /* 0100 */ V(15, 2, 3),
1710 /* 0101 */ V(15, 2, 3),
1711 /* 0110 */ V(6, 14, 4),
1712 /* 0111 */ V(15, 0, 4),
1713 /* 1000 */ V(1, 15, 3),
1714 /* 1001 */ V(1, 15, 3),
1715 /* 1010 */ V(15, 1, 3),
1716 /* 1011 */ V(15, 1, 3),
1717 /* 1100 */ V(9, 12, 3),
1718 /* 1101 */ V(9, 12, 3),
1719 /* 1110 */ V(12, 9, 3),
1720 /* 1111 */ V(12, 9, 3),
1721
1722 /* 0000 0101 ... */
1723 /* 000 */ V(5, 14, 3),/* 200 */
1724 /* 001 */ V(10, 11, 3),
1725 /* 010 */ V(11, 10, 3),
1726 /* 011 */ V(14, 5, 3),
1727 /* 100 */ V(7, 13, 3),
1728 /* 101 */ V(13, 7, 3),
1729 /* 110 */ V(4, 14, 3),
1730 /* 111 */ V(14, 4, 3),
1731
1732 /* 0000 0110 ... */
1733 /* 000 */ V(8, 12, 3),/* 208 */
1734 /* 001 */ V(12, 8, 3),
1735 /* 010 */ V(3, 14, 3),
1736 /* 011 */ V(6, 13, 3),
1737 /* 100 */ V(13, 6, 3),
1738 /* 101 */ V(14, 3, 3),
1739 /* 110 */ V(9, 11, 3),
1740 /* 111 */ V(11, 9, 3),
1741
1742 /* 0000 0111 ... */
1743 /* 0000 */ V(2, 14, 3),/* 216 */
1744 /* 0001 */ V(2, 14, 3),
1745 /* 0010 */ V(10, 10, 3),
1746 /* 0011 */ V(10, 10, 3),
1747 /* 0100 */ V(14, 2, 3),
1748 /* 0101 */ V(14, 2, 3),
1749 /* 0110 */ V(1, 14, 3),
1750 /* 0111 */ V(1, 14, 3),
1751 /* 1000 */ V(14, 1, 3),
1752 /* 1001 */ V(14, 1, 3),
1753 /* 1010 */ V(0, 14, 4),
1754 /* 1011 */ V(14, 0, 4),
1755 /* 1100 */ V(5, 13, 3),
1756 /* 1101 */ V(5, 13, 3),
1757 /* 1110 */ V(13, 5, 3),
1758 /* 1111 */ V(13, 5, 3),
1759
1760 /* 0000 1000 ... */
1761 /* 000 */ V(7, 12, 3),/* 232 */
1762 /* 001 */ V(12, 7, 3),
1763 /* 010 */ V(4, 13, 3),
1764 /* 011 */ V(8, 11, 3),
1765 /* 100 */ V(13, 4, 2),
1766 /* 101 */ V(13, 4, 2),
1767 /* 110 */ V(11, 8, 3),
1768 /* 111 */ V(9, 10, 3),
1769
1770 /* 0000 1001 ... */
1771 /* 000 */ V(10, 9, 3),/* 240 */
1772 /* 001 */ V(6, 12, 3),
1773 /* 010 */ V(12, 6, 3),
1774 /* 011 */ V(3, 13, 3),
1775 /* 100 */ V(13, 3, 2),
1776 /* 101 */ V(13, 3, 2),
1777 /* 110 */ V(13, 2, 2),
1778 /* 111 */ V(13, 2, 2),
1779
1780 /* 0000 1010 ... */
1781 /* 000 */ V(2, 13, 3),/* 248 */
1782 /* 001 */ V(0, 13, 3),
1783 /* 010 */ V(1, 13, 2),
1784 /* 011 */ V(1, 13, 2),
1785 /* 100 */ V(7, 11, 2),
1786 /* 101 */ V(7, 11, 2),
1787 /* 110 */ V(11, 7, 2),
1788 /* 111 */ V(11, 7, 2),
1789
1790 /* 0000 1011 ... */
1791 /* 000 */ V(13, 1, 2),/* 256 */
1792 /* 001 */ V(13, 1, 2),
1793 /* 010 */ V(5, 12, 3),
1794 /* 011 */ V(13, 0, 3),
1795 /* 100 */ V(12, 5, 2),
1796 /* 101 */ V(12, 5, 2),
1797 /* 110 */ V(8, 10, 2),
1798 /* 111 */ V(8, 10, 2),
1799
1800 /* 0000 1100 ... */
1801 /* 00 */ V(10, 8, 2),/* 264 */
1802 /* 01 */ V(4, 12, 2),
1803 /* 10 */ V(12, 4, 2),
1804 /* 11 */ V(6, 11, 2),
1805
1806 /* 0000 1101 ... */
1807 /* 000 */ V(11, 6, 2),/* 268 */
1808 /* 001 */ V(11, 6, 2),
1809 /* 010 */ V(9, 9, 3),
1810 /* 011 */ V(0, 12, 3),
1811 /* 100 */ V(3, 12, 2),
1812 /* 101 */ V(3, 12, 2),
1813 /* 110 */ V(12, 3, 2),
1814 /* 111 */ V(12, 3, 2),
1815
1816 /* 0000 1110 ... */
1817 /* 000 */ V(7, 10, 2),/* 276 */
1818 /* 001 */ V(7, 10, 2),
1819 /* 010 */ V(10, 7, 2),
1820 /* 011 */ V(10, 7, 2),
1821 /* 100 */ V(10, 6, 2),
1822 /* 101 */ V(10, 6, 2),
1823 /* 110 */ V(12, 0, 3),
1824 /* 111 */ V(0, 11, 3),
1825
1826 /* 0000 1111 ... */
1827 /* 00 */ V(12, 2, 1),/* 284 */
1828 /* 01 */ V(12, 2, 1),
1829 /* 10 */ V(2, 12, 2),
1830 /* 11 */ V(5, 11, 2),
1831
1832 /* 0001 0000 ... */
1833 /* 00 */ V(11, 5, 2),/* 288 */
1834 /* 01 */ V(1, 12, 2),
1835 /* 10 */ V(8, 9, 2),
1836 /* 11 */ V(9, 8, 2),
1837
1838 /* 0001 0001 ... */
1839 /* 00 */ V(12, 1, 2),/* 292 */
1840 /* 01 */ V(4, 11, 2),
1841 /* 10 */ V(11, 4, 2),
1842 /* 11 */ V(6, 10, 2),
1843
1844 /* 0001 0010 ... */
1845 /* 00 */ V(3, 11, 2),/* 296 */
1846 /* 01 */ V(7, 9, 2),
1847 /* 10 */ V(11, 3, 1),
1848 /* 11 */ V(11, 3, 1),
1849
1850 /* 0001 0011 ... */
1851 /* 00 */ V(9, 7, 2),/* 300 */
1852 /* 01 */ V(8, 8, 2),
1853 /* 10 */ V(2, 11, 2),
1854 /* 11 */ V(5, 10, 2),
1855
1856 /* 0001 0100 ... */
1857 /* 00 */ V(11, 2, 1),/* 304 */
1858 /* 01 */ V(11, 2, 1),
1859 /* 10 */ V(10, 5, 2),
1860 /* 11 */ V(1, 11, 2),
1861
1862 /* 0001 0101 ... */
1863 /* 00 */ V(11, 1, 1),/* 308 */
1864 /* 01 */ V(11, 1, 1),
1865 /* 10 */ V(11, 0, 2),
1866 /* 11 */ V(6, 9, 2),
1867
1868 /* 0001 0110 ... */
1869 /* 00 */ V(9, 6, 2),/* 312 */
1870 /* 01 */ V(4, 10, 2),
1871 /* 10 */ V(10, 4, 2),
1872 /* 11 */ V(7, 8, 2),
1873
1874 /* 0001 0111 ... */
1875 /* 00 */ V(8, 7, 2),/* 316 */
1876 /* 01 */ V(3, 10, 2),
1877 /* 10 */ V(10, 3, 1),
1878 /* 11 */ V(10, 3, 1),
1879
1880 /* 0001 1000 ... */
1881 /* 0 */ V(5, 9, 1),/* 320 */
1882 /* 1 */ V(9, 5, 1),
1883
1884 /* 0001 1001 ... */
1885 /* 0 */ V(2, 10, 1),/* 322 */
1886 /* 1 */ V(10, 2, 1),
1887
1888 /* 0001 1010 ... */
1889 /* 0 */ V(1, 10, 1),/* 324 */
1890 /* 1 */ V(10, 1, 1),
1891
1892 /* 0001 1011 ... */
1893 /* 00 */ V(0, 10, 2),/* 326 */
1894 /* 01 */ V(10, 0, 2),
1895 /* 10 */ V(6, 8, 1),
1896 /* 11 */ V(6, 8, 1),
1897
1898 /* 0001 1100 ... */
1899 /* 0 */ V(8, 6, 1),/* 330 */
1900 /* 1 */ V(4, 9, 1),
1901
1902 /* 0001 1101 ... */
1903 /* 0 */ V(9, 4, 1),/* 332 */
1904 /* 1 */ V(3, 9, 1),
1905
1906 /* 0001 1110 ... */
1907 /* 00 */ V(9, 3, 1),/* 334 */
1908 /* 01 */ V(9, 3, 1),
1909 /* 10 */ V(7, 7, 2),
1910 /* 11 */ V(0, 9, 2),
1911
1912 /* 0001 1111 ... */
1913 /* 0 */ V(5, 8, 1),/* 338 */
1914 /* 1 */ V(8, 5, 1),
1915
1916 /* 0010 0000 ... */
1917 /* 0 */ V(2, 9, 1),/* 340 */
1918 /* 1 */ V(6, 7, 1),
1919
1920 /* 0010 0001 ... */
1921 /* 0 */ V(7, 6, 1),/* 342 */
1922 /* 1 */ V(9, 2, 1),
1923
1924 /* 0010 0011 ... */
1925 /* 0 */ V(1, 9, 1),/* 344 */
1926 /* 1 */ V(9, 0, 1),
1927
1928 /* 0010 0100 ... */
1929 /* 0 */ V(4, 8, 1),/* 346 */
1930 /* 1 */ V(8, 4, 1),
1931
1932 /* 0010 0101 ... */
1933 /* 0 */ V(5, 7, 1),/* 348 */
1934 /* 1 */ V(7, 5, 1),
1935
1936 /* 0010 0110 ... */
1937 /* 0 */ V(3, 8, 1),/* 350 */
1938 /* 1 */ V(8, 3, 1),
1939
1940 /* 0010 0111 ... */
1941 /* 0 */ V(6, 6, 1),/* 352 */
1942 /* 1 */ V(4, 7, 1),
1943
1944 /* 0010 1100 ... */
1945 /* 0 */ V(7, 4, 1),/* 354 */
1946 /* 1 */ V(0, 8, 1),
1947
1948 /* 0010 1101 ... */
1949 /* 0 */ V(8, 0, 1),/* 356 */
1950 /* 1 */ V(5, 6, 1),
1951
1952 /* 0010 1110 ... */
1953 /* 0 */ V(6, 5, 1),/* 358 */
1954 /* 1 */ V(3, 7, 1),
1955
1956 /* 0010 1111 ... */
1957 /* 0 */ V(7, 3, 1),/* 360 */
1958 /* 1 */ V(4, 6, 1),
1959
1960 /* 0011 0110 ... */
1961 /* 0 */ V(0, 7, 1),/* 362 */
1962 /* 1 */ V(7, 0, 1),
1963
1964 /* 0011 1110 ... */
1965 /* 0 */ V(0, 6, 1),/* 364 */
1966 /* 1 */ V(6, 0, 1),
1967
1968 /* 0000 0000 0000 ... */
1969 /* 0 */ V(15, 15, 1),/* 366 */
1970 /* 1 */ V(14, 15, 1),
1971
1972 /* 0000 0000 0001 ... */
1973 /* 0 */ V(15, 14, 1),/* 368 */
1974 /* 1 */ V(13, 15, 1),
1975
1976 /* 0000 0000 0011 ... */
1977 /* 0 */ V(15, 13, 1),/* 370 */
1978 /* 1 */ V(12, 15, 1),
1979
1980 /* 0000 0000 0100 ... */
1981 /* 0 */ V(15, 12, 1),/* 372 */
1982 /* 1 */ V(13, 14, 1),
1983
1984 /* 0000 0000 0101 ... */
1985 /* 0 */ V(14, 13, 1),/* 374 */
1986 /* 1 */ V(11, 15, 1),
1987
1988 /* 0000 0000 0111 ... */
1989 /* 0 */ V(12, 14, 1),/* 376 */
1990 /* 1 */ V(14, 12, 1),
1991
1992 /* 0000 0001 1111 ... */
1993 /* 0 */ V(10, 14, 1),/* 378 */
1994 /* 1 */ V(0, 15, 1)
1995};
1996
1997static
1998union huffpair const hufftab16[] = {
1999 /* 0000 */ PTR(16, 4),
2000 /* 0001 */ PTR(32, 4),
2001 /* 0010 */ PTR(48, 4),
2002 /* 0011 */ PTR(64, 2),
2003 /* 0100 */ V(1, 1, 4),
2004 /* 0101 */ V(0, 1, 4),
2005 /* 0110 */ V(1, 0, 3),
2006 /* 0111 */ V(1, 0, 3),
2007 /* 1000 */ V(0, 0, 1),
2008 /* 1001 */ V(0, 0, 1),
2009 /* 1010 */ V(0, 0, 1),
2010 /* 1011 */ V(0, 0, 1),
2011 /* 1100 */ V(0, 0, 1),
2012 /* 1101 */ V(0, 0, 1),
2013 /* 1110 */ V(0, 0, 1),
2014 /* 1111 */ V(0, 0, 1),
2015
2016 /* 0000 ... */
2017 /* 0000 */ PTR(68, 3),/* 16 */
2018 /* 0001 */ PTR(76, 3),
2019 /* 0010 */ PTR(84, 2),
2020 /* 0011 */ V(15, 15, 4),
2021 /* 0100 */ PTR(88, 2),
2022 /* 0101 */ PTR(92, 1),
2023 /* 0110 */ PTR(94, 4),
2024 /* 0111 */ V(15, 2, 4),
2025 /* 1000 */ PTR(110, 1),
2026 /* 1001 */ V(1, 15, 4),
2027 /* 1010 */ V(15, 1, 4),
2028 /* 1011 */ PTR(112, 4),
2029 /* 1100 */ PTR(128, 4),
2030 /* 1101 */ PTR(144, 4),
2031 /* 1110 */ PTR(160, 4),
2032 /* 1111 */ PTR(176, 4),
2033
2034 /* 0001 ... */
2035 /* 0000 */ PTR(192, 4),/* 32 */
2036 /* 0001 */ PTR(208, 3),
2037 /* 0010 */ PTR(216, 3),
2038 /* 0011 */ PTR(224, 3),
2039 /* 0100 */ PTR(232, 3),
2040 /* 0101 */ PTR(240, 3),
2041 /* 0110 */ PTR(248, 3),
2042 /* 0111 */ PTR(256, 3),
2043 /* 1000 */ PTR(264, 2),
2044 /* 1001 */ PTR(268, 2),
2045 /* 1010 */ PTR(272, 1),
2046 /* 1011 */ PTR(274, 2),
2047 /* 1100 */ PTR(278, 2),
2048 /* 1101 */ PTR(282, 1),
2049 /* 1110 */ V(5, 1, 4),
2050 /* 1111 */ PTR(284, 1),
2051
2052 /* 0010 ... */
2053 /* 0000 */ PTR(286, 1),/* 48 */
2054 /* 0001 */ PTR(288, 1),
2055 /* 0010 */ PTR(290, 1),
2056 /* 0011 */ V(1, 4, 4),
2057 /* 0100 */ V(4, 1, 4),
2058 /* 0101 */ PTR(292, 1),
2059 /* 0110 */ V(2, 3, 4),
2060 /* 0111 */ V(3, 2, 4),
2061 /* 1000 */ V(1, 3, 3),
2062 /* 1001 */ V(1, 3, 3),
2063 /* 1010 */ V(3, 1, 3),
2064 /* 1011 */ V(3, 1, 3),
2065 /* 1100 */ V(0, 3, 4),
2066 /* 1101 */ V(3, 0, 4),
2067 /* 1110 */ V(2, 2, 3),
2068 /* 1111 */ V(2, 2, 3),
2069
2070 /* 0011 ... */
2071 /* 00 */ V(1, 2, 2),/* 64 */
2072 /* 01 */ V(2, 1, 2),
2073 /* 10 */ V(0, 2, 2),
2074 /* 11 */ V(2, 0, 2),
2075
2076 /* 0000 0000 ... */
2077 /* 000 */ V(14, 15, 3),/* 68 */
2078 /* 001 */ V(15, 14, 3),
2079 /* 010 */ V(13, 15, 3),
2080 /* 011 */ V(15, 13, 3),
2081 /* 100 */ V(12, 15, 3),
2082 /* 101 */ V(15, 12, 3),
2083 /* 110 */ V(11, 15, 3),
2084 /* 111 */ V(15, 11, 3),
2085
2086 /* 0000 0001 ... */
2087 /* 000 */ V(10, 15, 2),/* 76 */
2088 /* 001 */ V(10, 15, 2),
2089 /* 010 */ V(15, 10, 3),
2090 /* 011 */ V(9, 15, 3),
2091 /* 100 */ V(15, 9, 3),
2092 /* 101 */ V(15, 8, 3),
2093 /* 110 */ V(8, 15, 2),
2094 /* 111 */ V(8, 15, 2),
2095
2096 /* 0000 0010 ... */
2097 /* 00 */ V(7, 15, 2),/* 84 */
2098 /* 01 */ V(15, 7, 2),
2099 /* 10 */ V(6, 15, 2),
2100 /* 11 */ V(15, 6, 2),
2101
2102 /* 0000 0100 ... */
2103 /* 00 */ V(5, 15, 2),/* 88 */
2104 /* 01 */ V(15, 5, 2),
2105 /* 10 */ V(4, 15, 1),
2106 /* 11 */ V(4, 15, 1),
2107
2108 /* 0000 0101 ... */
2109 /* 0 */ V(15, 4, 1),/* 92 */
2110 /* 1 */ V(15, 3, 1),
2111
2112 /* 0000 0110 ... */
2113 /* 0000 */ V(15, 0, 1),/* 94 */
2114 /* 0001 */ V(15, 0, 1),
2115 /* 0010 */ V(15, 0, 1),
2116 /* 0011 */ V(15, 0, 1),
2117 /* 0100 */ V(15, 0, 1),
2118 /* 0101 */ V(15, 0, 1),
2119 /* 0110 */ V(15, 0, 1),
2120 /* 0111 */ V(15, 0, 1),
2121 /* 1000 */ V(3, 15, 2),
2122 /* 1001 */ V(3, 15, 2),
2123 /* 1010 */ V(3, 15, 2),
2124 /* 1011 */ V(3, 15, 2),
2125 /* 1100 */ PTR(294, 4),
2126 /* 1101 */ PTR(310, 3),
2127 /* 1110 */ PTR(318, 3),
2128 /* 1111 */ PTR(326, 3),
2129
2130 /* 0000 1000 ... */
2131 /* 0 */ V(2, 15, 1),/* 110 */
2132 /* 1 */ V(0, 15, 1),
2133
2134 /* 0000 1011 ... */
2135 /* 0000 */ PTR(334, 2),/* 112 */
2136 /* 0001 */ PTR(338, 2),
2137 /* 0010 */ PTR(342, 2),
2138 /* 0011 */ PTR(346, 1),
2139 /* 0100 */ PTR(348, 2),
2140 /* 0101 */ PTR(352, 2),
2141 /* 0110 */ PTR(356, 1),
2142 /* 0111 */ PTR(358, 2),
2143 /* 1000 */ PTR(362, 2),
2144 /* 1001 */ PTR(366, 2),
2145 /* 1010 */ PTR(370, 2),
2146 /* 1011 */ V(14, 3, 4),
2147 /* 1100 */ PTR(374, 1),
2148 /* 1101 */ PTR(376, 1),
2149 /* 1110 */ PTR(378, 1),
2150 /* 1111 */ PTR(380, 1),
2151
2152 /* 0000 1100 ... */
2153 /* 0000 */ PTR(382, 1),/* 128 */
2154 /* 0001 */ PTR(384, 1),
2155 /* 0010 */ PTR(386, 1),
2156 /* 0011 */ V(0, 13, 4),
2157 /* 0100 */ PTR(388, 1),
2158 /* 0101 */ PTR(390, 1),
2159 /* 0110 */ PTR(392, 1),
2160 /* 0111 */ V(3, 12, 4),
2161 /* 1000 */ PTR(394, 1),
2162 /* 1001 */ V(1, 12, 4),
2163 /* 1010 */ V(12, 0, 4),
2164 /* 1011 */ PTR(396, 1),
2165 /* 1100 */ V(14, 2, 3),
2166 /* 1101 */ V(14, 2, 3),
2167 /* 1110 */ V(2, 14, 4),
2168 /* 1111 */ V(1, 14, 4),
2169
2170 /* 0000 1101 ... */
2171 /* 0000 */ V(13, 3, 4),/* 144 */
2172 /* 0001 */ V(2, 13, 4),
2173 /* 0010 */ V(13, 2, 4),
2174 /* 0011 */ V(13, 1, 4),
2175 /* 0100 */ V(3, 11, 4),
2176 /* 0101 */ PTR(398, 1),
2177 /* 0110 */ V(1, 13, 3),
2178 /* 0111 */ V(1, 13, 3),
2179 /* 1000 */ V(12, 4, 4),
2180 /* 1001 */ V(6, 11, 4),
2181 /* 1010 */ V(12, 3, 4),
2182 /* 1011 */ V(10, 7, 4),
2183 /* 1100 */ V(2, 12, 3),
2184 /* 1101 */ V(2, 12, 3),
2185 /* 1110 */ V(12, 2, 4),
2186 /* 1111 */ V(11, 5, 4),
2187
2188 /* 0000 1110 ... */
2189 /* 0000 */ V(12, 1, 4),/* 160 */
2190 /* 0001 */ V(0, 12, 4),
2191 /* 0010 */ V(4, 11, 4),
2192 /* 0011 */ V(11, 4, 4),
2193 /* 0100 */ V(6, 10, 4),
2194 /* 0101 */ V(10, 6, 4),
2195 /* 0110 */ V(11, 3, 3),
2196 /* 0111 */ V(11, 3, 3),
2197 /* 1000 */ V(5, 10, 4),
2198 /* 1001 */ V(10, 5, 4),
2199 /* 1010 */ V(2, 11, 3),
2200 /* 1011 */ V(2, 11, 3),
2201 /* 1100 */ V(11, 2, 3),
2202 /* 1101 */ V(11, 2, 3),
2203 /* 1110 */ V(1, 11, 3),
2204 /* 1111 */ V(1, 11, 3),
2205
2206 /* 0000 1111 ... */
2207 /* 0000 */ V(11, 1, 3),/* 176 */
2208 /* 0001 */ V(11, 1, 3),
2209 /* 0010 */ V(0, 11, 4),
2210 /* 0011 */ V(11, 0, 4),
2211 /* 0100 */ V(6, 9, 4),
2212 /* 0101 */ V(9, 6, 4),
2213 /* 0110 */ V(4, 10, 4),
2214 /* 0111 */ V(10, 4, 4),
2215 /* 1000 */ V(7, 8, 4),
2216 /* 1001 */ V(8, 7, 4),
2217 /* 1010 */ V(10, 3, 3),
2218 /* 1011 */ V(10, 3, 3),
2219 /* 1100 */ V(3, 10, 4),
2220 /* 1101 */ V(5, 9, 4),
2221 /* 1110 */ V(2, 10, 3),
2222 /* 1111 */ V(2, 10, 3),
2223
2224 /* 0001 0000 ... */
2225 /* 0000 */ V(9, 5, 4),/* 192 */
2226 /* 0001 */ V(6, 8, 4),
2227 /* 0010 */ V(10, 1, 3),
2228 /* 0011 */ V(10, 1, 3),
2229 /* 0100 */ V(8, 6, 4),
2230 /* 0101 */ V(7, 7, 4),
2231 /* 0110 */ V(9, 4, 3),
2232 /* 0111 */ V(9, 4, 3),
2233 /* 1000 */ V(4, 9, 4),
2234 /* 1001 */ V(5, 7, 4),
2235 /* 1010 */ V(6, 7, 3),
2236 /* 1011 */ V(6, 7, 3),
2237 /* 1100 */ V(10, 2, 2),
2238 /* 1101 */ V(10, 2, 2),
2239 /* 1110 */ V(10, 2, 2),
2240 /* 1111 */ V(10, 2, 2),
2241
2242 /* 0001 0001 ... */
2243 /* 000 */ V(1, 10, 2),/* 208 */
2244 /* 001 */ V(1, 10, 2),
2245 /* 010 */ V(0, 10, 3),
2246 /* 011 */ V(10, 0, 3),
2247 /* 100 */ V(3, 9, 3),
2248 /* 101 */ V(9, 3, 3),
2249 /* 110 */ V(5, 8, 3),
2250 /* 111 */ V(8, 5, 3),
2251
2252 /* 0001 0010 ... */
2253 /* 000 */ V(2, 9, 2),/* 216 */
2254 /* 001 */ V(2, 9, 2),
2255 /* 010 */ V(9, 2, 2),
2256 /* 011 */ V(9, 2, 2),
2257 /* 100 */ V(7, 6, 3),
2258 /* 101 */ V(0, 9, 3),
2259 /* 110 */ V(1, 9, 2),
2260 /* 111 */ V(1, 9, 2),
2261
2262 /* 0001 0011 ... */
2263 /* 000 */ V(9, 1, 2),/* 224 */
2264 /* 001 */ V(9, 1, 2),
2265 /* 010 */ V(9, 0, 3),
2266 /* 011 */ V(4, 8, 3),
2267 /* 100 */ V(8, 4, 3),
2268 /* 101 */ V(7, 5, 3),
2269 /* 110 */ V(3, 8, 3),
2270 /* 111 */ V(8, 3, 3),
2271
2272 /* 0001 0100 ... */
2273 /* 000 */ V(6, 6, 3),/* 232 */
2274 /* 001 */ V(2, 8, 3),
2275 /* 010 */ V(8, 2, 2),
2276 /* 011 */ V(8, 2, 2),
2277 /* 100 */ V(4, 7, 3),
2278 /* 101 */ V(7, 4, 3),
2279 /* 110 */ V(1, 8, 2),
2280 /* 111 */ V(1, 8, 2),
2281
2282 /* 0001 0101 ... */
2283 /* 000 */ V(8, 1, 2),/* 240 */
2284 /* 001 */ V(8, 1, 2),
2285 /* 010 */ V(8, 0, 2),
2286 /* 011 */ V(8, 0, 2),
2287 /* 100 */ V(0, 8, 3),
2288 /* 101 */ V(5, 6, 3),
2289 /* 110 */ V(3, 7, 2),
2290 /* 111 */ V(3, 7, 2),
2291
2292 /* 0001 0110 ... */
2293 /* 000 */ V(7, 3, 2),/* 248 */
2294 /* 001 */ V(7, 3, 2),
2295 /* 010 */ V(6, 5, 3),
2296 /* 011 */ V(4, 6, 3),
2297 /* 100 */ V(2, 7, 2),
2298 /* 101 */ V(2, 7, 2),
2299 /* 110 */ V(7, 2, 2),
2300 /* 111 */ V(7, 2, 2),
2301
2302 /* 0001 0111 ... */
2303 /* 000 */ V(6, 4, 3),/* 256 */
2304 /* 001 */ V(5, 5, 3),
2305 /* 010 */ V(0, 7, 2),
2306 /* 011 */ V(0, 7, 2),
2307 /* 100 */ V(1, 7, 1),
2308 /* 101 */ V(1, 7, 1),
2309 /* 110 */ V(1, 7, 1),
2310 /* 111 */ V(1, 7, 1),
2311
2312 /* 0001 1000 ... */
2313 /* 00 */ V(7, 1, 1),/* 264 */
2314 /* 01 */ V(7, 1, 1),
2315 /* 10 */ V(7, 0, 2),
2316 /* 11 */ V(3, 6, 2),
2317
2318 /* 0001 1001 ... */
2319 /* 00 */ V(6, 3, 2),/* 268 */
2320 /* 01 */ V(4, 5, 2),
2321 /* 10 */ V(5, 4, 2),
2322 /* 11 */ V(2, 6, 2),
2323
2324 /* 0001 1010 ... */
2325 /* 0 */ V(6, 2, 1),/* 272 */
2326 /* 1 */ V(1, 6, 1),
2327
2328 /* 0001 1011 ... */
2329 /* 00 */ V(6, 1, 1),/* 274 */
2330 /* 01 */ V(6, 1, 1),
2331 /* 10 */ V(0, 6, 2),
2332 /* 11 */ V(6, 0, 2),
2333
2334 /* 0001 1100 ... */
2335 /* 00 */ V(5, 3, 1),/* 278 */
2336 /* 01 */ V(5, 3, 1),
2337 /* 10 */ V(3, 5, 2),
2338 /* 11 */ V(4, 4, 2),
2339
2340 /* 0001 1101 ... */
2341 /* 0 */ V(2, 5, 1),/* 282 */
2342 /* 1 */ V(5, 2, 1),
2343
2344 /* 0001 1111 ... */
2345 /* 0 */ V(1, 5, 1),/* 284 */
2346 /* 1 */ V(0, 5, 1),
2347
2348 /* 0010 0000 ... */
2349 /* 0 */ V(3, 4, 1),/* 286 */
2350 /* 1 */ V(4, 3, 1),
2351
2352 /* 0010 0001 ... */
2353 /* 0 */ V(5, 0, 1),/* 288 */
2354 /* 1 */ V(2, 4, 1),
2355
2356 /* 0010 0010 ... */
2357 /* 0 */ V(4, 2, 1),/* 290 */
2358 /* 1 */ V(3, 3, 1),
2359
2360 /* 0010 0101 ... */
2361 /* 0 */ V(0, 4, 1),/* 292 */
2362 /* 1 */ V(4, 0, 1),
2363
2364 /* 0000 0110 1100 ... */
2365 /* 0000 */ V(12, 14, 4),/* 294 */
2366 /* 0001 */ PTR(400, 1),
2367 /* 0010 */ V(13, 14, 3),
2368 /* 0011 */ V(13, 14, 3),
2369 /* 0100 */ V(14, 9, 3),
2370 /* 0101 */ V(14, 9, 3),
2371 /* 0110 */ V(14, 10, 4),
2372 /* 0111 */ V(13, 9, 4),
2373 /* 1000 */ V(14, 14, 2),
2374 /* 1001 */ V(14, 14, 2),
2375 /* 1010 */ V(14, 14, 2),
2376 /* 1011 */ V(14, 14, 2),
2377 /* 1100 */ V(14, 13, 3),
2378 /* 1101 */ V(14, 13, 3),
2379 /* 1110 */ V(14, 11, 3),
2380 /* 1111 */ V(14, 11, 3),
2381
2382 /* 0000 0110 1101 ... */
2383 /* 000 */ V(11, 14, 2),/* 310 */
2384 /* 001 */ V(11, 14, 2),
2385 /* 010 */ V(12, 13, 2),
2386 /* 011 */ V(12, 13, 2),
2387 /* 100 */ V(13, 12, 3),
2388 /* 101 */ V(13, 11, 3),
2389 /* 110 */ V(10, 14, 2),
2390 /* 111 */ V(10, 14, 2),
2391
2392 /* 0000 0110 1110 ... */
2393 /* 000 */ V(12, 12, 2),/* 318 */
2394 /* 001 */ V(12, 12, 2),
2395 /* 010 */ V(10, 13, 3),
2396 /* 011 */ V(13, 10, 3),
2397 /* 100 */ V(7, 14, 3),
2398 /* 101 */ V(10, 12, 3),
2399 /* 110 */ V(12, 10, 2),
2400 /* 111 */ V(12, 10, 2),
2401
2402 /* 0000 0110 1111 ... */
2403 /* 000 */ V(12, 9, 3),/* 326 */
2404 /* 001 */ V(7, 13, 3),
2405 /* 010 */ V(5, 14, 2),
2406 /* 011 */ V(5, 14, 2),
2407 /* 100 */ V(11, 13, 1),
2408 /* 101 */ V(11, 13, 1),
2409 /* 110 */ V(11, 13, 1),
2410 /* 111 */ V(11, 13, 1),
2411
2412 /* 0000 1011 0000 ... */
2413 /* 00 */ V(9, 14, 1),/* 334 */
2414 /* 01 */ V(9, 14, 1),
2415 /* 10 */ V(11, 12, 2),
2416 /* 11 */ V(12, 11, 2),
2417
2418 /* 0000 1011 0001 ... */
2419 /* 00 */ V(8, 14, 2),/* 338 */
2420 /* 01 */ V(14, 8, 2),
2421 /* 10 */ V(9, 13, 2),
2422 /* 11 */ V(14, 7, 2),
2423
2424 /* 0000 1011 0010 ... */
2425 /* 00 */ V(11, 11, 2),/* 342 */
2426 /* 01 */ V(8, 13, 2),
2427 /* 10 */ V(13, 8, 2),
2428 /* 11 */ V(6, 14, 2),
2429
2430 /* 0000 1011 0011 ... */
2431 /* 0 */ V(14, 6, 1),/* 346 */
2432 /* 1 */ V(9, 12, 1),
2433
2434 /* 0000 1011 0100 ... */
2435 /* 00 */ V(10, 11, 2),/* 348 */
2436 /* 01 */ V(11, 10, 2),
2437 /* 10 */ V(14, 5, 2),
2438 /* 11 */ V(13, 7, 2),
2439
2440 /* 0000 1011 0101 ... */
2441 /* 00 */ V(4, 14, 1),/* 352 */
2442 /* 01 */ V(4, 14, 1),
2443 /* 10 */ V(14, 4, 2),
2444 /* 11 */ V(8, 12, 2),
2445
2446 /* 0000 1011 0110 ... */
2447 /* 0 */ V(12, 8, 1),/* 356 */
2448 /* 1 */ V(3, 14, 1),
2449
2450 /* 0000 1011 0111 ... */
2451 /* 00 */ V(6, 13, 1),/* 358 */
2452 /* 01 */ V(6, 13, 1),
2453 /* 10 */ V(13, 6, 2),
2454 /* 11 */ V(9, 11, 2),
2455
2456 /* 0000 1011 1000 ... */
2457 /* 00 */ V(11, 9, 2),/* 362 */
2458 /* 01 */ V(10, 10, 2),
2459 /* 10 */ V(14, 1, 1),
2460 /* 11 */ V(14, 1, 1),
2461
2462 /* 0000 1011 1001 ... */
2463 /* 00 */ V(13, 4, 1),/* 366 */
2464 /* 01 */ V(13, 4, 1),
2465 /* 10 */ V(11, 8, 2),
2466 /* 11 */ V(10, 9, 2),
2467
2468 /* 0000 1011 1010 ... */
2469 /* 00 */ V(7, 11, 1),/* 370 */
2470 /* 01 */ V(7, 11, 1),
2471 /* 10 */ V(11, 7, 2),
2472 /* 11 */ V(13, 0, 2),
2473
2474 /* 0000 1011 1100 ... */
2475 /* 0 */ V(0, 14, 1),/* 374 */
2476 /* 1 */ V(14, 0, 1),
2477
2478 /* 0000 1011 1101 ... */
2479 /* 0 */ V(5, 13, 1),/* 376 */
2480 /* 1 */ V(13, 5, 1),
2481
2482 /* 0000 1011 1110 ... */
2483 /* 0 */ V(7, 12, 1),/* 378 */
2484 /* 1 */ V(12, 7, 1),
2485
2486 /* 0000 1011 1111 ... */
2487 /* 0 */ V(4, 13, 1),/* 380 */
2488 /* 1 */ V(8, 11, 1),
2489
2490 /* 0000 1100 0000 ... */
2491 /* 0 */ V(9, 10, 1),/* 382 */
2492 /* 1 */ V(6, 12, 1),
2493
2494 /* 0000 1100 0001 ... */
2495 /* 0 */ V(12, 6, 1),/* 384 */
2496 /* 1 */ V(3, 13, 1),
2497
2498 /* 0000 1100 0010 ... */
2499 /* 0 */ V(5, 12, 1),/* 386 */
2500 /* 1 */ V(12, 5, 1),
2501
2502 /* 0000 1100 0100 ... */
2503 /* 0 */ V(8, 10, 1),/* 388 */
2504 /* 1 */ V(10, 8, 1),
2505
2506 /* 0000 1100 0101 ... */
2507 /* 0 */ V(9, 9, 1),/* 390 */
2508 /* 1 */ V(4, 12, 1),
2509
2510 /* 0000 1100 0110 ... */
2511 /* 0 */ V(11, 6, 1),/* 392 */
2512 /* 1 */ V(7, 10, 1),
2513
2514 /* 0000 1100 1000 ... */
2515 /* 0 */ V(5, 11, 1),/* 394 */
2516 /* 1 */ V(8, 9, 1),
2517
2518 /* 0000 1100 1011 ... */
2519 /* 0 */ V(9, 8, 1),/* 396 */
2520 /* 1 */ V(7, 9, 1),
2521
2522 /* 0000 1101 0101 ... */
2523 /* 0 */ V(9, 7, 1),/* 398 */
2524 /* 1 */ V(8, 8, 1),
2525
2526 /* 0000 0110 1100 0001 ... */
2527 /* 0 */ V(14, 12, 1),/* 400 */
2528 /* 1 */ V(13, 13, 1)
2529};
2530
2531static
2532union huffpair const hufftab24[] = {
2533 /* 0000 */ PTR(16, 4),
2534 /* 0001 */ PTR(32, 4),
2535 /* 0010 */ PTR(48, 4),
2536 /* 0011 */ V(15, 15, 4),
2537 /* 0100 */ PTR(64, 4),
2538 /* 0101 */ PTR(80, 4),
2539 /* 0110 */ PTR(96, 4),
2540 /* 0111 */ PTR(112, 4),
2541 /* 1000 */ PTR(128, 4),
2542 /* 1001 */ PTR(144, 4),
2543 /* 1010 */ PTR(160, 3),
2544 /* 1011 */ PTR(168, 2),
2545 /* 1100 */ V(1, 1, 4),
2546 /* 1101 */ V(0, 1, 4),
2547 /* 1110 */ V(1, 0, 4),
2548 /* 1111 */ V(0, 0, 4),
2549
2550 /* 0000 ... */
2551 /* 0000 */ V(14, 15, 4),/* 16 */
2552 /* 0001 */ V(15, 14, 4),
2553 /* 0010 */ V(13, 15, 4),
2554 /* 0011 */ V(15, 13, 4),
2555 /* 0100 */ V(12, 15, 4),
2556 /* 0101 */ V(15, 12, 4),
2557 /* 0110 */ V(11, 15, 4),
2558 /* 0111 */ V(15, 11, 4),
2559 /* 1000 */ V(15, 10, 3),
2560 /* 1001 */ V(15, 10, 3),
2561 /* 1010 */ V(10, 15, 4),
2562 /* 1011 */ V(9, 15, 4),
2563 /* 1100 */ V(15, 9, 3),
2564 /* 1101 */ V(15, 9, 3),
2565 /* 1110 */ V(15, 8, 3),
2566 /* 1111 */ V(15, 8, 3),
2567
2568 /* 0001 ... */
2569 /* 0000 */ V(8, 15, 4),/* 32 */
2570 /* 0001 */ V(7, 15, 4),
2571 /* 0010 */ V(15, 7, 3),
2572 /* 0011 */ V(15, 7, 3),
2573 /* 0100 */ V(6, 15, 3),
2574 /* 0101 */ V(6, 15, 3),
2575 /* 0110 */ V(15, 6, 3),
2576 /* 0111 */ V(15, 6, 3),
2577 /* 1000 */ V(5, 15, 3),
2578 /* 1001 */ V(5, 15, 3),
2579 /* 1010 */ V(15, 5, 3),
2580 /* 1011 */ V(15, 5, 3),
2581 /* 1100 */ V(4, 15, 3),
2582 /* 1101 */ V(4, 15, 3),
2583 /* 1110 */ V(15, 4, 3),
2584 /* 1111 */ V(15, 4, 3),
2585
2586 /* 0010 ... */
2587 /* 0000 */ V(3, 15, 3),/* 48 */
2588 /* 0001 */ V(3, 15, 3),
2589 /* 0010 */ V(15, 3, 3),
2590 /* 0011 */ V(15, 3, 3),
2591 /* 0100 */ V(2, 15, 3),
2592 /* 0101 */ V(2, 15, 3),
2593 /* 0110 */ V(15, 2, 3),
2594 /* 0111 */ V(15, 2, 3),
2595 /* 1000 */ V(15, 1, 3),
2596 /* 1001 */ V(15, 1, 3),
2597 /* 1010 */ V(1, 15, 4),
2598 /* 1011 */ V(15, 0, 4),
2599 /* 1100 */ PTR(172, 3),
2600 /* 1101 */ PTR(180, 3),
2601 /* 1110 */ PTR(188, 3),
2602 /* 1111 */ PTR(196, 3),
2603
2604 /* 0100 ... */
2605 /* 0000 */ PTR(204, 4),/* 64 */
2606 /* 0001 */ PTR(220, 3),
2607 /* 0010 */ PTR(228, 3),
2608 /* 0011 */ PTR(236, 3),
2609 /* 0100 */ PTR(244, 2),
2610 /* 0101 */ PTR(248, 2),
2611 /* 0110 */ PTR(252, 2),
2612 /* 0111 */ PTR(256, 2),
2613 /* 1000 */ PTR(260, 2),
2614 /* 1001 */ PTR(264, 2),
2615 /* 1010 */ PTR(268, 2),
2616 /* 1011 */ PTR(272, 2),
2617 /* 1100 */ PTR(276, 2),
2618 /* 1101 */ PTR(280, 3),
2619 /* 1110 */ PTR(288, 2),
2620 /* 1111 */ PTR(292, 2),
2621
2622 /* 0101 ... */
2623 /* 0000 */ PTR(296, 2),/* 80 */
2624 /* 0001 */ PTR(300, 3),
2625 /* 0010 */ PTR(308, 2),
2626 /* 0011 */ PTR(312, 3),
2627 /* 0100 */ PTR(320, 1),
2628 /* 0101 */ PTR(322, 2),
2629 /* 0110 */ PTR(326, 2),
2630 /* 0111 */ PTR(330, 1),
2631 /* 1000 */ PTR(332, 2),
2632 /* 1001 */ PTR(336, 1),
2633 /* 1010 */ PTR(338, 1),
2634 /* 1011 */ PTR(340, 1),
2635 /* 1100 */ PTR(342, 1),
2636 /* 1101 */ PTR(344, 1),
2637 /* 1110 */ PTR(346, 1),
2638 /* 1111 */ PTR(348, 1),
2639
2640 /* 0110 ... */
2641 /* 0000 */ PTR(350, 1),/* 96 */
2642 /* 0001 */ PTR(352, 1),
2643 /* 0010 */ PTR(354, 1),
2644 /* 0011 */ PTR(356, 1),
2645 /* 0100 */ PTR(358, 1),
2646 /* 0101 */ PTR(360, 1),
2647 /* 0110 */ PTR(362, 1),
2648 /* 0111 */ PTR(364, 1),
2649 /* 1000 */ PTR(366, 1),
2650 /* 1001 */ PTR(368, 1),
2651 /* 1010 */ PTR(370, 2),
2652 /* 1011 */ PTR(374, 1),
2653 /* 1100 */ PTR(376, 2),
2654 /* 1101 */ V(7, 3, 4),
2655 /* 1110 */ PTR(380, 1),
2656 /* 1111 */ V(7, 2, 4),
2657
2658 /* 0111 ... */
2659 /* 0000 */ V(4, 6, 4),/* 112 */
2660 /* 0001 */ V(6, 4, 4),
2661 /* 0010 */ V(5, 5, 4),
2662 /* 0011 */ V(7, 1, 4),
2663 /* 0100 */ V(3, 6, 4),
2664 /* 0101 */ V(6, 3, 4),
2665 /* 0110 */ V(4, 5, 4),
2666 /* 0111 */ V(5, 4, 4),
2667 /* 1000 */ V(2, 6, 4),
2668 /* 1001 */ V(6, 2, 4),
2669 /* 1010 */ V(1, 6, 4),
2670 /* 1011 */ V(6, 1, 4),
2671 /* 1100 */ PTR(382, 1),
2672 /* 1101 */ V(3, 5, 4),
2673 /* 1110 */ V(5, 3, 4),
2674 /* 1111 */ V(4, 4, 4),
2675
2676 /* 1000 ... */
2677 /* 0000 */ V(2, 5, 4),/* 128 */
2678 /* 0001 */ V(5, 2, 4),
2679 /* 0010 */ V(1, 5, 4),
2680 /* 0011 */ PTR(384, 1),
2681 /* 0100 */ V(5, 1, 3),
2682 /* 0101 */ V(5, 1, 3),
2683 /* 0110 */ V(3, 4, 4),
2684 /* 0111 */ V(4, 3, 4),
2685 /* 1000 */ V(2, 4, 3),
2686 /* 1001 */ V(2, 4, 3),
2687 /* 1010 */ V(4, 2, 3),
2688 /* 1011 */ V(4, 2, 3),
2689 /* 1100 */ V(3, 3, 3),
2690 /* 1101 */ V(3, 3, 3),
2691 /* 1110 */ V(1, 4, 3),
2692 /* 1111 */ V(1, 4, 3),
2693
2694 /* 1001 ... */
2695 /* 0000 */ V(4, 1, 3),/* 144 */
2696 /* 0001 */ V(4, 1, 3),
2697 /* 0010 */ V(0, 4, 4),
2698 /* 0011 */ V(4, 0, 4),
2699 /* 0100 */ V(2, 3, 3),
2700 /* 0101 */ V(2, 3, 3),
2701 /* 0110 */ V(3, 2, 3),
2702 /* 0111 */ V(3, 2, 3),
2703 /* 1000 */ V(1, 3, 2),
2704 /* 1001 */ V(1, 3, 2),
2705 /* 1010 */ V(1, 3, 2),
2706 /* 1011 */ V(1, 3, 2),
2707 /* 1100 */ V(3, 1, 2),
2708 /* 1101 */ V(3, 1, 2),
2709 /* 1110 */ V(3, 1, 2),
2710 /* 1111 */ V(3, 1, 2),
2711
2712 /* 1010 ... */
2713 /* 000 */ V(0, 3, 3),/* 160 */
2714 /* 001 */ V(3, 0, 3),
2715 /* 010 */ V(2, 2, 2),
2716 /* 011 */ V(2, 2, 2),
2717 /* 100 */ V(1, 2, 1),
2718 /* 101 */ V(1, 2, 1),
2719 /* 110 */ V(1, 2, 1),
2720 /* 111 */ V(1, 2, 1),
2721
2722 /* 1011 ... */
2723 /* 00 */ V(2, 1, 1),/* 168 */
2724 /* 01 */ V(2, 1, 1),
2725 /* 10 */ V(0, 2, 2),
2726 /* 11 */ V(2, 0, 2),
2727
2728 /* 0010 1100 ... */
2729 /* 000 */ V(0, 15, 1),/* 172 */
2730 /* 001 */ V(0, 15, 1),
2731 /* 010 */ V(0, 15, 1),
2732 /* 011 */ V(0, 15, 1),
2733 /* 100 */ V(14, 14, 3),
2734 /* 101 */ V(13, 14, 3),
2735 /* 110 */ V(14, 13, 3),
2736 /* 111 */ V(12, 14, 3),
2737
2738 /* 0010 1101 ... */
2739 /* 000 */ V(14, 12, 3),/* 180 */
2740 /* 001 */ V(13, 13, 3),
2741 /* 010 */ V(11, 14, 3),
2742 /* 011 */ V(14, 11, 3),
2743 /* 100 */ V(12, 13, 3),
2744 /* 101 */ V(13, 12, 3),
2745 /* 110 */ V(10, 14, 3),
2746 /* 111 */ V(14, 10, 3),
2747
2748 /* 0010 1110 ... */
2749 /* 000 */ V(11, 13, 3),/* 188 */
2750 /* 001 */ V(13, 11, 3),
2751 /* 010 */ V(12, 12, 3),
2752 /* 011 */ V(9, 14, 3),
2753 /* 100 */ V(14, 9, 3),
2754 /* 101 */ V(10, 13, 3),
2755 /* 110 */ V(13, 10, 3),
2756 /* 111 */ V(11, 12, 3),
2757
2758 /* 0010 1111 ... */
2759 /* 000 */ V(12, 11, 3),/* 196 */
2760 /* 001 */ V(8, 14, 3),
2761 /* 010 */ V(14, 8, 3),
2762 /* 011 */ V(9, 13, 3),
2763 /* 100 */ V(13, 9, 3),
2764 /* 101 */ V(7, 14, 3),
2765 /* 110 */ V(14, 7, 3),
2766 /* 111 */ V(10, 12, 3),
2767
2768 /* 0100 0000 ... */
2769 /* 0000 */ V(12, 10, 3),/* 204 */
2770 /* 0001 */ V(12, 10, 3),
2771 /* 0010 */ V(11, 11, 3),
2772 /* 0011 */ V(11, 11, 3),
2773 /* 0100 */ V(8, 13, 3),
2774 /* 0101 */ V(8, 13, 3),
2775 /* 0110 */ V(13, 8, 3),
2776 /* 0111 */ V(13, 8, 3),
2777 /* 1000 */ V(0, 14, 4),
2778 /* 1001 */ V(14, 0, 4),
2779 /* 1010 */ V(0, 13, 3),
2780 /* 1011 */ V(0, 13, 3),
2781 /* 1100 */ V(14, 6, 2),
2782 /* 1101 */ V(14, 6, 2),
2783 /* 1110 */ V(14, 6, 2),
2784 /* 1111 */ V(14, 6, 2),
2785
2786 /* 0100 0001 ... */
2787 /* 000 */ V(6, 14, 3),/* 220 */
2788 /* 001 */ V(9, 12, 3),
2789 /* 010 */ V(12, 9, 2),
2790 /* 011 */ V(12, 9, 2),
2791 /* 100 */ V(5, 14, 2),
2792 /* 101 */ V(5, 14, 2),
2793 /* 110 */ V(11, 10, 2),
2794 /* 111 */ V(11, 10, 2),
2795
2796 /* 0100 0010 ... */
2797 /* 000 */ V(14, 5, 2),/* 228 */
2798 /* 001 */ V(14, 5, 2),
2799 /* 010 */ V(10, 11, 3),
2800 /* 011 */ V(7, 13, 3),
2801 /* 100 */ V(13, 7, 2),
2802 /* 101 */ V(13, 7, 2),
2803 /* 110 */ V(14, 4, 2),
2804 /* 111 */ V(14, 4, 2),
2805
2806 /* 0100 0011 ... */
2807 /* 000 */ V(8, 12, 2),/* 236 */
2808 /* 001 */ V(8, 12, 2),
2809 /* 010 */ V(12, 8, 2),
2810 /* 011 */ V(12, 8, 2),
2811 /* 100 */ V(4, 14, 3),
2812 /* 101 */ V(2, 14, 3),
2813 /* 110 */ V(3, 14, 2),
2814 /* 111 */ V(3, 14, 2),
2815
2816 /* 0100 0100 ... */
2817 /* 00 */ V(6, 13, 2),/* 244 */
2818 /* 01 */ V(13, 6, 2),
2819 /* 10 */ V(14, 3, 2),
2820 /* 11 */ V(9, 11, 2),
2821
2822 /* 0100 0101 ... */
2823 /* 00 */ V(11, 9, 2),/* 248 */
2824 /* 01 */ V(10, 10, 2),
2825 /* 10 */ V(14, 2, 2),
2826 /* 11 */ V(1, 14, 2),
2827
2828 /* 0100 0110 ... */
2829 /* 00 */ V(14, 1, 2),/* 252 */
2830 /* 01 */ V(5, 13, 2),
2831 /* 10 */ V(13, 5, 2),
2832 /* 11 */ V(7, 12, 2),
2833
2834 /* 0100 0111 ... */
2835 /* 00 */ V(12, 7, 2),/* 256 */
2836 /* 01 */ V(4, 13, 2),
2837 /* 10 */ V(8, 11, 2),
2838 /* 11 */ V(11, 8, 2),
2839
2840 /* 0100 1000 ... */
2841 /* 00 */ V(13, 4, 2),/* 260 */
2842 /* 01 */ V(9, 10, 2),
2843 /* 10 */ V(10, 9, 2),
2844 /* 11 */ V(6, 12, 2),
2845
2846 /* 0100 1001 ... */
2847 /* 00 */ V(12, 6, 2),/* 264 */
2848 /* 01 */ V(3, 13, 2),
2849 /* 10 */ V(13, 3, 2),
2850 /* 11 */ V(2, 13, 2),
2851
2852 /* 0100 1010 ... */
2853 /* 00 */ V(13, 2, 2),/* 268 */
2854 /* 01 */ V(1, 13, 2),
2855 /* 10 */ V(7, 11, 2),
2856 /* 11 */ V(11, 7, 2),
2857
2858 /* 0100 1011 ... */
2859 /* 00 */ V(13, 1, 2),/* 272 */
2860 /* 01 */ V(5, 12, 2),
2861 /* 10 */ V(12, 5, 2),
2862 /* 11 */ V(8, 10, 2),
2863
2864 /* 0100 1100 ... */
2865 /* 00 */ V(10, 8, 2),/* 276 */
2866 /* 01 */ V(9, 9, 2),
2867 /* 10 */ V(4, 12, 2),
2868 /* 11 */ V(12, 4, 2),
2869
2870 /* 0100 1101 ... */
2871 /* 000 */ V(6, 11, 2),/* 280 */
2872 /* 001 */ V(6, 11, 2),
2873 /* 010 */ V(11, 6, 2),
2874 /* 011 */ V(11, 6, 2),
2875 /* 100 */ V(13, 0, 3),
2876 /* 101 */ V(0, 12, 3),
2877 /* 110 */ V(3, 12, 2),
2878 /* 111 */ V(3, 12, 2),
2879
2880 /* 0100 1110 ... */
2881 /* 00 */ V(12, 3, 2),/* 288 */
2882 /* 01 */ V(7, 10, 2),
2883 /* 10 */ V(10, 7, 2),
2884 /* 11 */ V(2, 12, 2),
2885
2886 /* 0100 1111 ... */
2887 /* 00 */ V(12, 2, 2),/* 292 */
2888 /* 01 */ V(5, 11, 2),
2889 /* 10 */ V(11, 5, 2),
2890 /* 11 */ V(1, 12, 2),
2891
2892 /* 0101 0000 ... */
2893 /* 00 */ V(8, 9, 2),/* 296 */
2894 /* 01 */ V(9, 8, 2),
2895 /* 10 */ V(12, 1, 2),
2896 /* 11 */ V(4, 11, 2),
2897
2898 /* 0101 0001 ... */
2899 /* 000 */ V(12, 0, 3),/* 300 */
2900 /* 001 */ V(0, 11, 3),
2901 /* 010 */ V(3, 11, 2),
2902 /* 011 */ V(3, 11, 2),
2903 /* 100 */ V(11, 0, 3),
2904 /* 101 */ V(0, 10, 3),
2905 /* 110 */ V(1, 10, 2),
2906 /* 111 */ V(1, 10, 2),
2907
2908 /* 0101 0010 ... */
2909 /* 00 */ V(11, 4, 1),/* 308 */
2910 /* 01 */ V(11, 4, 1),
2911 /* 10 */ V(6, 10, 2),
2912 /* 11 */ V(10, 6, 2),
2913
2914 /* 0101 0011 ... */
2915 /* 000 */ V(7, 9, 2),/* 312 */
2916 /* 001 */ V(7, 9, 2),
2917 /* 010 */ V(9, 7, 2),
2918 /* 011 */ V(9, 7, 2),
2919 /* 100 */ V(10, 0, 3),
2920 /* 101 */ V(0, 9, 3),
2921 /* 110 */ V(9, 0, 2),
2922 /* 111 */ V(9, 0, 2),
2923
2924 /* 0101 0100 ... */
2925 /* 0 */ V(11, 3, 1),/* 320 */
2926 /* 1 */ V(8, 8, 1),
2927
2928 /* 0101 0101 ... */
2929 /* 00 */ V(2, 11, 2),/* 322 */
2930 /* 01 */ V(5, 10, 2),
2931 /* 10 */ V(11, 2, 1),
2932 /* 11 */ V(11, 2, 1),
2933
2934 /* 0101 0110 ... */
2935 /* 00 */ V(10, 5, 2),/* 326 */
2936 /* 01 */ V(1, 11, 2),
2937 /* 10 */ V(11, 1, 2),
2938 /* 11 */ V(6, 9, 2),
2939
2940 /* 0101 0111 ... */
2941 /* 0 */ V(9, 6, 1),/* 330 */
2942 /* 1 */ V(10, 4, 1),
2943
2944 /* 0101 1000 ... */
2945 /* 00 */ V(4, 10, 2),/* 332 */
2946 /* 01 */ V(7, 8, 2),
2947 /* 10 */ V(8, 7, 1),
2948 /* 11 */ V(8, 7, 1),
2949
2950 /* 0101 1001 ... */
2951 /* 0 */ V(3, 10, 1),/* 336 */
2952 /* 1 */ V(10, 3, 1),
2953
2954 /* 0101 1010 ... */
2955 /* 0 */ V(5, 9, 1),/* 338 */
2956 /* 1 */ V(9, 5, 1),
2957
2958 /* 0101 1011 ... */
2959 /* 0 */ V(2, 10, 1),/* 340 */
2960 /* 1 */ V(10, 2, 1),
2961
2962 /* 0101 1100 ... */
2963 /* 0 */ V(10, 1, 1),/* 342 */
2964 /* 1 */ V(6, 8, 1),
2965
2966 /* 0101 1101 ... */
2967 /* 0 */ V(8, 6, 1),/* 344 */
2968 /* 1 */ V(7, 7, 1),
2969
2970 /* 0101 1110 ... */
2971 /* 0 */ V(4, 9, 1),/* 346 */
2972 /* 1 */ V(9, 4, 1),
2973
2974 /* 0101 1111 ... */
2975 /* 0 */ V(3, 9, 1),/* 348 */
2976 /* 1 */ V(9, 3, 1),
2977
2978 /* 0110 0000 ... */
2979 /* 0 */ V(5, 8, 1),/* 350 */
2980 /* 1 */ V(8, 5, 1),
2981
2982 /* 0110 0001 ... */
2983 /* 0 */ V(2, 9, 1),/* 352 */
2984 /* 1 */ V(6, 7, 1),
2985
2986 /* 0110 0010 ... */
2987 /* 0 */ V(7, 6, 1),/* 354 */
2988 /* 1 */ V(9, 2, 1),
2989
2990 /* 0110 0011 ... */
2991 /* 0 */ V(1, 9, 1),/* 356 */
2992 /* 1 */ V(9, 1, 1),
2993
2994 /* 0110 0100 ... */
2995 /* 0 */ V(4, 8, 1),/* 358 */
2996 /* 1 */ V(8, 4, 1),
2997
2998 /* 0110 0101 ... */
2999 /* 0 */ V(5, 7, 1),/* 360 */
3000 /* 1 */ V(7, 5, 1),
3001
3002 /* 0110 0110 ... */
3003 /* 0 */ V(3, 8, 1),/* 362 */
3004 /* 1 */ V(8, 3, 1),
3005
3006 /* 0110 0111 ... */
3007 /* 0 */ V(6, 6, 1),/* 364 */
3008 /* 1 */ V(2, 8, 1),
3009
3010 /* 0110 1000 ... */
3011 /* 0 */ V(8, 2, 1),/* 366 */
3012 /* 1 */ V(1, 8, 1),
3013
3014 /* 0110 1001 ... */
3015 /* 0 */ V(4, 7, 1),/* 368 */
3016 /* 1 */ V(7, 4, 1),
3017
3018 /* 0110 1010 ... */
3019 /* 00 */ V(8, 1, 1),/* 370 */
3020 /* 01 */ V(8, 1, 1),
3021 /* 10 */ V(0, 8, 2),
3022 /* 11 */ V(8, 0, 2),
3023
3024 /* 0110 1011 ... */
3025 /* 0 */ V(5, 6, 1),/* 374 */
3026 /* 1 */ V(6, 5, 1),
3027
3028 /* 0110 1100 ... */
3029 /* 00 */ V(1, 7, 1),/* 376 */
3030 /* 01 */ V(1, 7, 1),
3031 /* 10 */ V(0, 7, 2),
3032 /* 11 */ V(7, 0, 2),
3033
3034 /* 0110 1110 ... */
3035 /* 0 */ V(3, 7, 1),/* 380 */
3036 /* 1 */ V(2, 7, 1),
3037
3038 /* 0111 1100 ... */
3039 /* 0 */ V(0, 6, 1),/* 382 */
3040 /* 1 */ V(6, 0, 1),
3041
3042 /* 1000 0011 ... */
3043 /* 0 */ V(0, 5, 1),/* 384 */
3044 /* 1 */ V(5, 0, 1)
3045};
3046
3047# undef V
3048# undef PTR
3049
3050/* external tables */
3051
3052union huffquad const *const mad_huff_quad_table[2] = { hufftabA, hufftabB };
3053
3054struct hufftable const mad_huff_pair_table[32] = {
3055 /* 0 */ { hufftab0, 0, 0 },
3056 /* 1 */ { hufftab1, 0, 3 },
3057 /* 2 */ { hufftab2, 0, 3 },
3058 /* 3 */ { hufftab3, 0, 3 },
3059 /* 4 */ { 0 /* not used */ },
3060 /* 5 */ { hufftab5, 0, 3 },
3061 /* 6 */ { hufftab6, 0, 4 },
3062 /* 7 */ { hufftab7, 0, 4 },
3063 /* 8 */ { hufftab8, 0, 4 },
3064 /* 9 */ { hufftab9, 0, 4 },
3065 /* 10 */ { hufftab10, 0, 4 },
3066 /* 11 */ { hufftab11, 0, 4 },
3067 /* 12 */ { hufftab12, 0, 4 },
3068 /* 13 */ { hufftab13, 0, 4 },
3069 /* 14 */ { 0 /* not used */ },
3070 /* 15 */ { hufftab15, 0, 4 },
3071 /* 16 */ { hufftab16, 1, 4 },
3072 /* 17 */ { hufftab16, 2, 4 },
3073 /* 18 */ { hufftab16, 3, 4 },
3074 /* 19 */ { hufftab16, 4, 4 },
3075 /* 20 */ { hufftab16, 6, 4 },
3076 /* 21 */ { hufftab16, 8, 4 },
3077 /* 22 */ { hufftab16, 10, 4 },
3078 /* 23 */ { hufftab16, 13, 4 },
3079 /* 24 */ { hufftab24, 4, 4 },
3080 /* 25 */ { hufftab24, 5, 4 },
3081 /* 26 */ { hufftab24, 6, 4 },
3082 /* 27 */ { hufftab24, 7, 4 },
3083 /* 28 */ { hufftab24, 8, 4 },
3084 /* 29 */ { hufftab24, 9, 4 },
3085 /* 30 */ { hufftab24, 11, 4 },
3086 /* 31 */ { hufftab24, 13, 4 }
3087};
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 @@
1/*
2 * mad - MPEG audio decoder
3 * Copyright (C) 2000-2001 Robert Leslie
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * $Id$
20 */
21
22# ifndef LIBMAD_HUFFMAN_H
23# define LIBMAD_HUFFMAN_H
24
25union huffquad {
26 struct {
27 unsigned short final : 1;
28 unsigned short hlen : 3;
29 unsigned short v : 1;
30 unsigned short w : 1;
31 unsigned short x : 1;
32 unsigned short y : 1;
33 } value;
34 struct {
35 unsigned short final : 1;
36 unsigned short bits : 3;
37 unsigned short offset : 12;
38 } ptr;
39 unsigned short final : 1;
40};
41
42union huffpair {
43 struct {
44 unsigned short final : 1;
45 unsigned short hlen : 3;
46 unsigned short x : 4;
47 unsigned short y : 4;
48 } value;
49 struct {
50 unsigned short final : 1;
51 unsigned short bits : 3;
52 unsigned short offset : 12;
53 } ptr;
54 unsigned short final : 1;
55};
56
57struct hufftable {
58 union huffpair const *table;
59 unsigned short linbits;
60 unsigned short startbits;
61};
62
63extern union huffquad const *const mad_huff_quad_table[2];
64extern struct hufftable const mad_huff_pair_table[32];
65
66# 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 @@
1/*****************************************************************************
2* Copyright (C) 2000-2001 Andre McCurdy <armccurdy@yahoo.co.uk>
3*
4* This program is free software. you can redistribute it and/or modify
5* it under the terms of the GNU General Public License as published by
6* the Free Software Foundation@ either version 2 of the License, or
7* (at your option) any later version.
8*
9* This program is distributed in the hope that it will be useful,
10* but WITHOUT ANY WARRANTY, without even the implied warranty of
11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12* GNU General Public License for more details.
13*
14* You should have received a copy of the GNU General Public License
15* along with this program@ if not, write to the Free Software
16* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17*
18*****************************************************************************
19*
20* Notes:
21*
22*
23*****************************************************************************
24*
25* $Id$
26*
27* 2001/03/24: Andre McCurdy <armccurdy@yahoo.co.uk>
28* - Corrected PIC unsafe loading of address of 'imdct36_long_karray'
29*
30* 2000/09/20: Robert Leslie <rob@mars.org>
31* - Added a global symbol with leading underscore per suggestion of
32* Simon Burge to support linking with the a.out format.
33*
34* 2000/09/15: Robert Leslie <rob@mars.org>
35* - Fixed a small bug where flags were changed before a conditional branch.
36*
37* 2000/09/15: Andre McCurdy <armccurdy@yahoo.co.uk>
38* - Applied Nicolas Pitre's rounding optimisation in all remaining places.
39*
40* 2000/09/09: Nicolas Pitre <nico@cam.org>
41* - Optimized rounding + scaling operations.
42*
43* 2000/08/09: Andre McCurdy <armccurdy@yahoo.co.uk>
44* - Original created.
45*
46****************************************************************************/
47
48
49/*
50 On entry:
51
52 r0 = pointer to 18 element input array
53 r1 = pointer to 36 element output array
54 r2 = windowing block type
55
56
57 Stack frame created during execution of the function:
58
59 Initial Holds:
60 Stack
61 pointer
62 minus:
63
64 0
65 4 lr
66 8 r11
67 12 r10
68 16 r9
69 20 r8
70 24 r7
71 28 r6
72 32 r5
73 36 r4
74
75 40 r2 : windowing block type
76
77 44 ct00 high
78 48 ct00 low
79 52 ct01 high
80 56 ct01 low
81 60 ct04 high
82 64 ct04 low
83 68 ct06 high
84 72 ct06 low
85 76 ct05 high
86 80 ct05 low
87 84 ct03 high
88 88 ct03 low
89 92 -ct05 high
90 96 -ct05 low
91 100 -ct07 high
92 104 -ct07 low
93 108 ct07 high
94 112 ct07 low
95 116 ct02 high
96 120 ct02 low
97*/
98
99#define BLOCK_MODE_NORMAL 0
100#define BLOCK_MODE_START 1
101#define BLOCK_MODE_STOP 3
102
103
104#define X0 0x00
105#define X1 0x04
106#define X2 0x08
107#define X3 0x0C
108#define X4 0x10
109#define X5 0x14
110#define X6 0x18
111#define X7 0x1c
112#define X8 0x20
113#define X9 0x24
114#define X10 0x28
115#define X11 0x2c
116#define X12 0x30
117#define X13 0x34
118#define X14 0x38
119#define X15 0x3c
120#define X16 0x40
121#define X17 0x44
122
123#define x0 0x00
124#define x1 0x04
125#define x2 0x08
126#define x3 0x0C
127#define x4 0x10
128#define x5 0x14
129#define x6 0x18
130#define x7 0x1c
131#define x8 0x20
132#define x9 0x24
133#define x10 0x28
134#define x11 0x2c
135#define x12 0x30
136#define x13 0x34
137#define x14 0x38
138#define x15 0x3c
139#define x16 0x40
140#define x17 0x44
141#define x18 0x48
142#define x19 0x4c
143#define x20 0x50
144#define x21 0x54
145#define x22 0x58
146#define x23 0x5c
147#define x24 0x60
148#define x25 0x64
149#define x26 0x68
150#define x27 0x6c
151#define x28 0x70
152#define x29 0x74
153#define x30 0x78
154#define x31 0x7c
155#define x32 0x80
156#define x33 0x84
157#define x34 0x88
158#define x35 0x8c
159
160#define K00 0x0ffc19fd
161#define K01 0x00b2aa3e
162#define K02 0x0fdcf549
163#define K03 0x0216a2a2
164#define K04 0x0f9ee890
165#define K05 0x03768962
166#define K06 0x0f426cb5
167#define K07 0x04cfb0e2
168#define K08 0x0ec835e8
169#define K09 0x061f78aa
170#define K10 0x0e313245
171#define K11 0x07635284
172#define K12 0x0d7e8807
173#define K13 0x0898c779
174#define K14 0x0cb19346
175#define K15 0x09bd7ca0
176#define K16 0x0bcbe352
177#define K17 0x0acf37ad
178
179#define minus_K02 0xf0230ab7
180
181#define WL0 0x00b2aa3e
182#define WL1 0x0216a2a2
183#define WL2 0x03768962
184#define WL3 0x04cfb0e2
185#define WL4 0x061f78aa
186#define WL5 0x07635284
187#define WL6 0x0898c779
188#define WL7 0x09bd7ca0
189#define WL8 0x0acf37ad
190#define WL9 0x0bcbe352
191#define WL10 0x0cb19346
192#define WL11 0x0d7e8807
193#define WL12 0x0e313245
194#define WL13 0x0ec835e8
195#define WL14 0x0f426cb5
196#define WL15 0x0f9ee890
197#define WL16 0x0fdcf549
198#define WL17 0x0ffc19fd
199
200
201@*****************************************************************************
202
203
204 .text
205 .align
206
207 .global III_imdct_l
208 .global _III_imdct_l
209
210III_imdct_l:
211_III_imdct_l:
212
213 stmdb sp!, { r2, r4 - r11, lr } @ all callee saved regs, plus arg3
214
215 ldr r4, =K08 @ r4 = K08
216 ldr r5, =K09 @ r5 = K09
217 ldr r8, [r0, #X4] @ r8 = X4
218 ldr r9, [r0, #X13] @ r9 = X13
219 rsb r6, r4, #0 @ r6 = -K08
220 rsb r7, r5, #0 @ r7 = -K09
221
222 smull r2, r3, r4, r8 @ r2..r3 = (X4 * K08)
223 smlal r2, r3, r5, r9 @ r2..r3 = (X4 * K08) + (X13 * K09) = ct01
224
225 smull r10, lr, r8, r5 @ r10..lr = (X4 * K09)
226 smlal r10, lr, r9, r6 @ r10..lr = (X4 * K09) + (X13 * -K08) = ct00
227
228 ldr r8, [r0, #X7] @ r8 = X7
229 ldr r9, [r0, #X16] @ r9 = X16
230
231 stmdb sp!, { r2, r3, r10, lr } @ stack ct00_h, ct00_l, ct01_h, ct01_l
232
233 add r8, r8, r9 @ r8 = (X7 + X16)
234 ldr r9, [r0, #X1] @ r9 = X1
235
236 smlal r2, r3, r6, r8 @ r2..r3 = ct01 + ((X7 + X16) * -K08)
237 smlal r2, r3, r7, r9 @ r2..r3 += (X1 * -K09)
238
239 ldr r7, [r0, #X10] @ r7 = X10
240
241 rsbs r10, r10, #0
242 rsc lr, lr, #0 @ r10..lr = -ct00
243
244 smlal r2, r3, r5, r7 @ r2..r3 += (X10 * K09) = ct06
245
246 smlal r10, lr, r9, r6 @ r10..lr = -ct00 + ( X1 * -K08)
247 smlal r10, lr, r8, r5 @ r10..lr += ((X7 + X16) * K09)
248 smlal r10, lr, r7, r4 @ r10..lr += ( X10 * K08) = ct04
249
250 stmdb sp!, { r2, r3, r10, lr } @ stack ct04_h, ct04_l, ct06_h, ct06_l
251
252 @----
253
254 ldr r7, [r0, #X0]
255 ldr r8, [r0, #X11]
256 ldr r9, [r0, #X12]
257 sub r7, r7, r8
258 sub r7, r7, r9 @ r7 = (X0 - X11 -X12) = ct14
259
260 ldr r9, [r0, #X3]
261 ldr r8, [r0, #X8]
262 ldr r11, [r0, #X15]
263 sub r8, r8, r9
264 add r8, r8, r11 @ r8 = (X8 - X3 + X15) = ct16
265
266 add r11, r7, r8 @ r11 = ct14 + ct16 = ct18
267
268 smlal r2, r3, r6, r11 @ r2..r3 = ct06 + ((X0 - X11 - X3 + X15 + X8 - X12) * -K08)
269
270 ldr r6, [r0, #X2]
271 ldr r9, [r0, #X9]
272 ldr r12, [r0, #X14]
273 sub r6, r6, r9
274 sub r6, r6, r12 @ r6 = (X2 - X9 - X14) = ct15
275
276 ldr r9, [r0, #X5]
277 ldr r12, [r0, #X6]
278 sub r9, r9, r12
279 ldr r12, [r0, #X17]
280 sub r9, r9, r12 @ r9 = (X5 - X6 - X17) = ct17
281
282 add r12, r9, r6 @ r12 = ct15 + ct17 = ct19
283
284 smlal r2, r3, r5, r12 @ r2..r3 += ((X2 - X9 + X5 - X6 - X17 - X14) * K09)
285
286 smlal r10, lr, r11, r5 @ r10..lr = ct04 + (ct18 * K09)
287 smlal r10, lr, r12, r4 @ r10..lr = ct04 + (ct18 * K09) + (ct19 * K08)
288
289 movs r2, r2, lsr #28
290 adc r2, r2, r3, lsl #4 @ r2 = bits[59..28] of r2..r3
291 str r2, [r1, #x22] @ store result x22
292
293 movs r10, r10, lsr #28
294 adc r10, r10, lr, lsl #4 @ r10 = bits[59..28] of r10..lr
295 str r10, [r1, #x4] @ store result x4
296
297 @----
298
299 ldmia sp, { r2, r3, r4, r5 } @ r2..r3 = ct06, r4..r5 = ct04 (dont update sp)
300
301 @ r2..r3 = ct06
302 @ r4..r5 = ct04
303 @ r6 = ct15
304 @ r7 = ct14
305 @ r8 = ct16
306 @ r9 = ct17
307 @ r10 = .
308 @ r11 = .
309 @ r12 = .
310 @ lr = .
311
312 ldr r10, =K03 @ r10 = K03
313 ldr lr, =K15 @ lr = K15
314
315 smlal r2, r3, r10, r7 @ r2..r3 = ct06 + (ct14 * K03)
316 smlal r4, r5, lr, r7 @ r4..r5 = ct04 + (ct14 * K15)
317
318 ldr r12, =K14 @ r12 = K14
319 rsb r10, r10, #0 @ r10 = -K03
320
321 smlal r2, r3, lr, r6 @ r2..r3 += (ct15 * K15)
322 smlal r4, r5, r10, r6 @ r4..r5 += (ct15 * -K03)
323 smlal r2, r3, r12, r8 @ r2..r3 += (ct16 * K14)
324
325 ldr r11, =minus_K02 @ r11 = -K02
326 rsb r12, r12, #0 @ r12 = -K14
327
328 smlal r4, r5, r12, r9 @ r4..r5 += (ct17 * -K14)
329 smlal r2, r3, r11, r9 @ r2..r3 += (ct17 * -K02)
330 smlal r4, r5, r11, r8 @ r4..r5 += (ct16 * -K02)
331
332 movs r2, r2, lsr #28
333 adc r2, r2, r3, lsl #4 @ r2 = bits[59..28] of r2..r3
334 str r2, [r1, #x7] @ store result x7
335
336 movs r4, r4, lsr #28
337 adc r4, r4, r5, lsl #4 @ r4 = bits[59..28] of r4..r5
338 str r4, [r1, #x1] @ store result x1
339
340 @----
341
342 ldmia sp, { r2, r3, r4, r5 } @ r2..r3 = ct06, r4..r5 = ct04 (dont update sp)
343
344 @ r2..r3 = ct06
345 @ r4..r5 = ct04
346 @ r6 = ct15
347 @ r7 = ct14
348 @ r8 = ct16
349 @ r9 = ct17
350 @ r10 = -K03
351 @ r11 = -K02
352 @ r12 = -K14
353 @ lr = K15
354
355 rsbs r2, r2, #0
356 rsc r3, r3, #0 @ r2..r3 = -ct06
357
358 smlal r2, r3, r12, r7 @ r2..r3 = -ct06 + (ct14 * -K14)
359 smlal r2, r3, r10, r8 @ r2..r3 += (ct16 * -K03)
360
361 smlal r4, r5, r12, r6 @ r4..r5 = ct04 + (ct15 * -K14)
362 smlal r4, r5, r10, r9 @ r4..r5 += (ct17 * -K03)
363 smlal r4, r5, lr, r8 @ r4..r5 += (ct16 * K15)
364 smlal r4, r5, r11, r7 @ r4..r5 += (ct14 * -K02)
365
366 rsb lr, lr, #0 @ lr = -K15
367 rsb r11, r11, #0 @ r11 = K02
368
369 smlal r2, r3, lr, r9 @ r2..r3 += (ct17 * -K15)
370 smlal r2, r3, r11, r6 @ r2..r3 += (ct15 * K02)
371
372 movs r4, r4, lsr #28
373 adc r4, r4, r5, lsl #4 @ r4 = bits[59..28] of r4..r5
374 str r4, [r1, #x25] @ store result x25
375
376 movs r2, r2, lsr #28
377 adc r2, r2, r3, lsl #4 @ r2 = bits[59..28] of r2..r3
378 str r2, [r1, #x19] @ store result x19
379
380 @----
381
382 ldr r2, [sp, #16] @ r2 = ct01_l
383 ldr r3, [sp, #20] @ r3 = ct01_h
384
385 ldr r6, [r0, #X1]
386 ldr r8, [r0, #X7]
387 ldr r9, [r0, #X10]
388 ldr r7, [r0, #X16]
389
390 rsbs r2, r2, #0
391 rsc r3, r3, #0 @ r2..r3 = -ct01
392
393 mov r4, r2
394 mov r5, r3 @ r4..r5 = -ct01
395
396 @ r2..r3 = -ct01
397 @ r4..r5 = -ct01
398 @ r6 = X1
399 @ r7 = X16
400 @ r8 = X7
401 @ r9 = X10
402 @ r10 = -K03
403 @ r11 = K02
404 @ r12 = -K14
405 @ lr = -K15
406
407 smlal r4, r5, r12, r7 @ r4..r5 = -ct01 + (X16 * -K14)
408 smlal r2, r3, lr, r9 @ r2..r3 = -ct01 + (X10 * -K15)
409
410 smlal r4, r5, r10, r8 @ r4..r5 += (X7 * -K03)
411 smlal r2, r3, r10, r7 @ r2..r3 += (X16 * -K03)
412
413 smlal r4, r5, r11, r9 @ r4..r5 += (X10 * K02)
414 smlal r2, r3, r12, r8 @ r2..r3 += (X7 * -K14)
415
416 rsb lr, lr, #0 @ lr = K15
417 rsb r11, r11, #0 @ r11 = -K02
418
419 smlal r4, r5, lr, r6 @ r4..r5 += (X1 * K15) = ct05
420 smlal r2, r3, r11, r6 @ r2..r3 += (X1 * -K02) = ct03
421
422 stmdb sp!, { r2, r3, r4, r5 } @ stack ct05_h, ct05_l, ct03_h, ct03_l
423
424 rsbs r4, r4, #0
425 rsc r5, r5, #0 @ r4..r5 = -ct05
426
427 stmdb sp!, { r4, r5 } @ stack -ct05_h, -ct05_l
428
429 ldr r2, [sp, #48] @ r2 = ct00_l
430 ldr r3, [sp, #52] @ r3 = ct00_h
431
432 rsb r10, r10, #0 @ r10 = K03
433
434 rsbs r4, r2, #0
435 rsc r5, r3, #0 @ r4..r5 = -ct00
436
437 @ r2..r3 = ct00
438 @ r4..r5 = -ct00
439 @ r6 = X1
440 @ r7 = X16
441 @ r8 = X7
442 @ r9 = X10
443 @ r10 = K03
444 @ r11 = -K02
445 @ r12 = -K14
446 @ lr = K15
447
448 smlal r4, r5, r10, r6 @ r4..r5 = -ct00 + (X1 * K03)
449 smlal r2, r3, r10, r9 @ r2..r3 = ct00 + (X10 * K03)
450
451 smlal r4, r5, r12, r9 @ r4..r5 += (X10 * -K14)
452 smlal r2, r3, r12, r6 @ r2..r3 += (X1 * -K14)
453
454 smlal r4, r5, r11, r7 @ r4..r5 += (X16 * -K02)
455 smlal r4, r5, lr, r8 @ r4..r5 += (X7 * K15) = ct07
456
457 rsb lr, lr, #0 @ lr = -K15
458 rsb r11, r11, #0 @ r11 = K02
459
460 smlal r2, r3, r11, r8 @ r2..r3 += (X7 * K02)
461 smlal r2, r3, lr, r7 @ r2..r3 += (X16 * -K15) = ct02
462
463 rsbs r6, r4, #0
464 rsc r7, r5, #0 @ r6..r7 = -ct07
465
466 stmdb sp!, { r2 - r7 } @ stack -ct07_h, -ct07_l, ct07_h, ct07_l, ct02_h, ct02_l
467
468
469 @----
470
471 add r2, pc, #(imdct36_long_karray-.-8) @ r2 = base address of Knn array (PIC safe ?)
472
473
474loop:
475 ldr r12, [r0, #X0]
476
477 ldmia r2!, { r5 - r11 } @ first 7 words from Karray element
478
479 smull r3, r4, r5, r12 @ sum = (Kxx * X0)
480 ldr r12, [r0, #X2]
481 ldr r5, [r0, #X3]
482 smlal r3, r4, r6, r12 @ sum += (Kxx * X2)
483 ldr r12, [r0, #X5]
484 ldr r6, [r0, #X6]
485 smlal r3, r4, r7, r5 @ sum += (Kxx * X3)
486 smlal r3, r4, r8, r12 @ sum += (Kxx * X5)
487 ldr r12, [r0, #X8]
488 ldr r5, [r0, #X9]
489 smlal r3, r4, r9, r6 @ sum += (Kxx * X6)
490 smlal r3, r4, r10, r12 @ sum += (Kxx * X8)
491 smlal r3, r4, r11, r5 @ sum += (Kxx * X9)
492
493 ldmia r2!, { r5 - r10 } @ final 6 words from Karray element
494
495 ldr r11, [r0, #X11]
496 ldr r12, [r0, #X12]
497 smlal r3, r4, r5, r11 @ sum += (Kxx * X11)
498 ldr r11, [r0, #X14]
499 ldr r5, [r0, #X15]
500 smlal r3, r4, r6, r12 @ sum += (Kxx * X12)
501 smlal r3, r4, r7, r11 @ sum += (Kxx * X14)
502 ldr r11, [r0, #X17]
503 smlal r3, r4, r8, r5 @ sum += (Kxx * X15)
504 smlal r3, r4, r9, r11 @ sum += (Kxx * X17)
505
506 add r5, sp, r10, lsr #16 @ create index back into stack for required ctxx
507
508 ldmia r5, { r6, r7 } @ r6..r7 = ctxx
509
510 mov r8, r10, lsl #16 @ push ctxx index off the top end
511
512 adds r3, r3, r6 @ add low words
513 adc r4, r4, r7 @ add high words, with carry
514 movs r3, r3, lsr #28
515 adc r3, r3, r4, lsl #4 @ r3 = bits[59..28] of r3..r4
516
517 str r3, [r1, r8, lsr #24] @ push completion flag off the bottom end
518
519 movs r8, r8, lsl #8 @ push result location index off the top end
520 beq loop @ loop back if completion flag not set
521 b imdct_l_windowing @ branch to windowing stage if looping finished
522
523imdct36_long_karray:
524
525 .word K17, -K13, K10, -K06, -K05, K01, -K00, K04, -K07, K11, K12, -K16, 0x00000000
526 .word K13, K07, K16, K01, K10, -K05, K04, -K11, K00, -K17, K06, -K12, 0x00200800
527 .word K11, K17, K05, K12, -K01, K06, -K07, K00, -K13, K04, -K16, K10, 0x00200c00
528 .word K07, K00, -K12, K05, -K16, -K10, K11, -K17, K04, K13, K01, K06, 0x00001400
529 .word K05, K10, -K00, -K17, K07, -K13, K12, K06, -K16, K01, -K11, -K04, 0x00181800
530 .word K01, K05, -K07, -K11, K13, K17, -K16, -K12, K10, K06, -K04, -K00, 0x00102000
531 .word -K16, K12, -K11, K07, K04, -K00, -K01, K05, -K06, K10, K13, -K17, 0x00284800
532 .word -K12, K06, K17, -K00, -K11, K04, K05, -K10, K01, K16, -K07, -K13, 0x00085000
533 .word -K10, K16, K04, -K13, -K00, K07, K06, -K01, -K12, -K05, K17, K11, 0x00105400
534 .word -K06, -K01, K13, K04, K17, -K11, -K10, -K16, -K05, K12, K00, K07, 0x00185c00
535 .word -K04, -K11, -K01, K16, K06, K12, K13, -K07, -K17, -K00, -K10, -K05, 0x00006000
536 .word -K00, -K04, -K06, -K10, -K12, -K16, -K17, -K13, -K11, -K07, -K05, -K01, 0x00206801
537
538
539 @----
540 @-------------------------------------------------------------------------
541 @----
542
543imdct_l_windowing:
544
545 ldr r11, [sp, #80] @ fetch function parameter 3 from out of the stack
546 ldmia r1!, { r0, r2 - r9 } @ load 9 words from x0, update pointer
547
548 @ r0 = x0
549 @ r1 = &x[9]
550 @ r2 = x1
551 @ r3 = x2
552 @ r4 = x3
553 @ r5 = x4
554 @ r6 = x5
555 @ r7 = x6
556 @ r8 = x7
557 @ r9 = x8
558 @ r10 = .
559 @ r11 = window mode: (0 == normal), (1 == start block), (3 == stop block)
560 @ r12 = .
561 @ lr = .
562
563 cmp r11, #BLOCK_MODE_STOP @ setup flags
564 rsb r10, r0, #0 @ r10 = -x0 (DONT change flags !!)
565 beq stop_block_x0_to_x17
566
567
568 @ start and normal blocks are treated the same for x[0]..x[17]
569
570normal_block_x0_to_x17:
571
572 ldr r12, =WL9 @ r12 = window_l[9]
573
574 rsb r0, r9, #0 @ r0 = -x8
575 rsb r9, r2, #0 @ r9 = -x1
576 rsb r2, r8, #0 @ r2 = -x7
577 rsb r8, r3, #0 @ r8 = -x2
578 rsb r3, r7, #0 @ r3 = -x6
579 rsb r7, r4, #0 @ r7 = -x3
580 rsb r4, r6, #0 @ r4 = -x5
581 rsb r6, r5, #0 @ r6 = -x4
582
583 @ r0 = -x8
584 @ r1 = &x[9]
585 @ r2 = -x7
586 @ r3 = -x6
587 @ r4 = -x5
588 @ r5 = .
589 @ r6 = -x4
590 @ r7 = -x3
591 @ r8 = -x2
592 @ r9 = -x1
593 @ r10 = -x0
594 @ r11 = window mode: (0 == normal), (1 == start block), (3 == stop block)
595 @ r12 = window_l[9]
596 @ lr = .
597
598 smull r5, lr, r12, r0 @ r5..lr = (window_l[9] * (x[9] == -x[8]))
599 ldr r12, =WL10 @ r12 = window_l[10]
600 movs r5, r5, lsr #28
601 adc r0, r5, lr, lsl #4 @ r0 = bits[59..28] of windowed x9
602
603 smull r5, lr, r12, r2 @ r5..lr = (window_l[10] * (x[10] == -x[7]))
604 ldr r12, =WL11 @ r12 = window_l[11]
605 movs r5, r5, lsr #28
606 adc r2, r5, lr, lsl #4 @ r2 = bits[59..28] of windowed x10
607
608 smull r5, lr, r12, r3 @ r5..lr = (window_l[11] * (x[11] == -x[6]))
609 ldr r12, =WL12 @ r12 = window_l[12]
610 movs r5, r5, lsr #28
611 adc r3, r5, lr, lsl #4 @ r3 = bits[59..28] of windowed x11
612
613 smull r5, lr, r12, r4 @ r5..lr = (window_l[12] * (x[12] == -x[5]))
614 ldr r12, =WL13 @ r12 = window_l[13]
615 movs r5, r5, lsr #28
616 adc r4, r5, lr, lsl #4 @ r4 = bits[59..28] of windowed x12
617
618 smull r5, lr, r12, r6 @ r5..lr = (window_l[13] * (x[13] == -x[4]))
619 ldr r12, =WL14 @ r12 = window_l[14]
620 movs r5, r5, lsr #28
621 adc r6, r5, lr, lsl #4 @ r6 = bits[59..28] of windowed x13
622
623 smull r5, lr, r12, r7 @ r5..lr = (window_l[14] * (x[14] == -x[3]))
624 ldr r12, =WL15 @ r12 = window_l[15]
625 movs r5, r5, lsr #28
626 adc r7, r5, lr, lsl #4 @ r7 = bits[59..28] of windowed x14
627
628 smull r5, lr, r12, r8 @ r5..lr = (window_l[15] * (x[15] == -x[2]))
629 ldr r12, =WL16 @ r12 = window_l[16]
630 movs r5, r5, lsr #28
631 adc r8, r5, lr, lsl #4 @ r8 = bits[59..28] of windowed x15
632
633 smull r5, lr, r12, r9 @ r5..lr = (window_l[16] * (x[16] == -x[1]))
634 ldr r12, =WL17 @ r12 = window_l[17]
635 movs r5, r5, lsr #28
636 adc r9, r5, lr, lsl #4 @ r9 = bits[59..28] of windowed x16
637
638 smull r5, lr, r12, r10 @ r5..lr = (window_l[17] * (x[17] == -x[0]))
639 ldr r12, =WL0 @ r12 = window_l[0]
640 movs r5, r5, lsr #28
641 adc r10, r5, lr, lsl #4 @ r10 = bits[59..28] of windowed x17
642
643
644 stmia r1, { r0, r2 - r4, r6 - r10 } @ store windowed x[9] .. x[17]
645 ldmdb r1!, { r0, r2 - r9 } @ load 9 words downto (and including) x0
646
647
648 smull r10, lr, r12, r0 @ r10..lr = (window_l[0] * x[0])
649 ldr r12, =WL1 @ r12 = window_l[1]
650 movs r10, r10, lsr #28
651 adc r0, r10, lr, lsl #4 @ r0 = bits[59..28] of windowed x0
652
653 smull r10, lr, r12, r2 @ r10..lr = (window_l[1] * x[1])
654 ldr r12, =WL2 @ r12 = window_l[2]
655 movs r10, r10, lsr #28
656 adc r2, r10, lr, lsl #4 @ r2 = bits[59..28] of windowed x1
657
658 smull r10, lr, r12, r3 @ r10..lr = (window_l[2] * x[2])
659 ldr r12, =WL3 @ r12 = window_l[3]
660 movs r10, r10, lsr #28
661 adc r3, r10, lr, lsl #4 @ r3 = bits[59..28] of windowed x2
662
663 smull r10, lr, r12, r4 @ r10..lr = (window_l[3] * x[3])
664 ldr r12, =WL4 @ r12 = window_l[4]
665 movs r10, r10, lsr #28
666 adc r4, r10, lr, lsl #4 @ r4 = bits[59..28] of windowed x3
667
668 smull r10, lr, r12, r5 @ r10..lr = (window_l[4] * x[4])
669 ldr r12, =WL5 @ r12 = window_l[5]
670 movs r10, r10, lsr #28
671 adc r5, r10, lr, lsl #4 @ r5 = bits[59..28] of windowed x4
672
673 smull r10, lr, r12, r6 @ r10..lr = (window_l[5] * x[5])
674 ldr r12, =WL6 @ r12 = window_l[6]
675 movs r10, r10, lsr #28
676 adc r6, r10, lr, lsl #4 @ r6 = bits[59..28] of windowed x5
677
678 smull r10, lr, r12, r7 @ r10..lr = (window_l[6] * x[6])
679 ldr r12, =WL7 @ r12 = window_l[7]
680 movs r10, r10, lsr #28
681 adc r7, r10, lr, lsl #4 @ r7 = bits[59..28] of windowed x6
682
683 smull r10, lr, r12, r8 @ r10..lr = (window_l[7] * x[7])
684 ldr r12, =WL8 @ r12 = window_l[8]
685 movs r10, r10, lsr #28
686 adc r8, r10, lr, lsl #4 @ r8 = bits[59..28] of windowed x7
687
688 smull r10, lr, r12, r9 @ r10..lr = (window_l[8] * x[8])
689 movs r10, r10, lsr #28
690 adc r9, r10, lr, lsl #4 @ r9 = bits[59..28] of windowed x8
691
692 stmia r1, { r0, r2 - r9 } @ store windowed x[0] .. x[8]
693
694 cmp r11, #BLOCK_MODE_START
695 beq start_block_x18_to_x35
696
697
698 @----
699
700
701normal_block_x18_to_x35:
702
703 ldr r11, =WL3 @ r11 = window_l[3]
704 ldr r12, =WL4 @ r12 = window_l[4]
705
706 add r1, r1, #(18*4) @ r1 = &x[18]
707
708 ldmia r1!, { r0, r2 - r4, r6 - r10 } @ load 9 words from x18, update pointer
709
710 @ r0 = x18
711 @ r1 = &x[27]
712 @ r2 = x19
713 @ r3 = x20
714 @ r4 = x21
715 @ r5 = .
716 @ r6 = x22
717 @ r7 = x23
718 @ r8 = x24
719 @ r9 = x25
720 @ r10 = x26
721 @ r11 = window_l[3]
722 @ r12 = window_l[4]
723 @ lr = .
724
725 smull r5, lr, r12, r6 @ r5..lr = (window_l[4] * (x[22] == x[31]))
726 movs r5, r5, lsr #28
727 adc r5, r5, lr, lsl #4 @ r5 = bits[59..28] of windowed x31
728
729 smull r6, lr, r11, r4 @ r5..lr = (window_l[3] * (x[21] == x[32]))
730 ldr r12, =WL5 @ r12 = window_l[5]
731 movs r6, r6, lsr #28
732 adc r6, r6, lr, lsl #4 @ r6 = bits[59..28] of windowed x32
733
734 smull r4, lr, r12, r7 @ r4..lr = (window_l[5] * (x[23] == x[30]))
735 ldr r11, =WL1 @ r11 = window_l[1]
736 ldr r12, =WL2 @ r12 = window_l[2]
737 movs r4, r4, lsr #28
738 adc r4, r4, lr, lsl #4 @ r4 = bits[59..28] of windowed x30
739
740 smull r7, lr, r12, r3 @ r7..lr = (window_l[2] * (x[20] == x[33]))
741 ldr r12, =WL6 @ r12 = window_l[6]
742 movs r7, r7, lsr #28
743 adc r7, r7, lr, lsl #4 @ r7 = bits[59..28] of windowed x33
744
745 smull r3, lr, r12, r8 @ r3..lr = (window_l[6] * (x[24] == x[29]))
746 movs r3, r3, lsr #28
747 adc r3, r3, lr, lsl #4 @ r3 = bits[59..28] of windowed x29
748
749 smull r8, lr, r11, r2 @ r7..lr = (window_l[1] * (x[19] == x[34]))
750 ldr r12, =WL7 @ r12 = window_l[7]
751 ldr r11, =WL8 @ r11 = window_l[8]
752 movs r8, r8, lsr #28
753 adc r8, r8, lr, lsl #4 @ r8 = bits[59..28] of windowed x34
754
755 smull r2, lr, r12, r9 @ r7..lr = (window_l[7] * (x[25] == x[28]))
756 ldr r12, =WL0 @ r12 = window_l[0]
757 movs r2, r2, lsr #28
758 adc r2, r2, lr, lsl #4 @ r2 = bits[59..28] of windowed x28
759
760 smull r9, lr, r12, r0 @ r3..lr = (window_l[0] * (x[18] == x[35]))
761 movs r9, r9, lsr #28
762 adc r9, r9, lr, lsl #4 @ r9 = bits[59..28] of windowed x35
763
764 smull r0, lr, r11, r10 @ r7..lr = (window_l[8] * (x[26] == x[27]))
765 ldr r11, =WL16 @ r11 = window_l[16]
766 ldr r12, =WL17 @ r12 = window_l[17]
767 movs r0, r0, lsr #28
768 adc r0, r0, lr, lsl #4 @ r0 = bits[59..28] of windowed x27
769
770
771 stmia r1, { r0, r2 - r9 } @ store windowed x[27] .. x[35]
772 ldmdb r1!, { r0, r2 - r9 } @ load 9 words downto (and including) x18
773
774
775 smull r10, lr, r12, r0 @ r10..lr = (window_l[17] * x[18])
776 movs r10, r10, lsr #28
777 adc r0, r10, lr, lsl #4 @ r0 = bits[59..28] of windowed x0
778
779 smull r10, lr, r11, r2 @ r10..lr = (window_l[16] * x[19])
780 ldr r11, =WL14 @ r11 = window_l[14]
781 ldr r12, =WL15 @ r12 = window_l[15]
782 movs r10, r10, lsr #28
783 adc r2, r10, lr, lsl #4 @ r2 = bits[59..28] of windowed x1
784
785 smull r10, lr, r12, r3 @ r10..lr = (window_l[15] * x[20])
786 movs r10, r10, lsr #28
787 adc r3, r10, lr, lsl #4 @ r3 = bits[59..28] of windowed x2
788
789 smull r10, lr, r11, r4 @ r10..lr = (window_l[14] * x[21])
790 ldr r11, =WL12 @ r11 = window_l[12]
791 ldr r12, =WL13 @ r12 = window_l[13]
792 movs r10, r10, lsr #28
793 adc r4, r10, lr, lsl #4 @ r4 = bits[59..28] of windowed x3
794
795 smull r10, lr, r12, r5 @ r10..lr = (window_l[13] * x[22])
796 movs r10, r10, lsr #28
797 adc r5, r10, lr, lsl #4 @ r5 = bits[59..28] of windowed x4
798
799 smull r10, lr, r11, r6 @ r10..lr = (window_l[12] * x[23])
800 ldr r11, =WL10 @ r12 = window_l[10]
801 ldr r12, =WL11 @ r12 = window_l[11]
802 movs r10, r10, lsr #28
803 adc r6, r10, lr, lsl #4 @ r6 = bits[59..28] of windowed x5
804
805 smull r10, lr, r12, r7 @ r10..lr = (window_l[11] * x[24])
806 movs r10, r10, lsr #28
807 adc r7, r10, lr, lsl #4 @ r7 = bits[59..28] of windowed x6
808
809 smull r10, lr, r11, r8 @ r10..lr = (window_l[10] * x[25])
810 ldr r12, =WL9 @ r12 = window_l[9]
811 movs r10, r10, lsr #28
812 adc r8, r10, lr, lsl #4 @ r8 = bits[59..28] of windowed x7
813
814 smull r10, lr, r12, r9 @ r10..lr = (window_l[9] * x[26])
815
816 movs r10, r10, lsr #28
817 adc r9, r10, lr, lsl #4 @ r9 = bits[59..28] of windowed x8
818
819 stmia r1, { r0, r2 - r9 } @ store windowed x[18] .. x[26]
820
821 @----
822 @ NB there are 2 possible exits from this function - this is only one of them
823 @----
824
825 add sp, sp, #(21*4) @ return stack frame
826 ldmia sp!, { r4 - r11, pc } @ restore callee saved regs, and return
827
828 @----
829
830
831stop_block_x0_to_x17:
832
833 @ r0 = x0
834 @ r1 = &x[9]
835 @ r2 = x1
836 @ r3 = x2
837 @ r4 = x3
838 @ r5 = x4
839 @ r6 = x5
840 @ r7 = x6
841 @ r8 = x7
842 @ r9 = x8
843 @ r10 = -x0
844 @ r11 = window mode: (0 == normal), (1 == start block), (3 == stop block)
845 @ r12 = .
846 @ lr = .
847
848 rsb r0, r6, #0 @ r0 = -x5
849 rsb r6, r2, #0 @ r6 = -x1
850 rsb r2, r5, #0 @ r2 = -x4
851 rsb r5, r3, #0 @ r5 = -x2
852 rsb r3, r4, #0 @ r3 = -x3
853
854 add r1, r1, #(3*4) @ r1 = &x[12]
855 stmia r1, { r0, r2, r3, r5, r6, r10 } @ store unchanged x[12] .. x[17]
856
857 ldr r0, =WL1 @ r0 = window_l[1] == window_s[0]
858
859 rsb r10, r9, #0 @ r10 = -x8
860 rsb r12, r8, #0 @ r12 = -x7
861 rsb lr, r7, #0 @ lr = -x6
862
863 @ r0 = WL1
864 @ r1 = &x[12]
865 @ r2 = .
866 @ r3 = .
867 @ r4 = .
868 @ r5 = .
869 @ r6 = .
870 @ r7 = x6
871 @ r8 = x7
872 @ r9 = x8
873 @ r10 = -x8
874 @ r11 = window mode: (0 == normal), (1 == start block), (3 == stop block)
875 @ r12 = -x7
876 @ lr = -x6
877
878 smull r5, r6, r0, r7 @ r5..r6 = (window_l[1] * x[6])
879 ldr r2, =WL4 @ r2 = window_l[4] == window_s[1]
880 movs r5, r5, lsr #28
881 adc r7, r5, r6, lsl #4 @ r7 = bits[59..28] of windowed x6
882
883 smull r5, r6, r2, r8 @ r5..r6 = (window_l[4] * x[7])
884 ldr r3, =WL7 @ r3 = window_l[7] == window_s[2]
885 movs r5, r5, lsr #28
886 adc r8, r5, r6, lsl #4 @ r8 = bits[59..28] of windowed x7
887
888 smull r5, r6, r3, r9 @ r5..r6 = (window_l[7] * x[8])
889 ldr r4, =WL10 @ r4 = window_l[10] == window_s[3]
890 movs r5, r5, lsr #28
891 adc r9, r5, r6, lsl #4 @ r9 = bits[59..28] of windowed x8
892
893 smull r5, r6, r4, r10 @ r5..r6 = (window_l[10] * (x[9] == -x[8]))
894 ldr r0, =WL13 @ r0 = window_l[13] == window_s[4]
895 movs r5, r5, lsr #28
896 adc r10, r5, r6, lsl #4 @ r10 = bits[59..28] of windowed x9
897
898 smull r5, r6, r0, r12 @ r5..r6 = (window_l[13] * (x[10] == -x[7]))
899 ldr r2, =WL16 @ r2 = window_l[16] == window_s[5]
900 movs r5, r5, lsr #28
901 adc r12, r5, r6, lsl #4 @ r10 = bits[59..28] of windowed x9
902
903 smull r5, r6, r2, lr @ r5..r6 = (window_l[16] * (x[11] == -x[6]))
904
905 ldr r0, =0x00
906
907 movs r5, r5, lsr #28
908 adc lr, r5, r6, lsl #4 @ r10 = bits[59..28] of windowed x9
909
910 stmdb r1!, { r7 - r10, r12, lr } @ store windowed x[6] .. x[11]
911
912 ldr r5, =0x00
913 ldr r6, =0x00
914 ldr r2, =0x00
915 ldr r3, =0x00
916 ldr r4, =0x00
917
918 stmdb r1!, { r0, r2 - r6 } @ store windowed x[0] .. x[5]
919
920 b normal_block_x18_to_x35
921
922
923 @----
924
925
926start_block_x18_to_x35:
927
928 ldr r4, =WL1 @ r0 = window_l[1] == window_s[0]
929
930 add r1, r1, #(24*4) @ r1 = &x[24]
931
932 ldmia r1, { r0, r2, r3 } @ load 3 words from x24, dont update pointer
933
934 @ r0 = x24
935 @ r1 = &x[24]
936 @ r2 = x25
937 @ r3 = x26
938 @ r4 = WL1
939 @ r5 = WL4
940 @ r6 = WL7
941 @ r7 = WL10
942 @ r8 = WL13
943 @ r9 = WL16
944 @ r10 = .
945 @ r11 = .
946 @ r12 = .
947 @ lr = .
948
949 ldr r5, =WL4 @ r5 = window_l[4] == window_s[1]
950
951 smull r10, r11, r4, r0 @ r10..r11 = (window_l[1] * (x[24] == x[29]))
952 ldr r6, =WL7 @ r6 = window_l[7] == window_s[2]
953 movs r10, r10, lsr #28
954 adc lr, r10, r11, lsl #4 @ lr = bits[59..28] of windowed x29
955
956 smull r10, r11, r5, r2 @ r10..r11 = (window_l[4] * (x[25] == x[28]))
957 ldr r7, =WL10 @ r7 = window_l[10] == window_s[3]
958 movs r10, r10, lsr #28
959 adc r12, r10, r11, lsl #4 @ r12 = bits[59..28] of windowed x28
960
961 smull r10, r11, r6, r3 @ r10..r11 = (window_l[7] * (x[26] == x[27]))
962 ldr r8, =WL13 @ r8 = window_l[13] == window_s[4]
963 movs r10, r10, lsr #28
964 adc r4, r10, r11, lsl #4 @ r4 = bits[59..28] of windowed x27
965
966 smull r10, r11, r7, r3 @ r10..r11 = (window_l[10] * x[26])
967 ldr r9, =WL16 @ r9 = window_l[16] == window_s[5]
968 movs r10, r10, lsr #28
969 adc r3, r10, r11, lsl #4 @ r3 = bits[59..28] of windowed x26
970
971 smull r10, r11, r8, r2 @ r10..r11 = (window_l[13] * x[25])
972 ldr r5, =0x00
973 movs r10, r10, lsr #28
974 adc r2, r10, r11, lsl #4 @ r2 = bits[59..28] of windowed x25
975
976 smull r10, r11, r9, r0 @ r10..r11 = (window_l[16] * x[24])
977 ldr r6, =0x00
978 movs r10, r10, lsr #28
979 adc r0, r10, r11, lsl #4 @ r0 = bits[59..28] of windowed x24
980
981 stmia r1!, { r0, r2, r3, r4, r12, lr } @ store windowed x[24] .. x[29]
982
983 ldr r7, =0x00
984 ldr r8, =0x00
985 ldr r9, =0x00
986 ldr r10, =0x00
987
988 stmia r1!, { r5 - r10 } @ store windowed x[30] .. x[35]
989
990 @----
991 @ NB there are 2 possible exits from this function - this is only one of them
992 @----
993
994 add sp, sp, #(21*4) @ return stack frame
995 ldmia sp!, { r4 - r11, pc } @ restore callee saved regs, and return
996
997 @----
998 @END
999 @----
1000
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 @@
1/*
2 * mad - MPEG audio decoder
3 * Copyright (C) 2000-2001 Robert Leslie
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * $Id$
20 */
21
22 /* 0 */ { MAD_F(0x09bd7ca0) /* 0.608761429 */,
23 -MAD_F(0x0ec835e8) /* -0.923879533 */,
24 -MAD_F(0x0216a2a2) /* -0.130526192 */,
25 MAD_F(0x0fdcf549) /* 0.991444861 */,
26 -MAD_F(0x061f78aa) /* -0.382683432 */,
27 -MAD_F(0x0cb19346) /* -0.793353340 */ },
28
29 /* 6 */ { -MAD_F(0x0cb19346) /* -0.793353340 */,
30 MAD_F(0x061f78aa) /* 0.382683432 */,
31 MAD_F(0x0fdcf549) /* 0.991444861 */,
32 MAD_F(0x0216a2a2) /* 0.130526192 */,
33 -MAD_F(0x0ec835e8) /* -0.923879533 */,
34 -MAD_F(0x09bd7ca0) /* -0.608761429 */ },
35
36 /* 1 */ { MAD_F(0x061f78aa) /* 0.382683432 */,
37 -MAD_F(0x0ec835e8) /* -0.923879533 */,
38 MAD_F(0x0ec835e8) /* 0.923879533 */,
39 -MAD_F(0x061f78aa) /* -0.382683432 */,
40 -MAD_F(0x061f78aa) /* -0.382683432 */,
41 MAD_F(0x0ec835e8) /* 0.923879533 */ },
42
43 /* 7 */ { -MAD_F(0x0ec835e8) /* -0.923879533 */,
44 -MAD_F(0x061f78aa) /* -0.382683432 */,
45 MAD_F(0x061f78aa) /* 0.382683432 */,
46 MAD_F(0x0ec835e8) /* 0.923879533 */,
47 MAD_F(0x0ec835e8) /* 0.923879533 */,
48 MAD_F(0x061f78aa) /* 0.382683432 */ },
49
50 /* 2 */ { MAD_F(0x0216a2a2) /* 0.130526192 */,
51 -MAD_F(0x061f78aa) /* -0.382683432 */,
52 MAD_F(0x09bd7ca0) /* 0.608761429 */,
53 -MAD_F(0x0cb19346) /* -0.793353340 */,
54 MAD_F(0x0ec835e8) /* 0.923879533 */,
55 -MAD_F(0x0fdcf549) /* -0.991444861 */ },
56
57 /* 8 */ { -MAD_F(0x0fdcf549) /* -0.991444861 */,
58 -MAD_F(0x0ec835e8) /* -0.923879533 */,
59 -MAD_F(0x0cb19346) /* -0.793353340 */,
60 -MAD_F(0x09bd7ca0) /* -0.608761429 */,
61 -MAD_F(0x061f78aa) /* -0.382683432 */,
62 -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 @@
1/*
2 * mad - MPEG audio decoder
3 * Copyright (C) 2000-2001 Robert Leslie
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * $Id$
20 */
21
22# ifdef HAVE_CONFIG_H
23# include "libmad_config.h"
24# endif
25
26# include "libmad_global.h"
27
28# ifdef HAVE_LIMITS_H
29# include <limits.h>
30# else
31# define CHAR_BIT 8
32# endif
33
34# include "fixed.h"
35# include "bit.h"
36# include "stream.h"
37# include "frame.h"
38# include "layer12.h"
39
40/*
41 * scalefactor table
42 * used in both Layer I and Layer II decoding
43 */
44static
45mad_fixed_t const sf_table[63] = {
46# include "sf_table.dat"
47};
48
49/* --- Layer I ------------------------------------------------------------- */
50
51/* linear scaling table */
52static
53mad_fixed_t const linear_table[14] = {
54 MAD_F(0x15555555), /* 2^2 / (2^2 - 1) == 1.33333333333333 */
55 MAD_F(0x12492492), /* 2^3 / (2^3 - 1) == 1.14285714285714 */
56 MAD_F(0x11111111), /* 2^4 / (2^4 - 1) == 1.06666666666667 */
57 MAD_F(0x10842108), /* 2^5 / (2^5 - 1) == 1.03225806451613 */
58 MAD_F(0x10410410), /* 2^6 / (2^6 - 1) == 1.01587301587302 */
59 MAD_F(0x10204081), /* 2^7 / (2^7 - 1) == 1.00787401574803 */
60 MAD_F(0x10101010), /* 2^8 / (2^8 - 1) == 1.00392156862745 */
61 MAD_F(0x10080402), /* 2^9 / (2^9 - 1) == 1.00195694716243 */
62 MAD_F(0x10040100), /* 2^10 / (2^10 - 1) == 1.00097751710655 */
63 MAD_F(0x10020040), /* 2^11 / (2^11 - 1) == 1.00048851978505 */
64 MAD_F(0x10010010), /* 2^12 / (2^12 - 1) == 1.00024420024420 */
65 MAD_F(0x10008004), /* 2^13 / (2^13 - 1) == 1.00012208521548 */
66 MAD_F(0x10004001), /* 2^14 / (2^14 - 1) == 1.00006103888177 */
67 MAD_F(0x10002000) /* 2^15 / (2^15 - 1) == 1.00003051850948 */
68};
69
70/*
71 * NAME:I_sample()
72 * DESCRIPTION:decode one requantized Layer I sample from a bitstream
73 */
74static
75mad_fixed_t I_sample(struct mad_bitptr *ptr, unsigned int nb)
76{
77 mad_fixed_t sample;
78
79 sample = mad_bit_read(ptr, nb);
80
81 /* invert most significant bit, extend sign, then scale to fixed format */
82
83 sample ^= 1 << (nb - 1);
84 sample |= -(sample & (1 << (nb - 1)));
85
86 sample <<= MAD_F_FRACBITS - (nb - 1);
87
88 /* requantize the sample */
89
90 /* s'' = (2^nb / (2^nb - 1)) * (s''' + 2^(-nb + 1)) */
91
92 sample += MAD_F_ONE >> (nb - 1);
93
94 return mad_f_mul(sample, linear_table[nb - 2]);
95
96 /* s' = factor * s'' */
97 /* (to be performed by caller) */
98}
99
100/*
101 * NAME:layer->I()
102 * DESCRIPTION:decode a single Layer I frame
103 */
104int mad_layer_I(struct mad_stream *stream, struct mad_frame *frame)
105{
106 struct mad_header *header = &frame->header;
107 unsigned int nch, bound, ch, s, sb, nb;
108 unsigned char allocation[2][32], scalefactor[2][32];
109
110 nch = MAD_NCHANNELS(header);
111
112 bound = 32;
113 if (header->mode == MAD_MODE_JOINT_STEREO) {
114 header->flags |= MAD_FLAG_I_STEREO;
115 bound = 4 + header->mode_extension * 4;
116 }
117
118 /* check CRC word */
119
120 if (header->flags & MAD_FLAG_PROTECTION) {
121 header->crc_check =
122 mad_bit_crc(stream->ptr, 4 * (bound * nch + (32 - bound)),
123 header->crc_check);
124
125 if (header->crc_check != header->crc_target &&
126 !(frame->options & MAD_OPTION_IGNORECRC)) {
127 stream->error = MAD_ERROR_BADCRC;
128 return -1;
129 }
130 }
131
132 /* decode bit allocations */
133
134 for (sb = 0; sb < bound; ++sb) {
135 for (ch = 0; ch < nch; ++ch) {
136 nb = mad_bit_read(&stream->ptr, 4);
137
138 if (nb == 15) {
139 stream->error = MAD_ERROR_BADBITALLOC;
140 return -1;
141 }
142
143 allocation[ch][sb] = nb ? nb + 1 : 0;
144 }
145 }
146
147 for (sb = bound; sb < 32; ++sb) {
148 nb = mad_bit_read(&stream->ptr, 4);
149
150 if (nb == 15) {
151 stream->error = MAD_ERROR_BADBITALLOC;
152 return -1;
153 }
154
155 allocation[0][sb] =
156 allocation[1][sb] = nb ? nb + 1 : 0;
157 }
158
159 /* decode scalefactors */
160
161 for (sb = 0; sb < 32; ++sb) {
162 for (ch = 0; ch < nch; ++ch) {
163 if (allocation[ch][sb]) {
164 scalefactor[ch][sb] = mad_bit_read(&stream->ptr, 6);
165
166 if (scalefactor[ch][sb] == 63) {
167 stream->error = MAD_ERROR_BADSCALEFACTOR;
168 return -1;
169 }
170 }
171 }
172 }
173
174 /* decode samples */
175
176 for (s = 0; s < 12; ++s) {
177 for (sb = 0; sb < bound; ++sb) {
178 for (ch = 0; ch < nch; ++ch) {
179 nb = allocation[ch][sb];
180 frame->sbsample[ch][s][sb] = nb ?
181 mad_f_mul(I_sample(&stream->ptr, nb),
182 sf_table[scalefactor[ch][sb]]) : 0;
183 }
184 }
185
186 for (sb = bound; sb < 32; ++sb) {
187 if ((nb = allocation[0][sb])) {
188 mad_fixed_t sample;
189
190 sample = I_sample(&stream->ptr, nb);
191
192 for (ch = 0; ch < nch; ++ch) {
193 frame->sbsample[ch][s][sb] =
194 mad_f_mul(sample, sf_table[scalefactor[ch][sb]]);
195 }
196 }
197 else {
198 for (ch = 0; ch < nch; ++ch)
199 frame->sbsample[ch][s][sb] = 0;
200 }
201 }
202 }
203
204 return 0;
205}
206
207/* --- Layer II ------------------------------------------------------------ */
208
209/* possible quantization per subband table */
210static
211struct {
212 unsigned int sblimit;
213 unsigned char const offsets[30];
214} const sbquant_table[5] = {
215 /* ISO/IEC 11172-3 Table B.2a */
216 { 27, { 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3,/* 0 */
217 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0 } },
218 /* ISO/IEC 11172-3 Table B.2b */
219 { 30, { 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3,/* 1 */
220 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0 } },
221 /* ISO/IEC 11172-3 Table B.2c */
222 { 8, { 5, 5, 2, 2, 2, 2, 2, 2 } }, /* 2 */
223 /* ISO/IEC 11172-3 Table B.2d */
224 { 12, { 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 } }, /* 3 */
225 /* ISO/IEC 13818-3 Table B.1 */
226 { 30, { 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1,/* 4 */
227 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } }
228};
229
230/* bit allocation table */
231static
232struct {
233 unsigned short nbal;
234 unsigned short offset;
235} const bitalloc_table[8] = {
236 { 2, 0 }, /* 0 */
237 { 2, 3 }, /* 1 */
238 { 3, 3 }, /* 2 */
239 { 3, 1 }, /* 3 */
240 { 4, 2 }, /* 4 */
241 { 4, 3 }, /* 5 */
242 { 4, 4 }, /* 6 */
243 { 4, 5 } /* 7 */
244};
245
246/* offsets into quantization class table */
247static
248unsigned char const offset_table[6][15] = {
249 { 0, 1, 16 }, /* 0 */
250 { 0, 1, 2, 3, 4, 5, 16 }, /* 1 */
251 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }, /* 2 */
252 { 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, /* 3 */
253 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16 }, /* 4 */
254 { 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 } /* 5 */
255};
256
257/* quantization class table */
258static
259struct quantclass {
260 unsigned short nlevels;
261 unsigned char group;
262 unsigned char bits;
263 mad_fixed_t C;
264 mad_fixed_t D;
265} const qc_table[17] = {
266# include "qc_table.dat"
267};
268
269/*
270 * NAME:II_samples()
271 * DESCRIPTION:decode three requantized Layer II samples from a bitstream
272 */
273static
274void II_samples(struct mad_bitptr *ptr,
275 struct quantclass const *quantclass,
276 mad_fixed_t output[3])
277{
278 unsigned int nb, s, sample[3];
279
280 if ((nb = quantclass->group)) {
281 unsigned int c, nlevels;
282
283 /* degrouping */
284 c = mad_bit_read(ptr, quantclass->bits);
285 nlevels = quantclass->nlevels;
286
287 for (s = 0; s < 3; ++s) {
288 sample[s] = c % nlevels;
289 c /= nlevels;
290 }
291 }
292 else {
293 nb = quantclass->bits;
294
295 for (s = 0; s < 3; ++s)
296 sample[s] = mad_bit_read(ptr, nb);
297 }
298
299 for (s = 0; s < 3; ++s) {
300 mad_fixed_t requantized;
301
302 /* invert most significant bit, extend sign, then scale to fixed format */
303
304 requantized = sample[s] ^ (1 << (nb - 1));
305 requantized |= -(requantized & (1 << (nb - 1)));
306
307 requantized <<= MAD_F_FRACBITS - (nb - 1);
308
309 /* requantize the sample */
310
311 /* s'' = C * (s''' + D) */
312
313 output[s] = mad_f_mul(requantized + quantclass->D, quantclass->C);
314
315 /* s' = factor * s'' */
316 /* (to be performed by caller) */
317 }
318}
319
320/*
321 * NAME:layer->II()
322 * DESCRIPTION:decode a single Layer II frame
323 */
324int mad_layer_II(struct mad_stream *stream, struct mad_frame *frame)
325{
326 struct mad_header *header = &frame->header;
327 struct mad_bitptr start;
328 unsigned int index, sblimit, nbal, nch, bound, gr, ch, s, sb;
329 unsigned char const *offsets;
330 unsigned char allocation[2][32], scfsi[2][32], scalefactor[2][32][3];
331 mad_fixed_t samples[3];
332
333 nch = MAD_NCHANNELS(header);
334
335 if (header->flags & MAD_FLAG_LSF_EXT)
336 index = 4;
337 else {
338 switch (nch == 2 ? header->bitrate / 2 : header->bitrate) {
339 case 32000:
340 case 48000:
341 index = (header->samplerate == 32000) ? 3 : 2;
342 break;
343
344 case 56000:
345 case 64000:
346 case 80000:
347 index = 0;
348 break;
349
350 default:
351 index = (header->samplerate == 48000) ? 0 : 1;
352 }
353 }
354
355 sblimit = sbquant_table[index].sblimit;
356 offsets = sbquant_table[index].offsets;
357
358 bound = 32;
359 if (header->mode == MAD_MODE_JOINT_STEREO) {
360 header->flags |= MAD_FLAG_I_STEREO;
361 bound = 4 + header->mode_extension * 4;
362 }
363
364 if (bound > sblimit)
365 bound = sblimit;
366
367 start = stream->ptr;
368
369 /* decode bit allocations */
370
371 for (sb = 0; sb < bound; ++sb) {
372 nbal = bitalloc_table[offsets[sb]].nbal;
373
374 for (ch = 0; ch < nch; ++ch)
375 allocation[ch][sb] = mad_bit_read(&stream->ptr, nbal);
376 }
377
378 for (sb = bound; sb < sblimit; ++sb) {
379 nbal = bitalloc_table[offsets[sb]].nbal;
380
381 allocation[0][sb] =
382 allocation[1][sb] = mad_bit_read(&stream->ptr, nbal);
383 }
384
385 /* decode scalefactor selection info */
386
387 for (sb = 0; sb < sblimit; ++sb) {
388 for (ch = 0; ch < nch; ++ch) {
389 if (allocation[ch][sb])
390 scfsi[ch][sb] = mad_bit_read(&stream->ptr, 2);
391 }
392 }
393
394 /* check CRC word */
395
396 if (header->flags & MAD_FLAG_PROTECTION) {
397 header->crc_check =
398 mad_bit_crc(start, mad_bit_length(&start, &stream->ptr),
399 header->crc_check);
400
401 if (header->crc_check != header->crc_target &&
402 !(frame->options & MAD_OPTION_IGNORECRC)) {
403 stream->error = MAD_ERROR_BADCRC;
404 return -1;
405 }
406 }
407
408 /* decode scalefactors */
409
410 for (sb = 0; sb < sblimit; ++sb) {
411 for (ch = 0; ch < nch; ++ch) {
412 if (allocation[ch][sb]) {
413 scalefactor[ch][sb][0] = mad_bit_read(&stream->ptr, 6);
414
415 switch (scfsi[ch][sb]) {
416 case 2:
417 scalefactor[ch][sb][2] =
418 scalefactor[ch][sb][1] =
419 scalefactor[ch][sb][0];
420 break;
421
422 case 0:
423 scalefactor[ch][sb][1] = mad_bit_read(&stream->ptr, 6);
424 /* fall through */
425
426 case 1:
427 case 3:
428 scalefactor[ch][sb][2] = mad_bit_read(&stream->ptr, 6);
429 }
430
431 if (scfsi[ch][sb] & 1)
432 scalefactor[ch][sb][1] = scalefactor[ch][sb][scfsi[ch][sb] - 1];
433
434 if (scalefactor[ch][sb][0] == 63 ||
435 scalefactor[ch][sb][1] == 63 ||
436 scalefactor[ch][sb][2] == 63) {
437 stream->error = MAD_ERROR_BADSCALEFACTOR;
438 return -1;
439 }
440 }
441 }
442 }
443
444 /* decode samples */
445
446 for (gr = 0; gr < 12; ++gr) {
447 for (sb = 0; sb < bound; ++sb) {
448 for (ch = 0; ch < nch; ++ch) {
449 if ((index = allocation[ch][sb])) {
450 index = offset_table[bitalloc_table[offsets[sb]].offset][index - 1];
451
452 II_samples(&stream->ptr, &qc_table[index], samples);
453
454 for (s = 0; s < 3; ++s) {
455 frame->sbsample[ch][3 * gr + s][sb] =
456 mad_f_mul(samples[s], sf_table[scalefactor[ch][sb][gr / 4]]);
457 }
458 }
459 else {
460 for (s = 0; s < 3; ++s)
461 frame->sbsample[ch][3 * gr + s][sb] = 0;
462 }
463 }
464 }
465
466 for (sb = bound; sb < sblimit; ++sb) {
467 if ((index = allocation[0][sb])) {
468 index = offset_table[bitalloc_table[offsets[sb]].offset][index - 1];
469
470 II_samples(&stream->ptr, &qc_table[index], samples);
471
472 for (ch = 0; ch < nch; ++ch) {
473 for (s = 0; s < 3; ++s) {
474 frame->sbsample[ch][3 * gr + s][sb] =
475 mad_f_mul(samples[s], sf_table[scalefactor[ch][sb][gr / 4]]);
476 }
477 }
478 }
479 else {
480 for (ch = 0; ch < nch; ++ch) {
481 for (s = 0; s < 3; ++s)
482 frame->sbsample[ch][3 * gr + s][sb] = 0;
483 }
484 }
485 }
486
487 for (ch = 0; ch < nch; ++ch) {
488 for (s = 0; s < 3; ++s) {
489 for (sb = sblimit; sb < 32; ++sb)
490 frame->sbsample[ch][3 * gr + s][sb] = 0;
491 }
492 }
493 }
494
495 return 0;
496}
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 @@
1/*
2 * mad - MPEG audio decoder
3 * Copyright (C) 2000-2001 Robert Leslie
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * $Id$
20 */
21
22# ifndef LIBMAD_LAYER12_H
23# define LIBMAD_LAYER12_H
24
25# include "stream.h"
26# include "frame.h"
27
28int mad_layer_I(struct mad_stream *, struct mad_frame *);
29int mad_layer_II(struct mad_stream *, struct mad_frame *);
30
31# 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 @@
1/*
2 * mad - MPEG audio decoder
3 * Copyright (C) 2000-2001 Robert Leslie
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * $Id$
20 */
21
22# ifdef HAVE_CONFIG_H
23# include "libmad_config.h"
24# endif
25
26# include "libmad_global.h"
27
28# include <stdlib.h>
29# include <string.h>
30# include <assert.h>
31
32# ifdef HAVE_LIMITS_H
33# include <limits.h>
34# else
35# define CHAR_BIT 8
36# endif
37
38# include "fixed.h"
39# include "bit.h"
40# include "stream.h"
41# include "frame.h"
42# include "huffman.h"
43# include "layer3.h"
44
45/* --- Layer III ----------------------------------------------------------- */
46
47enum {
48 count1table_select = 0x01,
49 scalefac_scale = 0x02,
50 preflag = 0x04,
51 mixed_block_flag = 0x08
52};
53
54struct sideinfo {
55 unsigned int main_data_begin;
56 unsigned int private_bits;
57
58 unsigned char scfsi[2];
59
60 struct granule {
61 struct channel {
62 /* from side info */
63 unsigned short part2_3_length;
64 unsigned short big_values;
65 unsigned short global_gain;
66 unsigned short scalefac_compress;
67
68 unsigned char flags;
69 unsigned char block_type;
70 unsigned char table_select[3];
71 unsigned char subblock_gain[3];
72 unsigned char region0_count;
73 unsigned char region1_count;
74
75 /* from main_data */
76 unsigned char scalefac[39];/* scalefac_l and/or scalefac_s */
77 } ch[2];
78 } gr[2];
79};
80
81/*
82 * scalefactor bit lengths
83 * derived from section 2.4.2.7 of ISO/IEC 11172-3
84 */
85static
86struct {
87 unsigned char slen1;
88 unsigned char slen2;
89} const sflen_table[16] = {
90 { 0, 0 }, { 0, 1 }, { 0, 2 }, { 0, 3 },
91 { 3, 0 }, { 1, 1 }, { 1, 2 }, { 1, 3 },
92 { 2, 1 }, { 2, 2 }, { 2, 3 }, { 3, 1 },
93 { 3, 2 }, { 3, 3 }, { 4, 2 }, { 4, 3 }
94};
95
96/*
97 * number of LSF scalefactor band values
98 * derived from section 2.4.3.2 of ISO/IEC 13818-3
99 */
100static
101unsigned char const nsfb_table[6][3][4] = {
102 { { 6, 5, 5, 5 },
103 { 9, 9, 9, 9 },
104 { 6, 9, 9, 9 } },
105
106 { { 6, 5, 7, 3 },
107 { 9, 9, 12, 6 },
108 { 6, 9, 12, 6 } },
109
110 { { 11, 10, 0, 0 },
111 { 18, 18, 0, 0 },
112 { 15, 18, 0, 0 } },
113
114 { { 7, 7, 7, 0 },
115 { 12, 12, 12, 0 },
116 { 6, 15, 12, 0 } },
117
118 { { 6, 6, 6, 3 },
119 { 12, 9, 9, 6 },
120 { 6, 12, 9, 6 } },
121
122 { { 8, 8, 5, 0 },
123 { 15, 12, 9, 0 },
124 { 6, 18, 9, 0 } }
125};
126
127/*
128 * MPEG-1 scalefactor band widths
129 * derived from Table B.8 of ISO/IEC 11172-3
130 */
131static
132unsigned char const sfb_48000_long[] = {
133 4, 4, 4, 4, 4, 4, 6, 6, 6, 8, 10,
134 12, 16, 18, 22, 28, 34, 40, 46, 54, 54, 192
135};
136
137static
138unsigned char const sfb_44100_long[] = {
139 4, 4, 4, 4, 4, 4, 6, 6, 8, 8, 10,
140 12, 16, 20, 24, 28, 34, 42, 50, 54, 76, 158
141};
142
143static
144unsigned char const sfb_32000_long[] = {
145 4, 4, 4, 4, 4, 4, 6, 6, 8, 10, 12,
146 16, 20, 24, 30, 38, 46, 56, 68, 84, 102, 26
147};
148
149static
150unsigned char const sfb_48000_short[] = {
151 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6,
152 6, 6, 6, 6, 6, 10, 10, 10, 12, 12, 12, 14, 14,
153 14, 16, 16, 16, 20, 20, 20, 26, 26, 26, 66, 66, 66
154};
155
156static
157unsigned char const sfb_44100_short[] = {
158 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6,
159 6, 6, 8, 8, 8, 10, 10, 10, 12, 12, 12, 14, 14,
160 14, 18, 18, 18, 22, 22, 22, 30, 30, 30, 56, 56, 56
161};
162
163static
164unsigned char const sfb_32000_short[] = {
165 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6,
166 6, 6, 8, 8, 8, 12, 12, 12, 16, 16, 16, 20, 20,
167 20, 26, 26, 26, 34, 34, 34, 42, 42, 42, 12, 12, 12
168};
169
170static
171unsigned char const sfb_48000_mixed[] = {
172 /* long */ 4, 4, 4, 4, 4, 4, 6, 6,
173 /* short */ 4, 4, 4, 6, 6, 6, 6, 6, 6, 10,
174 10, 10, 12, 12, 12, 14, 14, 14, 16, 16,
175 16, 20, 20, 20, 26, 26, 26, 66, 66, 66
176};
177
178static
179unsigned char const sfb_44100_mixed[] = {
180 /* long */ 4, 4, 4, 4, 4, 4, 6, 6,
181 /* short */ 4, 4, 4, 6, 6, 6, 8, 8, 8, 10,
182 10, 10, 12, 12, 12, 14, 14, 14, 18, 18,
183 18, 22, 22, 22, 30, 30, 30, 56, 56, 56
184};
185
186static
187unsigned char const sfb_32000_mixed[] = {
188 /* long */ 4, 4, 4, 4, 4, 4, 6, 6,
189 /* short */ 4, 4, 4, 6, 6, 6, 8, 8, 8, 12,
190 12, 12, 16, 16, 16, 20, 20, 20, 26, 26,
191 26, 34, 34, 34, 42, 42, 42, 12, 12, 12
192};
193
194/*
195 * MPEG-2 scalefactor band widths
196 * derived from Table B.2 of ISO/IEC 13818-3
197 */
198static
199unsigned char const sfb_24000_long[] = {
200 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16,
201 18, 22, 26, 32, 38, 46, 54, 62, 70, 76, 36
202};
203
204static
205unsigned char const sfb_22050_long[] = {
206 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16,
207 20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54
208};
209
210# define sfb_16000_long sfb_22050_long
211
212static
213unsigned char const sfb_24000_short[] = {
214 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 8,
215 8, 8, 10, 10, 10, 12, 12, 12, 14, 14, 14, 18, 18,
216 18, 24, 24, 24, 32, 32, 32, 44, 44, 44, 12, 12, 12
217};
218
219static
220unsigned char const sfb_22050_short[] = {
221 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 6,
222 6, 6, 8, 8, 8, 10, 10, 10, 14, 14, 14, 18, 18,
223 18, 26, 26, 26, 32, 32, 32, 42, 42, 42, 18, 18, 18
224};
225
226static
227unsigned char const sfb_16000_short[] = {
228 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 8,
229 8, 8, 10, 10, 10, 12, 12, 12, 14, 14, 14, 18, 18,
230 18, 24, 24, 24, 30, 30, 30, 40, 40, 40, 18, 18, 18
231};
232
233static
234unsigned char const sfb_24000_mixed[] = {
235 /* long */ 6, 6, 6, 6, 6, 6,
236 /* short */ 6, 6, 6, 8, 8, 8, 10, 10, 10, 12,
237 12, 12, 14, 14, 14, 18, 18, 18, 24, 24,
238 24, 32, 32, 32, 44, 44, 44, 12, 12, 12
239};
240
241static
242unsigned char const sfb_22050_mixed[] = {
243 /* long */ 6, 6, 6, 6, 6, 6,
244 /* short */ 6, 6, 6, 6, 6, 6, 8, 8, 8, 10,
245 10, 10, 14, 14, 14, 18, 18, 18, 26, 26,
246 26, 32, 32, 32, 42, 42, 42, 18, 18, 18
247};
248
249static
250unsigned char const sfb_16000_mixed[] = {
251 /* long */ 6, 6, 6, 6, 6, 6,
252 /* short */ 6, 6, 6, 8, 8, 8, 10, 10, 10, 12,
253 12, 12, 14, 14, 14, 18, 18, 18, 24, 24,
254 24, 30, 30, 30, 40, 40, 40, 18, 18, 18
255};
256
257/*
258 * MPEG 2.5 scalefactor band widths
259 * derived from public sources
260 */
261# define sfb_12000_long sfb_16000_long
262# define sfb_11025_long sfb_12000_long
263
264static
265unsigned char const sfb_8000_long[] = {
266 12, 12, 12, 12, 12, 12, 16, 20, 24, 28, 32,
267 40, 48, 56, 64, 76, 90, 2, 2, 2, 2, 2
268};
269
270# define sfb_12000_short sfb_16000_short
271# define sfb_11025_short sfb_12000_short
272
273static
274unsigned char const sfb_8000_short[] = {
275 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 16,
276 16, 16, 20, 20, 20, 24, 24, 24, 28, 28, 28, 36, 36,
277 36, 2, 2, 2, 2, 2, 2, 2, 2, 2, 26, 26, 26
278};
279
280# define sfb_12000_mixed sfb_16000_mixed
281# define sfb_11025_mixed sfb_12000_mixed
282
283/* the 8000 Hz short block scalefactor bands do not break after the first 36
284 frequency lines, so this is probably wrong */
285static
286unsigned char const sfb_8000_mixed[] = {
287 /* long */ 12, 12, 12,
288 /* short */ 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16,
289 20, 20, 20, 24, 24, 24, 28, 28, 28, 36, 36, 36,
290 2, 2, 2, 2, 2, 2, 2, 2, 2, 26, 26, 26
291};
292
293static
294struct {
295 unsigned char const *l;
296 unsigned char const *s;
297 unsigned char const *m;
298} const sfbwidth_table[9] = {
299 { sfb_48000_long, sfb_48000_short, sfb_48000_mixed },
300 { sfb_44100_long, sfb_44100_short, sfb_44100_mixed },
301 { sfb_32000_long, sfb_32000_short, sfb_32000_mixed },
302 { sfb_24000_long, sfb_24000_short, sfb_24000_mixed },
303 { sfb_22050_long, sfb_22050_short, sfb_22050_mixed },
304 { sfb_16000_long, sfb_16000_short, sfb_16000_mixed },
305 { sfb_12000_long, sfb_12000_short, sfb_12000_mixed },
306 { sfb_11025_long, sfb_11025_short, sfb_11025_mixed },
307 { sfb_8000_long, sfb_8000_short, sfb_8000_mixed }
308};
309
310/*
311 * scalefactor band preemphasis (used only when preflag is set)
312 * derived from Table B.6 of ISO/IEC 11172-3
313 */
314static
315unsigned char const pretab[22] = {
316 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3, 2, 0
317};
318
319/*
320 * table for requantization
321 *
322 * rq_table[x].mantissa * 2^(rq_table[x].exponent) = x^(4/3)
323 */
324static
325struct fixedfloat {
326 unsigned long mantissa : 27;
327 unsigned short exponent : 5;
328} const rq_table[8207] = {
329# include "rq_table.dat"
330};
331
332/*
333 * fractional powers of two
334 * used for requantization and joint stereo decoding
335 *
336 * root_table[3 + x] = 2^(x/4)
337 */
338static
339mad_fixed_t const root_table[7] = {
340 MAD_F(0x09837f05) /* 2^(-3/4) == 0.59460355750136 */,
341 MAD_F(0x0b504f33) /* 2^(-2/4) == 0.70710678118655 */,
342 MAD_F(0x0d744fcd) /* 2^(-1/4) == 0.84089641525371 */,
343 MAD_F(0x10000000) /* 2^( 0/4) == 1.00000000000000 */,
344 MAD_F(0x1306fe0a) /* 2^(+1/4) == 1.18920711500272 */,
345 MAD_F(0x16a09e66) /* 2^(+2/4) == 1.41421356237310 */,
346 MAD_F(0x1ae89f99) /* 2^(+3/4) == 1.68179283050743 */
347};
348
349/*
350 * coefficients for aliasing reduction
351 * derived from Table B.9 of ISO/IEC 11172-3
352 *
353 * c[] = { -0.6, -0.535, -0.33, -0.185, -0.095, -0.041, -0.0142, -0.0037 }
354 * cs[i] = 1 / sqrt(1 + c[i]^2)
355 * ca[i] = c[i] / sqrt(1 + c[i]^2)
356 */
357static
358mad_fixed_t const cs[8] = {
359 +MAD_F(0x0db84a81) /* +0.857492926 */, +MAD_F(0x0e1b9d7f) /* +0.881741997 */,
360 +MAD_F(0x0f31adcf) /* +0.949628649 */, +MAD_F(0x0fbba815) /* +0.983314592 */,
361 +MAD_F(0x0feda417) /* +0.995517816 */, +MAD_F(0x0ffc8fc8) /* +0.999160558 */,
362 +MAD_F(0x0fff964c) /* +0.999899195 */, +MAD_F(0x0ffff8d3) /* +0.999993155 */
363};
364
365static
366mad_fixed_t const ca[8] = {
367 -MAD_F(0x083b5fe7) /* -0.514495755 */, -MAD_F(0x078c36d2) /* -0.471731969 */,
368 -MAD_F(0x05039814) /* -0.313377454 */, -MAD_F(0x02e91dd1) /* -0.181913200 */,
369 -MAD_F(0x0183603a) /* -0.094574193 */, -MAD_F(0x00a7cb87) /* -0.040965583 */,
370 -MAD_F(0x003a2847) /* -0.014198569 */, -MAD_F(0x000f27b4) /* -0.003699975 */
371};
372
373/*
374 * IMDCT coefficients for short blocks
375 * derived from section 2.4.3.4.10.2 of ISO/IEC 11172-3
376 *
377 * imdct_s[i/even][k] = cos((PI / 24) * (2 * (i / 2) + 7) * (2 * k + 1))
378 * imdct_s[i /odd][k] = cos((PI / 24) * (2 * (6 + (i-1)/2) + 7) * (2 * k + 1))
379 */
380static
381mad_fixed_t const imdct_s[6][6] = {
382# include "imdct_s.dat"
383};
384
385# if !defined(ASO_IMDCT)
386/*
387 * windowing coefficients for long blocks
388 * derived from section 2.4.3.4.10.3 of ISO/IEC 11172-3
389 *
390 * window_l[i] = sin((PI / 36) * (i + 1/2))
391 */
392static
393mad_fixed_t const window_l[36] = {
394 MAD_F(0x00b2aa3e) /* 0.043619387 */, MAD_F(0x0216a2a2) /* 0.130526192 */,
395 MAD_F(0x03768962) /* 0.216439614 */, MAD_F(0x04cfb0e2) /* 0.300705800 */,
396 MAD_F(0x061f78aa) /* 0.382683432 */, MAD_F(0x07635284) /* 0.461748613 */,
397 MAD_F(0x0898c779) /* 0.537299608 */, MAD_F(0x09bd7ca0) /* 0.608761429 */,
398 MAD_F(0x0acf37ad) /* 0.675590208 */, MAD_F(0x0bcbe352) /* 0.737277337 */,
399 MAD_F(0x0cb19346) /* 0.793353340 */, MAD_F(0x0d7e8807) /* 0.843391446 */,
400
401 MAD_F(0x0e313245) /* 0.887010833 */, MAD_F(0x0ec835e8) /* 0.923879533 */,
402 MAD_F(0x0f426cb5) /* 0.953716951 */, MAD_F(0x0f9ee890) /* 0.976296007 */,
403 MAD_F(0x0fdcf549) /* 0.991444861 */, MAD_F(0x0ffc19fd) /* 0.999048222 */,
404 MAD_F(0x0ffc19fd) /* 0.999048222 */, MAD_F(0x0fdcf549) /* 0.991444861 */,
405 MAD_F(0x0f9ee890) /* 0.976296007 */, MAD_F(0x0f426cb5) /* 0.953716951 */,
406 MAD_F(0x0ec835e8) /* 0.923879533 */, MAD_F(0x0e313245) /* 0.887010833 */,
407
408 MAD_F(0x0d7e8807) /* 0.843391446 */, MAD_F(0x0cb19346) /* 0.793353340 */,
409 MAD_F(0x0bcbe352) /* 0.737277337 */, MAD_F(0x0acf37ad) /* 0.675590208 */,
410 MAD_F(0x09bd7ca0) /* 0.608761429 */, MAD_F(0x0898c779) /* 0.537299608 */,
411 MAD_F(0x07635284) /* 0.461748613 */, MAD_F(0x061f78aa) /* 0.382683432 */,
412 MAD_F(0x04cfb0e2) /* 0.300705800 */, MAD_F(0x03768962) /* 0.216439614 */,
413 MAD_F(0x0216a2a2) /* 0.130526192 */, MAD_F(0x00b2aa3e) /* 0.043619387 */,
414};
415# endif /* ASO_IMDCT */
416
417/*
418 * windowing coefficients for short blocks
419 * derived from section 2.4.3.4.10.3 of ISO/IEC 11172-3
420 *
421 * window_s[i] = sin((PI / 12) * (i + 1/2))
422 */
423static
424mad_fixed_t const window_s[12] = {
425 MAD_F(0x0216a2a2) /* 0.130526192 */, MAD_F(0x061f78aa) /* 0.382683432 */,
426 MAD_F(0x09bd7ca0) /* 0.608761429 */, MAD_F(0x0cb19346) /* 0.793353340 */,
427 MAD_F(0x0ec835e8) /* 0.923879533 */, MAD_F(0x0fdcf549) /* 0.991444861 */,
428 MAD_F(0x0fdcf549) /* 0.991444861 */, MAD_F(0x0ec835e8) /* 0.923879533 */,
429 MAD_F(0x0cb19346) /* 0.793353340 */, MAD_F(0x09bd7ca0) /* 0.608761429 */,
430 MAD_F(0x061f78aa) /* 0.382683432 */, MAD_F(0x0216a2a2) /* 0.130526192 */,
431};
432
433/*
434 * coefficients for intensity stereo processing
435 * derived from section 2.4.3.4.9.3 of ISO/IEC 11172-3
436 *
437 * is_ratio[i] = tan(i * (PI / 12))
438 * is_table[i] = is_ratio[i] / (1 + is_ratio[i])
439 */
440static
441mad_fixed_t const is_table[7] = {
442 MAD_F(0x00000000) /* 0.000000000 */,
443 MAD_F(0x0361962f) /* 0.211324865 */,
444 MAD_F(0x05db3d74) /* 0.366025404 */,
445 MAD_F(0x08000000) /* 0.500000000 */,
446 MAD_F(0x0a24c28c) /* 0.633974596 */,
447 MAD_F(0x0c9e69d1) /* 0.788675135 */,
448 MAD_F(0x10000000) /* 1.000000000 */
449};
450
451/*
452 * coefficients for LSF intensity stereo processing
453 * derived from section 2.4.3.2 of ISO/IEC 13818-3
454 *
455 * is_lsf_table[0][i] = (1 / sqrt(sqrt(2)))^(i + 1)
456 * is_lsf_table[1][i] = (1 / sqrt(2))^(i + 1)
457 */
458static
459mad_fixed_t const is_lsf_table[2][15] = {
460 {
461 MAD_F(0x0d744fcd) /* 0.840896415 */,
462 MAD_F(0x0b504f33) /* 0.707106781 */,
463 MAD_F(0x09837f05) /* 0.594603558 */,
464 MAD_F(0x08000000) /* 0.500000000 */,
465 MAD_F(0x06ba27e6) /* 0.420448208 */,
466 MAD_F(0x05a8279a) /* 0.353553391 */,
467 MAD_F(0x04c1bf83) /* 0.297301779 */,
468 MAD_F(0x04000000) /* 0.250000000 */,
469 MAD_F(0x035d13f3) /* 0.210224104 */,
470 MAD_F(0x02d413cd) /* 0.176776695 */,
471 MAD_F(0x0260dfc1) /* 0.148650889 */,
472 MAD_F(0x02000000) /* 0.125000000 */,
473 MAD_F(0x01ae89fa) /* 0.105112052 */,
474 MAD_F(0x016a09e6) /* 0.088388348 */,
475 MAD_F(0x01306fe1) /* 0.074325445 */
476 }, {
477 MAD_F(0x0b504f33) /* 0.707106781 */,
478 MAD_F(0x08000000) /* 0.500000000 */,
479 MAD_F(0x05a8279a) /* 0.353553391 */,
480 MAD_F(0x04000000) /* 0.250000000 */,
481 MAD_F(0x02d413cd) /* 0.176776695 */,
482 MAD_F(0x02000000) /* 0.125000000 */,
483 MAD_F(0x016a09e6) /* 0.088388348 */,
484 MAD_F(0x01000000) /* 0.062500000 */,
485 MAD_F(0x00b504f3) /* 0.044194174 */,
486 MAD_F(0x00800000) /* 0.031250000 */,
487 MAD_F(0x005a827a) /* 0.022097087 */,
488 MAD_F(0x00400000) /* 0.015625000 */,
489 MAD_F(0x002d413d) /* 0.011048543 */,
490 MAD_F(0x00200000) /* 0.007812500 */,
491 MAD_F(0x0016a09e) /* 0.005524272 */
492 }
493};
494
495/*
496 * NAME:III_sideinfo()
497 * DESCRIPTION:decode frame side information from a bitstream
498 */
499static
500enum mad_error III_sideinfo(struct mad_bitptr *ptr, unsigned int nch,
501 int lsf, struct sideinfo *si,
502 unsigned int *data_bitlen,
503 unsigned int *priv_bitlen)
504{
505 unsigned int ngr, gr, ch, i;
506 enum mad_error result = 0;
507
508 *data_bitlen = 0;
509 *priv_bitlen = lsf ? ((nch == 1) ? 1 : 2) : ((nch == 1) ? 5 : 3);
510
511 si->main_data_begin = mad_bit_read(ptr, lsf ? 8 : 9);
512 si->private_bits = mad_bit_read(ptr, *priv_bitlen);
513
514 ngr = 1;
515 if (!lsf) {
516 ngr = 2;
517
518 for (ch = 0; ch < nch; ++ch)
519 si->scfsi[ch] = mad_bit_read(ptr, 4);
520 }
521
522 for (gr = 0; gr < ngr; ++gr) {
523 struct granule *granule = &si->gr[gr];
524
525 for (ch = 0; ch < nch; ++ch) {
526 struct channel *channel = &granule->ch[ch];
527
528 channel->part2_3_length = mad_bit_read(ptr, 12);
529 channel->big_values = mad_bit_read(ptr, 9);
530 channel->global_gain = mad_bit_read(ptr, 8);
531 channel->scalefac_compress = mad_bit_read(ptr, lsf ? 9 : 4);
532
533 *data_bitlen += channel->part2_3_length;
534
535 if (channel->big_values > 288 && result == 0)
536 result = MAD_ERROR_BADBIGVALUES;
537
538 channel->flags = 0;
539
540 /* window_switching_flag */
541 if (mad_bit_read(ptr, 1)) {
542 channel->block_type = mad_bit_read(ptr, 2);
543
544 if (channel->block_type == 0 && result == 0)
545 result = MAD_ERROR_BADBLOCKTYPE;
546
547 if (!lsf && channel->block_type == 2 && si->scfsi[ch] && result == 0)
548 result = MAD_ERROR_BADSCFSI;
549
550 channel->region0_count = 7;
551 channel->region1_count = 36;
552
553 if (mad_bit_read(ptr, 1))
554 channel->flags |= mixed_block_flag;
555 else if (channel->block_type == 2)
556 channel->region0_count = 8;
557
558 for (i = 0; i < 2; ++i)
559 channel->table_select[i] = mad_bit_read(ptr, 5);
560
561# if defined(DEBUG)
562 channel->table_select[2] = 4; /* not used */
563# endif
564
565 for (i = 0; i < 3; ++i)
566 channel->subblock_gain[i] = mad_bit_read(ptr, 3);
567 }
568 else {
569 channel->block_type = 0;
570
571 for (i = 0; i < 3; ++i)
572 channel->table_select[i] = mad_bit_read(ptr, 5);
573
574 channel->region0_count = mad_bit_read(ptr, 4);
575 channel->region1_count = mad_bit_read(ptr, 3);
576 }
577
578 /* [preflag,] scalefac_scale, count1table_select */
579 channel->flags |= mad_bit_read(ptr, lsf ? 2 : 3);
580 }
581 }
582
583 return result;
584}
585
586/*
587 * NAME:III_scalefactors_lsf()
588 * DESCRIPTION:decode channel scalefactors for LSF from a bitstream
589 */
590static
591unsigned int III_scalefactors_lsf(struct mad_bitptr *ptr,
592 struct channel *channel,
593 struct channel *gr1ch, int mode_extension)
594{
595 struct mad_bitptr start;
596 unsigned int scalefac_compress, index, slen[4], part, n, i;
597 unsigned char const *nsfb;
598
599 start = *ptr;
600
601 scalefac_compress = channel->scalefac_compress;
602 index = (channel->block_type == 2) ?
603 ((channel->flags & mixed_block_flag) ? 2 : 1) : 0;
604
605 if (!((mode_extension & 0x1) && gr1ch)) {
606 if (scalefac_compress < 400) {
607 slen[0] = (scalefac_compress >> 4) / 5;
608 slen[1] = (scalefac_compress >> 4) % 5;
609 slen[2] = (scalefac_compress % 16) >> 2;
610 slen[3] = scalefac_compress % 4;
611
612 nsfb = nsfb_table[0][index];
613 }
614 else if (scalefac_compress < 500) {
615 scalefac_compress -= 400;
616
617 slen[0] = (scalefac_compress >> 2) / 5;
618 slen[1] = (scalefac_compress >> 2) % 5;
619 slen[2] = scalefac_compress % 4;
620 slen[3] = 0;
621
622 nsfb = nsfb_table[1][index];
623 }
624 else {
625 scalefac_compress -= 500;
626
627 slen[0] = scalefac_compress / 3;
628 slen[1] = scalefac_compress % 3;
629 slen[2] = 0;
630 slen[3] = 0;
631
632 channel->flags |= preflag;
633
634 nsfb = nsfb_table[2][index];
635 }
636
637 n = 0;
638 for (part = 0; part < 4; ++part) {
639 for (i = 0; i < nsfb[part]; ++i)
640 channel->scalefac[n++] = mad_bit_read(ptr, slen[part]);
641 }
642
643 while (n < 39)
644 channel->scalefac[n++] = 0;
645 }
646 else { /* (mode_extension & 0x1) && gr1ch (i.e. ch == 1) */
647 scalefac_compress >>= 1;
648
649 if (scalefac_compress < 180) {
650 slen[0] = scalefac_compress / 36;
651 slen[1] = (scalefac_compress % 36) / 6;
652 slen[2] = (scalefac_compress % 36) % 6;
653 slen[3] = 0;
654
655 nsfb = nsfb_table[3][index];
656 }
657 else if (scalefac_compress < 244) {
658 scalefac_compress -= 180;
659
660 slen[0] = (scalefac_compress % 64) >> 4;
661 slen[1] = (scalefac_compress % 16) >> 2;
662 slen[2] = scalefac_compress % 4;
663 slen[3] = 0;
664
665 nsfb = nsfb_table[4][index];
666 }
667 else {
668 scalefac_compress -= 244;
669
670 slen[0] = scalefac_compress / 3;
671 slen[1] = scalefac_compress % 3;
672 slen[2] = 0;
673 slen[3] = 0;
674
675 nsfb = nsfb_table[5][index];
676 }
677
678 n = 0;
679 for (part = 0; part < 4; ++part) {
680 unsigned int max, is_pos;
681
682 max = (1 << slen[part]) - 1;
683
684 for (i = 0; i < nsfb[part]; ++i) {
685 is_pos = mad_bit_read(ptr, slen[part]);
686
687 channel->scalefac[n] = is_pos;
688 gr1ch->scalefac[n++] = (is_pos == max);
689 }
690 }
691
692 while (n < 39) {
693 channel->scalefac[n] = 0;
694 gr1ch->scalefac[n++] = 0; /* apparently not illegal */
695 }
696 }
697
698 return mad_bit_length(&start, ptr);
699}
700
701/*
702 * NAME:III_scalefactors()
703 * DESCRIPTION:decode channel scalefactors of one granule from a bitstream
704 */
705static
706unsigned int III_scalefactors(struct mad_bitptr *ptr, struct channel *channel,
707 struct channel const *gr0ch, unsigned int scfsi)
708{
709 struct mad_bitptr start;
710 unsigned int slen1, slen2, sfbi;
711
712 start = *ptr;
713
714 slen1 = sflen_table[channel->scalefac_compress].slen1;
715 slen2 = sflen_table[channel->scalefac_compress].slen2;
716
717 if (channel->block_type == 2) {
718 unsigned int nsfb;
719
720 sfbi = 0;
721
722 nsfb = (channel->flags & mixed_block_flag) ? 8 + 3 * 3 : 6 * 3;
723 while (nsfb--)
724 channel->scalefac[sfbi++] = mad_bit_read(ptr, slen1);
725
726 nsfb = 6 * 3;
727 while (nsfb--)
728 channel->scalefac[sfbi++] = mad_bit_read(ptr, slen2);
729
730 nsfb = 1 * 3;
731 while (nsfb--)
732 channel->scalefac[sfbi++] = 0;
733 }
734 else { /* channel->block_type != 2 */
735 if (scfsi & 0x8) {
736 for (sfbi = 0; sfbi < 6; ++sfbi)
737 channel->scalefac[sfbi] = gr0ch->scalefac[sfbi];
738 }
739 else {
740 for (sfbi = 0; sfbi < 6; ++sfbi)
741 channel->scalefac[sfbi] = mad_bit_read(ptr, slen1);
742 }
743
744 if (scfsi & 0x4) {
745 for (sfbi = 6; sfbi < 11; ++sfbi)
746 channel->scalefac[sfbi] = gr0ch->scalefac[sfbi];
747 }
748 else {
749 for (sfbi = 6; sfbi < 11; ++sfbi)
750 channel->scalefac[sfbi] = mad_bit_read(ptr, slen1);
751 }
752
753 if (scfsi & 0x2) {
754 for (sfbi = 11; sfbi < 16; ++sfbi)
755 channel->scalefac[sfbi] = gr0ch->scalefac[sfbi];
756 }
757 else {
758 for (sfbi = 11; sfbi < 16; ++sfbi)
759 channel->scalefac[sfbi] = mad_bit_read(ptr, slen2);
760 }
761
762 if (scfsi & 0x1) {
763 for (sfbi = 16; sfbi < 21; ++sfbi)
764 channel->scalefac[sfbi] = gr0ch->scalefac[sfbi];
765 }
766 else {
767 for (sfbi = 16; sfbi < 21; ++sfbi)
768 channel->scalefac[sfbi] = mad_bit_read(ptr, slen2);
769 }
770
771 channel->scalefac[21] = 0;
772 }
773
774 return mad_bit_length(&start, ptr);
775}
776
777/*
778 * NAME:III_exponents()
779 * DESCRIPTION:calculate scalefactor exponents
780 */
781static
782void III_exponents(struct channel const *channel,
783 unsigned char const *sfbwidth, signed int exponents[39])
784{
785 signed int gain;
786 unsigned int scalefac_multiplier, sfbi;
787
788 gain = (signed int) channel->global_gain - 210;
789 scalefac_multiplier = (channel->flags & scalefac_scale) ? 2 : 1;
790
791 if (channel->block_type == 2) {
792 unsigned int l;
793 signed int gain0, gain1, gain2;
794
795 sfbi = l = 0;
796
797 if (channel->flags & mixed_block_flag) {
798 unsigned int premask;
799
800 premask = (channel->flags & preflag) ? ~0 : 0;
801
802 /* long block subbands 0-1 */
803
804 while (l < 36) {
805 exponents[sfbi] = gain -
806 (signed int) ((channel->scalefac[sfbi] + (pretab[sfbi] & premask)) <<
807 scalefac_multiplier);
808
809 l += sfbwidth[sfbi++];
810 }
811 }
812
813 /* this is probably wrong for 8000 Hz short/mixed blocks */
814
815 gain0 = gain - 8 * (signed int) channel->subblock_gain[0];
816 gain1 = gain - 8 * (signed int) channel->subblock_gain[1];
817 gain2 = gain - 8 * (signed int) channel->subblock_gain[2];
818
819 while (l < 576) {
820 exponents[sfbi + 0] = gain0 -
821 (signed int) (channel->scalefac[sfbi + 0] << scalefac_multiplier);
822 exponents[sfbi + 1] = gain1 -
823 (signed int) (channel->scalefac[sfbi + 1] << scalefac_multiplier);
824 exponents[sfbi + 2] = gain2 -
825 (signed int) (channel->scalefac[sfbi + 2] << scalefac_multiplier);
826
827 l += 3 * sfbwidth[sfbi];
828 sfbi += 3;
829 }
830 }
831 else { /* channel->block_type != 2 */
832 if (channel->flags & preflag) {
833 for (sfbi = 0; sfbi < 22; ++sfbi) {
834 exponents[sfbi] = gain -
835 (signed int) ((channel->scalefac[sfbi] + pretab[sfbi]) <<
836 scalefac_multiplier);
837 }
838 }
839 else {
840 for (sfbi = 0; sfbi < 22; ++sfbi) {
841 exponents[sfbi] = gain -
842 (signed int) (channel->scalefac[sfbi] << scalefac_multiplier);
843 }
844 }
845 }
846}
847
848/*
849 * NAME:III_requantize()
850 * DESCRIPTION:requantize one (positive) value
851 */
852static
853mad_fixed_t III_requantize(unsigned int value, signed int exp)
854{
855 mad_fixed_t requantized;
856 signed int frac;
857 struct fixedfloat const *power;
858
859 /*
860 * long blocks:
861 * xr[i] = sign(is[i]) * abs(is[i])^(4/3) *
862 * 2^((1/4) * (global_gain - 210)) *
863 * 2^-(scalefac_multiplier *
864 * (scalefac_l[sfb] + preflag * pretab[sfb]))
865 *
866 * short blocks:
867 * xr[i] = sign(is[i]) * abs(is[i])^(4/3) *
868 * 2^((1/4) * (global_gain - 210 - 8 * subblock_gain[w])) *
869 * 2^-(scalefac_multiplier * scalefac_s[sfb][w])
870 *
871 * where:
872 * scalefac_multiplier = (scalefac_scale + 1) / 2
873 */
874
875 frac = exp % 4;
876 exp /= 4;
877
878 power = &rq_table[value];
879 requantized = power->mantissa;
880 exp += power->exponent;
881
882 if (exp < 0) {
883 if (-exp >= sizeof(mad_fixed_t) * CHAR_BIT) {
884 /* underflow */
885 requantized = 0;
886 }
887 else
888 requantized >>= -exp;
889 }
890 else {
891 if (exp >= 5) {
892 /* overflow */
893# if defined(DEBUG)
894 fprintf(stderr, "requantize overflow (%f * 2^%d)\n",
895 mad_f_todouble(requantized), exp);
896# endif
897 requantized = MAD_F_MAX;
898 }
899 else
900 requantized <<= exp;
901 }
902
903 return frac ? mad_f_mul(requantized, root_table[3 + frac]) : requantized;
904}
905
906/* we must take care that sz >= bits and sz < sizeof(long) lest bits == 0 */
907 # define MASK(cache, sz, bits)\
908 (((cache) >> ((sz) - (bits))) & ((1 << (bits)) - 1))
909# define MASK1BIT(cache, sz) \
910 ((cache) & (1 << ((sz) - 1)))
911
912/*
913 * NAME:III_huffdecode()
914 * DESCRIPTION:decode Huffman code words of one channel of one granule
915 */
916static
917enum mad_error III_huffdecode(struct mad_bitptr *ptr, mad_fixed_t xr[576],
918 struct channel *channel,
919 unsigned char const *sfbwidth,
920 unsigned int part2_length)
921{
922 signed int exponents[39], exp;
923 signed int const *expptr;
924 struct mad_bitptr peek;
925 signed int bits_left, cachesz;
926 register mad_fixed_t *xrptr;
927 mad_fixed_t const *sfbound;
928 register unsigned long bitcache;
929
930 bits_left = (signed) channel->part2_3_length - (signed) part2_length;
931 if (bits_left < 0)
932 return MAD_ERROR_BADPART3LEN;
933
934 III_exponents(channel, sfbwidth, exponents);
935
936 peek = *ptr;
937 mad_bit_skip(ptr, bits_left);
938
939 /* align bit reads to byte boundaries */
940 cachesz = mad_bit_bitsleft(&peek);
941 cachesz += ((32 - 1 - 24) + (24 - cachesz)) & ~7;
942
943 bitcache = mad_bit_read(&peek, cachesz);
944 bits_left -= cachesz;
945
946 xrptr = &xr[0];
947
948 /* big_values */
949 {
950 unsigned int region, rcount;
951 struct hufftable const *entry;
952 union huffpair const *table;
953 unsigned int linbits, startbits, big_values, reqhits;
954 mad_fixed_t reqcache[16];
955
956 sfbound = xrptr + *sfbwidth++;
957 rcount = channel->region0_count + 1;
958
959 entry = &mad_huff_pair_table[channel->table_select[region = 0]];
960 table = entry->table;
961 linbits = entry->linbits;
962 startbits = entry->startbits;
963
964 if (table == 0)
965 return MAD_ERROR_BADHUFFTABLE;
966
967 expptr = &exponents[0];
968 exp = *expptr++;
969 reqhits = 0;
970
971 big_values = channel->big_values;
972
973 while (big_values-- && cachesz + bits_left > 0) {
974 union huffpair const *pair;
975 unsigned int clumpsz, value;
976 register mad_fixed_t requantized;
977
978 if (xrptr == sfbound) {
979 sfbound += *sfbwidth++;
980
981 /* change table if region boundary */
982
983 if (--rcount == 0) {
984 if (region == 0)
985 rcount = channel->region1_count + 1;
986 else
987 rcount = 0; /* all remaining */
988
989 entry = &mad_huff_pair_table[channel->table_select[++region]];
990 table = entry->table;
991 linbits = entry->linbits;
992 startbits = entry->startbits;
993
994 if (table == 0)
995 return MAD_ERROR_BADHUFFTABLE;
996 }
997
998 if (exp != *expptr) {
999 exp = *expptr;
1000 reqhits = 0;
1001 }
1002
1003 ++expptr;
1004 }
1005
1006 if (cachesz < 21) {
1007 unsigned int bits;
1008
1009 bits = ((32 - 1 - 21) + (21 - cachesz)) & ~7;
1010 bitcache = (bitcache << bits) | mad_bit_read(&peek, bits);
1011 cachesz += bits;
1012 bits_left -= bits;
1013 }
1014
1015 /* hcod (0..19) */
1016
1017 clumpsz = startbits;
1018 pair = &table[MASK(bitcache, cachesz, clumpsz)];
1019
1020 while (!pair->final) {
1021 cachesz -= clumpsz;
1022
1023 clumpsz = pair->ptr.bits;
1024 pair = &table[pair->ptr.offset + MASK(bitcache, cachesz, clumpsz)];
1025 }
1026
1027 cachesz -= pair->value.hlen;
1028
1029 if (linbits) {
1030 /* x (0..14) */
1031
1032 value = pair->value.x;
1033
1034 switch (value) {
1035 case 0:
1036 xrptr[0] = 0;
1037 break;
1038
1039 case 15:
1040 if (cachesz < linbits + 2) {
1041 bitcache = (bitcache << 16) | mad_bit_read(&peek, 16);
1042 cachesz += 16;
1043 bits_left -= 16;
1044 }
1045
1046 value += MASK(bitcache, cachesz, linbits);
1047 cachesz -= linbits;
1048
1049 requantized = III_requantize(value, exp);
1050 goto x_final;
1051
1052 default:
1053 if (reqhits & (1 << value))
1054 requantized = reqcache[value];
1055 else {
1056 reqhits |= (1 << value);
1057 requantized = reqcache[value] = III_requantize(value, exp);
1058 }
1059
1060 x_final:
1061 xrptr[0] = MASK1BIT(bitcache, cachesz--) ?
1062 -requantized : requantized;
1063 }
1064
1065 /* y (0..14) */
1066
1067 value = pair->value.y;
1068
1069 switch (value) {
1070 case 0:
1071 xrptr[1] = 0;
1072 break;
1073
1074 case 15:
1075 if (cachesz < linbits + 1) {
1076 bitcache = (bitcache << 16) | mad_bit_read(&peek, 16);
1077 cachesz += 16;
1078 bits_left -= 16;
1079 }
1080
1081 value += MASK(bitcache, cachesz, linbits);
1082 cachesz -= linbits;
1083
1084 requantized = III_requantize(value, exp);
1085 goto y_final;
1086
1087 default:
1088 if (reqhits & (1 << value))
1089 requantized = reqcache[value];
1090 else {
1091 reqhits |= (1 << value);
1092 requantized = reqcache[value] = III_requantize(value, exp);
1093 }
1094
1095 y_final:
1096 xrptr[1] = MASK1BIT(bitcache, cachesz--) ?
1097 -requantized : requantized;
1098 }
1099 }
1100 else {
1101 /* x (0..1) */
1102
1103 value = pair->value.x;
1104
1105 if (value == 0)
1106 xrptr[0] = 0;
1107 else {
1108 if (reqhits & (1 << value))
1109 requantized = reqcache[value];
1110 else {
1111 reqhits |= (1 << value);
1112 requantized = reqcache[value] = III_requantize(value, exp);
1113 }
1114
1115 xrptr[0] = MASK1BIT(bitcache, cachesz--) ?
1116 -requantized : requantized;
1117 }
1118
1119 /* y (0..1) */
1120
1121 value = pair->value.y;
1122
1123 if (value == 0)
1124 xrptr[1] = 0;
1125 else {
1126 if (reqhits & (1 << value))
1127 requantized = reqcache[value];
1128 else {
1129 reqhits |= (1 << value);
1130 requantized = reqcache[value] = III_requantize(value, exp);
1131 }
1132
1133 xrptr[1] = MASK1BIT(bitcache, cachesz--) ?
1134 -requantized : requantized;
1135 }
1136 }
1137
1138 xrptr += 2;
1139 }
1140 }
1141
1142 if (cachesz + bits_left < 0)
1143 return MAD_ERROR_BADHUFFDATA; /* big_values overrun */
1144
1145 /* count1 */
1146 {
1147 union huffquad const *table;
1148 register mad_fixed_t requantized;
1149
1150 table = mad_huff_quad_table[channel->flags & count1table_select];
1151
1152 requantized = III_requantize(1, exp);
1153
1154 while (cachesz + bits_left > 0 && xrptr <= &xr[572]) {
1155 union huffquad const *quad;
1156
1157 /* hcod (1..6) */
1158
1159 if (cachesz < 10) {
1160 bitcache = (bitcache << 16) | mad_bit_read(&peek, 16);
1161 cachesz += 16;
1162 bits_left -= 16;
1163 }
1164
1165 quad = &table[MASK(bitcache, cachesz, 4)];
1166
1167 /* quad tables guaranteed to have at most one extra lookup */
1168 if (!quad->final) {
1169 cachesz -= 4;
1170
1171 quad = &table[quad->ptr.offset +
1172 MASK(bitcache, cachesz, quad->ptr.bits)];
1173 }
1174
1175 cachesz -= quad->value.hlen;
1176
1177 if (xrptr == sfbound) {
1178 sfbound += *sfbwidth++;
1179
1180 if (exp != *expptr) {
1181 exp = *expptr;
1182 requantized = III_requantize(1, exp);
1183 }
1184
1185 ++expptr;
1186 }
1187
1188 /* v (0..1) */
1189
1190 xrptr[0] = quad->value.v ?
1191 (MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0;
1192
1193 /* w (0..1) */
1194
1195 xrptr[1] = quad->value.w ?
1196 (MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0;
1197
1198 xrptr += 2;
1199
1200 if (xrptr == sfbound) {
1201 sfbound += *sfbwidth++;
1202
1203 if (exp != *expptr) {
1204 exp = *expptr;
1205 requantized = III_requantize(1, exp);
1206 }
1207
1208 ++expptr;
1209 }
1210
1211 /* x (0..1) */
1212
1213 xrptr[0] = quad->value.x ?
1214 (MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0;
1215
1216 /* y (0..1) */
1217
1218 xrptr[1] = quad->value.y ?
1219 (MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0;
1220
1221 xrptr += 2;
1222 }
1223
1224 if (cachesz + bits_left < 0) {
1225# if 0 && defined(DEBUG)
1226 fprintf(stderr, "huffman count1 overrun (%d bits)\n",
1227 -(cachesz + bits_left));
1228# endif
1229
1230 /* technically the bitstream is misformatted, but apparently
1231 some encoders are just a bit sloppy with stuffing bits */
1232
1233 xrptr -= 4;
1234 }
1235 }
1236
1237 assert(-bits_left <= MAD_BUFFER_GUARD * CHAR_BIT);
1238
1239# if 0 && defined(DEBUG)
1240 if (bits_left < 0)
1241 fprintf(stderr, "read %d bits too many\n", -bits_left);
1242 else if (cachesz + bits_left > 0)
1243 fprintf(stderr, "%d stuffing bits\n", cachesz + bits_left);
1244# endif
1245
1246 /* rzero */
1247 while (xrptr < &xr[576]) {
1248 xrptr[0] = 0;
1249 xrptr[1] = 0;
1250
1251 xrptr += 2;
1252 }
1253
1254 return 0;
1255}
1256
1257# undef MASK
1258# undef MASK1BIT
1259
1260/*
1261 * NAME:III_reorder()
1262 * DESCRIPTION:reorder frequency lines of a short block into subband order
1263 */
1264static
1265void III_reorder(mad_fixed_t xr[576], struct channel const *channel,
1266 unsigned char const sfbwidth[39])
1267{
1268 mad_fixed_t tmp[32][3][6];
1269 unsigned int sb, l, sfbi, f, w, sbw[3], sw[3];
1270
1271 /* this is probably wrong for 8000 Hz mixed blocks */
1272
1273 if (channel->flags & mixed_block_flag)
1274 sb = 2, sfbi = 3 * 3;
1275 else
1276 sb = 0, sfbi = 0;
1277
1278 for (w = 0; w < 3; ++w) {
1279 sbw[w] = sb;
1280 sw[w] = 0;
1281 }
1282
1283 f = sfbwidth[sfbi];
1284 w = 0;
1285
1286 for (l = 18 * sb; l < 576; ++l) {
1287 tmp[sbw[w]][w][sw[w]++] = xr[l];
1288
1289 if (sw[w] == 6) {
1290 sw[w] = 0;
1291 ++sbw[w];
1292 }
1293
1294 if (--f == 0) {
1295 if (++w == 3)
1296 w = 0;
1297
1298 f = sfbwidth[++sfbi];
1299 }
1300 }
1301
1302 memcpy(&xr[18 * sb], &tmp[sb], (576 - 18 * sb) * sizeof(mad_fixed_t));
1303}
1304
1305/*
1306 * NAME:III_stereo()
1307 * DESCRIPTION:perform joint stereo processing on a granule
1308 */
1309static
1310enum mad_error III_stereo(mad_fixed_t xr[2][576],
1311 struct granule const *granule,
1312 struct mad_header *header,
1313 unsigned char const *sfbwidth)
1314{
1315 short modes[39];
1316 unsigned int sfbi, l, n, i;
1317
1318 enum {
1319 i_stereo = 0x1,
1320 ms_stereo = 0x2
1321 };
1322
1323 if (granule->ch[0].block_type !=
1324 granule->ch[1].block_type ||
1325 (granule->ch[0].flags & mixed_block_flag) !=
1326 (granule->ch[1].flags & mixed_block_flag))
1327 return MAD_ERROR_BADSTEREO;
1328
1329 for (i = 0; i < 39; ++i)
1330 modes[i] = header->mode_extension;
1331
1332 /* intensity stereo */
1333
1334 if (header->mode_extension & i_stereo) {
1335 struct channel const *right_ch = &granule->ch[1];
1336 mad_fixed_t const *right_xr = xr[1];
1337 unsigned int is_pos;
1338
1339 header->flags |= MAD_FLAG_I_STEREO;
1340
1341 /* first determine which scalefactor bands are to be processed */
1342
1343 if (right_ch->block_type == 2) {
1344 unsigned int lower, start, max, bound[3], w;
1345
1346 lower = start = max = bound[0] = bound[1] = bound[2] = 0;
1347
1348 sfbi = l = 0;
1349
1350 if (right_ch->flags & mixed_block_flag) {
1351 while (l < 36) {
1352 n = sfbwidth[sfbi++];
1353
1354 for (i = 0; i < n; ++i) {
1355 if (right_xr[i]) {
1356 lower = sfbi;
1357 break;
1358 }
1359 }
1360
1361 right_xr += n;
1362 l += n;
1363 }
1364
1365 start = sfbi;
1366 }
1367
1368 w = 0;
1369 while (l < 576) {
1370 n = sfbwidth[sfbi++];
1371
1372 for (i = 0; i < n; ++i) {
1373 if (right_xr[i]) {
1374 max = bound[w] = sfbi;
1375 break;
1376 }
1377 }
1378
1379 right_xr += n;
1380 l += n;
1381 w = (w + 1) % 3;
1382 }
1383
1384 if (max)
1385 lower = start;
1386
1387 /* long blocks */
1388
1389 for (i = 0; i < lower; ++i)
1390 modes[i] = header->mode_extension & ~i_stereo;
1391
1392 /* short blocks */
1393
1394 w = 0;
1395 for (i = start; i < max; ++i) {
1396 if (i < bound[w])
1397 modes[i] = header->mode_extension & ~i_stereo;
1398
1399 w = (w + 1) % 3;
1400 }
1401 }
1402 else { /* right_ch->block_type != 2 */
1403 unsigned int bound;
1404
1405 bound = 0;
1406 for (sfbi = l = 0; l < 576; l += n) {
1407 n = sfbwidth[sfbi++];
1408
1409 for (i = 0; i < n; ++i) {
1410 if (right_xr[i]) {
1411 bound = sfbi;
1412 break;
1413 }
1414 }
1415
1416 right_xr += n;
1417 }
1418
1419 for (i = 0; i < bound; ++i)
1420 modes[i] = header->mode_extension & ~i_stereo;
1421 }
1422
1423 /* now do the actual processing */
1424
1425 if (header->flags & MAD_FLAG_LSF_EXT) {
1426 unsigned char const *illegal_pos = granule[1].ch[1].scalefac;
1427 mad_fixed_t const *lsf_scale;
1428
1429 /* intensity_scale */
1430 lsf_scale = is_lsf_table[right_ch->scalefac_compress & 0x1];
1431
1432 for (sfbi = l = 0; l < 576; ++sfbi, l += n) {
1433 n = sfbwidth[sfbi];
1434
1435 if (!(modes[sfbi] & i_stereo))
1436 continue;
1437
1438 if (illegal_pos[sfbi]) {
1439 modes[sfbi] &= ~i_stereo;
1440 continue;
1441 }
1442
1443 is_pos = right_ch->scalefac[sfbi];
1444
1445 for (i = 0; i < n; ++i) {
1446 register mad_fixed_t left;
1447
1448 left = xr[0][l + i];
1449
1450 if (is_pos == 0)
1451 xr[1][l + i] = left;
1452 else {
1453 register mad_fixed_t opposite;
1454
1455 opposite = mad_f_mul(left, lsf_scale[(is_pos - 1) / 2]);
1456
1457 if (is_pos & 1) {
1458 xr[0][l + i] = opposite;
1459 xr[1][l + i] = left;
1460 }
1461 else
1462 xr[1][l + i] = opposite;
1463 }
1464 }
1465 }
1466 }
1467 else { /* !(header->flags & MAD_FLAG_LSF_EXT) */
1468 for (sfbi = l = 0; l < 576; ++sfbi, l += n) {
1469 n = sfbwidth[sfbi];
1470
1471 if (!(modes[sfbi] & i_stereo))
1472 continue;
1473
1474 is_pos = right_ch->scalefac[sfbi];
1475
1476 if (is_pos >= 7) { /* illegal intensity position */
1477 modes[sfbi] &= ~i_stereo;
1478 continue;
1479 }
1480
1481 for (i = 0; i < n; ++i) {
1482 register mad_fixed_t left;
1483
1484 left = xr[0][l + i];
1485
1486 xr[0][l + i] = mad_f_mul(left, is_table[ is_pos]);
1487 xr[1][l + i] = mad_f_mul(left, is_table[6 - is_pos]);
1488 }
1489 }
1490 }
1491 }
1492
1493 /* middle/side stereo */
1494
1495 if (header->mode_extension & ms_stereo) {
1496 register mad_fixed_t invsqrt2;
1497
1498 header->flags |= MAD_FLAG_MS_STEREO;
1499
1500 invsqrt2 = root_table[3 + -2];
1501
1502 for (sfbi = l = 0; l < 576; ++sfbi, l += n) {
1503 n = sfbwidth[sfbi];
1504
1505 if (modes[sfbi] != ms_stereo)
1506 continue;
1507
1508 for (i = 0; i < n; ++i) {
1509 register mad_fixed_t m, s;
1510
1511 m = xr[0][l + i];
1512 s = xr[1][l + i];
1513
1514 xr[0][l + i] = mad_f_mul(m + s, invsqrt2); /* l = (m + s) / sqrt(2) */
1515 xr[1][l + i] = mad_f_mul(m - s, invsqrt2); /* r = (m - s) / sqrt(2) */
1516 }
1517 }
1518 }
1519
1520 return 0;
1521}
1522
1523/*
1524 * NAME:III_aliasreduce()
1525 * DESCRIPTION:perform frequency line alias reduction
1526 */
1527static
1528void III_aliasreduce(mad_fixed_t xr[576], int lines)
1529{
1530 mad_fixed_t const *bound;
1531 int i;
1532
1533 bound = &xr[lines];
1534 for (xr += 18; xr < bound; xr += 18) {
1535 for (i = 0; i < 8; ++i) {
1536 register mad_fixed_t *aptr, *bptr, a, b;
1537 register mad_fixed64hi_t hi;
1538 register mad_fixed64lo_t lo;
1539
1540 aptr = &xr[-1 - i];
1541 bptr = &xr[ i];
1542
1543 a = *aptr;
1544 b = *bptr;
1545
1546# if defined(ASO_ZEROCHECK)
1547 if (a | b) {
1548# endif
1549 MAD_F_ML0(hi, lo, a, cs[i]);
1550 MAD_F_MLA(hi, lo, -b, ca[i]);
1551
1552 *aptr = MAD_F_MLZ(hi, lo);
1553
1554 MAD_F_ML0(hi, lo, b, cs[i]);
1555 MAD_F_MLA(hi, lo, a, ca[i]);
1556
1557 *bptr = MAD_F_MLZ(hi, lo);
1558# if defined(ASO_ZEROCHECK)
1559 }
1560# endif
1561 }
1562 }
1563}
1564
1565# if defined(ASO_IMDCT)
1566void III_imdct_l(mad_fixed_t const [18], mad_fixed_t [36], unsigned int);
1567# else
1568/*
1569 * NAME:imdct36
1570 * DESCRIPTION:perform X[18]->x[36] IMDCT
1571 */
1572static inline
1573void imdct36(mad_fixed_t const X[18], mad_fixed_t x[36])
1574{
1575 mad_fixed_t t0, t1, t2, t3, t4, t5, t6, t7;
1576 mad_fixed_t t8, t9, t10, t11, t12, t13, t14, t15;
1577 register mad_fixed64hi_t hi;
1578 register mad_fixed64lo_t lo;
1579
1580 MAD_F_ML0(hi, lo, X[4], MAD_F(0x0ec835e8));
1581 MAD_F_MLA(hi, lo, X[13], MAD_F(0x061f78aa));
1582
1583 t6 = MAD_F_MLZ(hi, lo);
1584
1585 MAD_F_MLA(hi, lo, (t14 = X[1] - X[10]), -MAD_F(0x061f78aa));
1586 MAD_F_MLA(hi, lo, (t15 = X[7] + X[16]), -MAD_F(0x0ec835e8));
1587
1588 t0 = MAD_F_MLZ(hi, lo);
1589
1590 MAD_F_MLA(hi, lo, (t8 = X[0] - X[11] - X[12]), MAD_F(0x0216a2a2));
1591 MAD_F_MLA(hi, lo, (t9 = X[2] - X[9] - X[14]), MAD_F(0x09bd7ca0));
1592 MAD_F_MLA(hi, lo, (t10 = X[3] - X[8] - X[15]), -MAD_F(0x0cb19346));
1593 MAD_F_MLA(hi, lo, (t11 = X[5] - X[6] - X[17]), -MAD_F(0x0fdcf549));
1594
1595 x[7] = MAD_F_MLZ(hi, lo);
1596 x[10] = -x[7];
1597
1598 MAD_F_ML0(hi, lo, t8, -MAD_F(0x0cb19346));
1599 MAD_F_MLA(hi, lo, t9, MAD_F(0x0fdcf549));
1600 MAD_F_MLA(hi, lo, t10, MAD_F(0x0216a2a2));
1601 MAD_F_MLA(hi, lo, t11, -MAD_F(0x09bd7ca0));
1602
1603 x[19] = x[34] = MAD_F_MLZ(hi, lo) - t0;
1604
1605 t12 = X[0] - X[3] + X[8] - X[11] - X[12] + X[15];
1606 t13 = X[2] + X[5] - X[6] - X[9] - X[14] - X[17];
1607
1608 MAD_F_ML0(hi, lo, t12, -MAD_F(0x0ec835e8));
1609 MAD_F_MLA(hi, lo, t13, MAD_F(0x061f78aa));
1610
1611 x[22] = x[31] = MAD_F_MLZ(hi, lo) + t0;
1612
1613 MAD_F_ML0(hi, lo, X[1], -MAD_F(0x09bd7ca0));
1614 MAD_F_MLA(hi, lo, X[7], MAD_F(0x0216a2a2));
1615 MAD_F_MLA(hi, lo, X[10], -MAD_F(0x0fdcf549));
1616 MAD_F_MLA(hi, lo, X[16], MAD_F(0x0cb19346));
1617
1618 t1 = MAD_F_MLZ(hi, lo) + t6;
1619
1620 MAD_F_ML0(hi, lo, X[0], MAD_F(0x03768962));
1621 MAD_F_MLA(hi, lo, X[2], MAD_F(0x0e313245));
1622 MAD_F_MLA(hi, lo, X[3], -MAD_F(0x0ffc19fd));
1623 MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0acf37ad));
1624 MAD_F_MLA(hi, lo, X[6], MAD_F(0x04cfb0e2));
1625 MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0898c779));
1626 MAD_F_MLA(hi, lo, X[9], MAD_F(0x0d7e8807));
1627 MAD_F_MLA(hi, lo, X[11], MAD_F(0x0f426cb5));
1628 MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0bcbe352));
1629 MAD_F_MLA(hi, lo, X[14], MAD_F(0x00b2aa3e));
1630 MAD_F_MLA(hi, lo, X[15], -MAD_F(0x07635284));
1631 MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0f9ee890));
1632
1633 x[6] = MAD_F_MLZ(hi, lo) + t1;
1634 x[11] = -x[6];
1635
1636 MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0f426cb5));
1637 MAD_F_MLA(hi, lo, X[2], -MAD_F(0x00b2aa3e));
1638 MAD_F_MLA(hi, lo, X[3], MAD_F(0x0898c779));
1639 MAD_F_MLA(hi, lo, X[5], MAD_F(0x0f9ee890));
1640 MAD_F_MLA(hi, lo, X[6], MAD_F(0x0acf37ad));
1641 MAD_F_MLA(hi, lo, X[8], -MAD_F(0x07635284));
1642 MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0e313245));
1643 MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0bcbe352));
1644 MAD_F_MLA(hi, lo, X[12], -MAD_F(0x03768962));
1645 MAD_F_MLA(hi, lo, X[14], MAD_F(0x0d7e8807));
1646 MAD_F_MLA(hi, lo, X[15], MAD_F(0x0ffc19fd));
1647 MAD_F_MLA(hi, lo, X[17], MAD_F(0x04cfb0e2));
1648
1649 x[23] = x[30] = MAD_F_MLZ(hi, lo) + t1;
1650
1651 MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0bcbe352));
1652 MAD_F_MLA(hi, lo, X[2], MAD_F(0x0d7e8807));
1653 MAD_F_MLA(hi, lo, X[3], -MAD_F(0x07635284));
1654 MAD_F_MLA(hi, lo, X[5], MAD_F(0x04cfb0e2));
1655 MAD_F_MLA(hi, lo, X[6], MAD_F(0x0f9ee890));
1656 MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0ffc19fd));
1657 MAD_F_MLA(hi, lo, X[9], -MAD_F(0x00b2aa3e));
1658 MAD_F_MLA(hi, lo, X[11], MAD_F(0x03768962));
1659 MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0f426cb5));
1660 MAD_F_MLA(hi, lo, X[14], MAD_F(0x0e313245));
1661 MAD_F_MLA(hi, lo, X[15], MAD_F(0x0898c779));
1662 MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0acf37ad));
1663
1664 x[18] = x[35] = MAD_F_MLZ(hi, lo) - t1;
1665
1666 MAD_F_ML0(hi, lo, X[4], MAD_F(0x061f78aa));
1667 MAD_F_MLA(hi, lo, X[13], -MAD_F(0x0ec835e8));
1668
1669 t7 = MAD_F_MLZ(hi, lo);
1670
1671 MAD_F_MLA(hi, lo, X[1], -MAD_F(0x0cb19346));
1672 MAD_F_MLA(hi, lo, X[7], MAD_F(0x0fdcf549));
1673 MAD_F_MLA(hi, lo, X[10], MAD_F(0x0216a2a2));
1674 MAD_F_MLA(hi, lo, X[16], -MAD_F(0x09bd7ca0));
1675
1676 t2 = MAD_F_MLZ(hi, lo);
1677
1678 MAD_F_MLA(hi, lo, X[0], MAD_F(0x04cfb0e2));
1679 MAD_F_MLA(hi, lo, X[2], MAD_F(0x0ffc19fd));
1680 MAD_F_MLA(hi, lo, X[3], -MAD_F(0x0d7e8807));
1681 MAD_F_MLA(hi, lo, X[5], MAD_F(0x03768962));
1682 MAD_F_MLA(hi, lo, X[6], -MAD_F(0x0bcbe352));
1683 MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0e313245));
1684 MAD_F_MLA(hi, lo, X[9], MAD_F(0x07635284));
1685 MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0acf37ad));
1686 MAD_F_MLA(hi, lo, X[12], MAD_F(0x0f9ee890));
1687 MAD_F_MLA(hi, lo, X[14], MAD_F(0x0898c779));
1688 MAD_F_MLA(hi, lo, X[15], MAD_F(0x00b2aa3e));
1689 MAD_F_MLA(hi, lo, X[17], MAD_F(0x0f426cb5));
1690
1691 x[5] = MAD_F_MLZ(hi, lo);
1692 x[12] = -x[5];
1693
1694 MAD_F_ML0(hi, lo, X[0], MAD_F(0x0acf37ad));
1695 MAD_F_MLA(hi, lo, X[2], -MAD_F(0x0898c779));
1696 MAD_F_MLA(hi, lo, X[3], MAD_F(0x0e313245));
1697 MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0f426cb5));
1698 MAD_F_MLA(hi, lo, X[6], -MAD_F(0x03768962));
1699 MAD_F_MLA(hi, lo, X[8], MAD_F(0x00b2aa3e));
1700 MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0ffc19fd));
1701 MAD_F_MLA(hi, lo, X[11], MAD_F(0x0f9ee890));
1702 MAD_F_MLA(hi, lo, X[12], -MAD_F(0x04cfb0e2));
1703 MAD_F_MLA(hi, lo, X[14], MAD_F(0x07635284));
1704 MAD_F_MLA(hi, lo, X[15], MAD_F(0x0d7e8807));
1705 MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0bcbe352));
1706
1707 x[0] = MAD_F_MLZ(hi, lo) + t2;
1708 x[17] = -x[0];
1709
1710 MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0f9ee890));
1711 MAD_F_MLA(hi, lo, X[2], -MAD_F(0x07635284));
1712 MAD_F_MLA(hi, lo, X[3], -MAD_F(0x00b2aa3e));
1713 MAD_F_MLA(hi, lo, X[5], MAD_F(0x0bcbe352));
1714 MAD_F_MLA(hi, lo, X[6], MAD_F(0x0f426cb5));
1715 MAD_F_MLA(hi, lo, X[8], MAD_F(0x0d7e8807));
1716 MAD_F_MLA(hi, lo, X[9], MAD_F(0x0898c779));
1717 MAD_F_MLA(hi, lo, X[11], -MAD_F(0x04cfb0e2));
1718 MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0acf37ad));
1719 MAD_F_MLA(hi, lo, X[14], -MAD_F(0x0ffc19fd));
1720 MAD_F_MLA(hi, lo, X[15], -MAD_F(0x0e313245));
1721 MAD_F_MLA(hi, lo, X[17], -MAD_F(0x03768962));
1722
1723 x[24] = x[29] = MAD_F_MLZ(hi, lo) + t2;
1724
1725 MAD_F_ML0(hi, lo, X[1], -MAD_F(0x0216a2a2));
1726 MAD_F_MLA(hi, lo, X[7], -MAD_F(0x09bd7ca0));
1727 MAD_F_MLA(hi, lo, X[10], MAD_F(0x0cb19346));
1728 MAD_F_MLA(hi, lo, X[16], MAD_F(0x0fdcf549));
1729
1730 t3 = MAD_F_MLZ(hi, lo) + t7;
1731
1732 MAD_F_ML0(hi, lo, X[0], MAD_F(0x00b2aa3e));
1733 MAD_F_MLA(hi, lo, X[2], MAD_F(0x03768962));
1734 MAD_F_MLA(hi, lo, X[3], -MAD_F(0x04cfb0e2));
1735 MAD_F_MLA(hi, lo, X[5], -MAD_F(0x07635284));
1736 MAD_F_MLA(hi, lo, X[6], MAD_F(0x0898c779));
1737 MAD_F_MLA(hi, lo, X[8], MAD_F(0x0acf37ad));
1738 MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0bcbe352));
1739 MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0d7e8807));
1740 MAD_F_MLA(hi, lo, X[12], MAD_F(0x0e313245));
1741 MAD_F_MLA(hi, lo, X[14], MAD_F(0x0f426cb5));
1742 MAD_F_MLA(hi, lo, X[15], -MAD_F(0x0f9ee890));
1743 MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0ffc19fd));
1744
1745 x[8] = MAD_F_MLZ(hi, lo) + t3;
1746 x[9] = -x[8];
1747
1748 MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0e313245));
1749 MAD_F_MLA(hi, lo, X[2], MAD_F(0x0bcbe352));
1750 MAD_F_MLA(hi, lo, X[3], MAD_F(0x0f9ee890));
1751 MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0898c779));
1752 MAD_F_MLA(hi, lo, X[6], -MAD_F(0x0ffc19fd));
1753 MAD_F_MLA(hi, lo, X[8], MAD_F(0x04cfb0e2));
1754 MAD_F_MLA(hi, lo, X[9], MAD_F(0x0f426cb5));
1755 MAD_F_MLA(hi, lo, X[11], -MAD_F(0x00b2aa3e));
1756 MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0d7e8807));
1757 MAD_F_MLA(hi, lo, X[14], -MAD_F(0x03768962));
1758 MAD_F_MLA(hi, lo, X[15], MAD_F(0x0acf37ad));
1759 MAD_F_MLA(hi, lo, X[17], MAD_F(0x07635284));
1760
1761 x[21] = x[32] = MAD_F_MLZ(hi, lo) + t3;
1762
1763 MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0d7e8807));
1764 MAD_F_MLA(hi, lo, X[2], MAD_F(0x0f426cb5));
1765 MAD_F_MLA(hi, lo, X[3], MAD_F(0x0acf37ad));
1766 MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0ffc19fd));
1767 MAD_F_MLA(hi, lo, X[6], -MAD_F(0x07635284));
1768 MAD_F_MLA(hi, lo, X[8], MAD_F(0x0f9ee890));
1769 MAD_F_MLA(hi, lo, X[9], MAD_F(0x03768962));
1770 MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0e313245));
1771 MAD_F_MLA(hi, lo, X[12], MAD_F(0x00b2aa3e));
1772 MAD_F_MLA(hi, lo, X[14], MAD_F(0x0bcbe352));
1773 MAD_F_MLA(hi, lo, X[15], -MAD_F(0x04cfb0e2));
1774 MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0898c779));
1775
1776 x[20] = x[33] = MAD_F_MLZ(hi, lo) - t3;
1777
1778 MAD_F_ML0(hi, lo, t14, -MAD_F(0x0ec835e8));
1779 MAD_F_MLA(hi, lo, t15, MAD_F(0x061f78aa));
1780
1781 t4 = MAD_F_MLZ(hi, lo) - t7;
1782
1783 MAD_F_ML0(hi, lo, t12, MAD_F(0x061f78aa));
1784 MAD_F_MLA(hi, lo, t13, MAD_F(0x0ec835e8));
1785
1786 x[4] = MAD_F_MLZ(hi, lo) + t4;
1787 x[13] = -x[4];
1788
1789 MAD_F_ML0(hi, lo, t8, MAD_F(0x09bd7ca0));
1790 MAD_F_MLA(hi, lo, t9, -MAD_F(0x0216a2a2));
1791 MAD_F_MLA(hi, lo, t10, MAD_F(0x0fdcf549));
1792 MAD_F_MLA(hi, lo, t11, -MAD_F(0x0cb19346));
1793
1794 x[1] = MAD_F_MLZ(hi, lo) + t4;
1795 x[16] = -x[1];
1796
1797 MAD_F_ML0(hi, lo, t8, -MAD_F(0x0fdcf549));
1798 MAD_F_MLA(hi, lo, t9, -MAD_F(0x0cb19346));
1799 MAD_F_MLA(hi, lo, t10, -MAD_F(0x09bd7ca0));
1800 MAD_F_MLA(hi, lo, t11, -MAD_F(0x0216a2a2));
1801
1802 x[25] = x[28] = MAD_F_MLZ(hi, lo) + t4;
1803
1804 MAD_F_ML0(hi, lo, X[1], -MAD_F(0x0fdcf549));
1805 MAD_F_MLA(hi, lo, X[7], -MAD_F(0x0cb19346));
1806 MAD_F_MLA(hi, lo, X[10], -MAD_F(0x09bd7ca0));
1807 MAD_F_MLA(hi, lo, X[16], -MAD_F(0x0216a2a2));
1808
1809 t5 = MAD_F_MLZ(hi, lo) - t6;
1810
1811 MAD_F_ML0(hi, lo, X[0], MAD_F(0x0898c779));
1812 MAD_F_MLA(hi, lo, X[2], MAD_F(0x04cfb0e2));
1813 MAD_F_MLA(hi, lo, X[3], MAD_F(0x0bcbe352));
1814 MAD_F_MLA(hi, lo, X[5], MAD_F(0x00b2aa3e));
1815 MAD_F_MLA(hi, lo, X[6], MAD_F(0x0e313245));
1816 MAD_F_MLA(hi, lo, X[8], -MAD_F(0x03768962));
1817 MAD_F_MLA(hi, lo, X[9], MAD_F(0x0f9ee890));
1818 MAD_F_MLA(hi, lo, X[11], -MAD_F(0x07635284));
1819 MAD_F_MLA(hi, lo, X[12], MAD_F(0x0ffc19fd));
1820 MAD_F_MLA(hi, lo, X[14], -MAD_F(0x0acf37ad));
1821 MAD_F_MLA(hi, lo, X[15], MAD_F(0x0f426cb5));
1822 MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0d7e8807));
1823
1824 x[2] = MAD_F_MLZ(hi, lo) + t5;
1825 x[15] = -x[2];
1826
1827 MAD_F_ML0(hi, lo, X[0], MAD_F(0x07635284));
1828 MAD_F_MLA(hi, lo, X[2], MAD_F(0x0acf37ad));
1829 MAD_F_MLA(hi, lo, X[3], MAD_F(0x03768962));
1830 MAD_F_MLA(hi, lo, X[5], MAD_F(0x0d7e8807));
1831 MAD_F_MLA(hi, lo, X[6], -MAD_F(0x00b2aa3e));
1832 MAD_F_MLA(hi, lo, X[8], MAD_F(0x0f426cb5));
1833 MAD_F_MLA(hi, lo, X[9], -MAD_F(0x04cfb0e2));
1834 MAD_F_MLA(hi, lo, X[11], MAD_F(0x0ffc19fd));
1835 MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0898c779));
1836 MAD_F_MLA(hi, lo, X[14], MAD_F(0x0f9ee890));
1837 MAD_F_MLA(hi, lo, X[15], -MAD_F(0x0bcbe352));
1838 MAD_F_MLA(hi, lo, X[17], MAD_F(0x0e313245));
1839
1840 x[3] = MAD_F_MLZ(hi, lo) + t5;
1841 x[14] = -x[3];
1842
1843 MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0ffc19fd));
1844 MAD_F_MLA(hi, lo, X[2], -MAD_F(0x0f9ee890));
1845 MAD_F_MLA(hi, lo, X[3], -MAD_F(0x0f426cb5));
1846 MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0e313245));
1847 MAD_F_MLA(hi, lo, X[6], -MAD_F(0x0d7e8807));
1848 MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0bcbe352));
1849 MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0acf37ad));
1850 MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0898c779));
1851 MAD_F_MLA(hi, lo, X[12], -MAD_F(0x07635284));
1852 MAD_F_MLA(hi, lo, X[14], -MAD_F(0x04cfb0e2));
1853 MAD_F_MLA(hi, lo, X[15], -MAD_F(0x03768962));
1854 MAD_F_MLA(hi, lo, X[17], -MAD_F(0x00b2aa3e));
1855
1856 x[26] = x[27] = MAD_F_MLZ(hi, lo) + t5;
1857}
1858
1859/*
1860 * NAME:III_imdct_l()
1861 * DESCRIPTION:perform IMDCT and windowing for long blocks
1862 */
1863static
1864void III_imdct_l(mad_fixed_t const X[18], mad_fixed_t z[36],
1865 unsigned int block_type)
1866{
1867 unsigned int i;
1868
1869 /* IMDCT */
1870
1871 imdct36(X, z);
1872
1873 /* windowing */
1874
1875 switch (block_type) {
1876 case 0: /* normal window */
1877# if defined(ASO_INTERLEAVE1)
1878 {
1879 register mad_fixed_t tmp1, tmp2;
1880
1881 tmp1 = window_l[0];
1882 tmp2 = window_l[1];
1883
1884 for (i = 0; i < 34; i += 2) {
1885 z[i + 0] = mad_f_mul(z[i + 0], tmp1);
1886 tmp1 = window_l[i + 2];
1887 z[i + 1] = mad_f_mul(z[i + 1], tmp2);
1888 tmp2 = window_l[i + 3];
1889 }
1890
1891 z[34] = mad_f_mul(z[34], tmp1);
1892 z[35] = mad_f_mul(z[35], tmp2);
1893 }
1894# elif defined(ASO_INTERLEAVE2)
1895 {
1896 register mad_fixed_t tmp1, tmp2;
1897
1898 tmp1 = z[0];
1899 tmp2 = window_l[0];
1900
1901 for (i = 0; i < 35; ++i) {
1902 z[i] = mad_f_mul(tmp1, tmp2);
1903 tmp1 = z[i + 1];
1904 tmp2 = window_l[i + 1];
1905 }
1906
1907 z[35] = mad_f_mul(tmp1, tmp2);
1908 }
1909# elif 1
1910 for (i = 0; i < 36; i += 4) {
1911 z[i + 0] = mad_f_mul(z[i + 0], window_l[i + 0]);
1912 z[i + 1] = mad_f_mul(z[i + 1], window_l[i + 1]);
1913 z[i + 2] = mad_f_mul(z[i + 2], window_l[i + 2]);
1914 z[i + 3] = mad_f_mul(z[i + 3], window_l[i + 3]);
1915 }
1916# else
1917 for (i = 0; i < 36; ++i) z[i] = mad_f_mul(z[i], window_l[i]);
1918# endif
1919 break;
1920
1921 case 1: /* start block */
1922 for (i = 0; i < 18; ++i) z[i] = mad_f_mul(z[i], window_l[i]);
1923 /* (i = 18; i < 24; ++i) z[i] unchanged */
1924 for (i = 24; i < 30; ++i) z[i] = mad_f_mul(z[i], window_s[i - 18]);
1925 for (i = 30; i < 36; ++i) z[i] = 0;
1926 break;
1927
1928 case 3: /* stop block */
1929 for (i = 0; i < 6; ++i) z[i] = 0;
1930 for (i = 6; i < 12; ++i) z[i] = mad_f_mul(z[i], window_s[i - 6]);
1931 /* (i = 12; i < 18; ++i) z[i] unchanged */
1932 for (i = 18; i < 36; ++i) z[i] = mad_f_mul(z[i], window_l[i]);
1933 break;
1934 }
1935}
1936# endif /* ASO_IMDCT */
1937
1938/*
1939 * NAME:III_imdct_s()
1940 * DESCRIPTION:perform IMDCT and windowing for short blocks
1941 */
1942static
1943void III_imdct_s(mad_fixed_t const X[18], mad_fixed_t z[36])
1944{
1945 mad_fixed_t y[36], *yptr;
1946 mad_fixed_t const *wptr;
1947 int w, i;
1948 register mad_fixed64hi_t hi;
1949 register mad_fixed64lo_t lo;
1950
1951 /* IMDCT */
1952
1953 yptr = &y[0];
1954
1955 for (w = 0; w < 3; ++w) {
1956 register mad_fixed_t const (*s)[6];
1957
1958 s = imdct_s;
1959
1960 for (i = 0; i < 3; ++i) {
1961 MAD_F_ML0(hi, lo, X[0], (*s)[0]);
1962 MAD_F_MLA(hi, lo, X[1], (*s)[1]);
1963 MAD_F_MLA(hi, lo, X[2], (*s)[2]);
1964 MAD_F_MLA(hi, lo, X[3], (*s)[3]);
1965 MAD_F_MLA(hi, lo, X[4], (*s)[4]);
1966 MAD_F_MLA(hi, lo, X[5], (*s)[5]);
1967
1968 yptr[i + 0] = MAD_F_MLZ(hi, lo);
1969 yptr[5 - i] = -yptr[i + 0];
1970
1971 ++s;
1972
1973 MAD_F_ML0(hi, lo, X[0], (*s)[0]);
1974 MAD_F_MLA(hi, lo, X[1], (*s)[1]);
1975 MAD_F_MLA(hi, lo, X[2], (*s)[2]);
1976 MAD_F_MLA(hi, lo, X[3], (*s)[3]);
1977 MAD_F_MLA(hi, lo, X[4], (*s)[4]);
1978 MAD_F_MLA(hi, lo, X[5], (*s)[5]);
1979
1980 yptr[ i + 6] = MAD_F_MLZ(hi, lo);
1981 yptr[11 - i] = yptr[i + 6];
1982
1983 ++s;
1984 }
1985
1986 yptr += 12;
1987 X += 6;
1988 }
1989
1990 /* windowing, overlapping and concatenation */
1991
1992 yptr = &y[0];
1993 wptr = &window_s[0];
1994
1995 for (i = 0; i < 6; ++i) {
1996 z[i + 0] = 0;
1997 z[i + 6] = mad_f_mul(yptr[ 0 + 0], wptr[0]);
1998
1999 MAD_F_ML0(hi, lo, yptr[ 0 + 6], wptr[6]);
2000 MAD_F_MLA(hi, lo, yptr[12 + 0], wptr[0]);
2001
2002 z[i + 12] = MAD_F_MLZ(hi, lo);
2003
2004 MAD_F_ML0(hi, lo, yptr[12 + 6], wptr[6]);
2005 MAD_F_MLA(hi, lo, yptr[24 + 0], wptr[0]);
2006
2007 z[i + 18] = MAD_F_MLZ(hi, lo);
2008
2009 z[i + 24] = mad_f_mul(yptr[24 + 6], wptr[6]);
2010 z[i + 30] = 0;
2011
2012 ++yptr;
2013 ++wptr;
2014 }
2015}
2016
2017/*
2018 * NAME:III_overlap()
2019 * DESCRIPTION:perform overlap-add of windowed IMDCT outputs
2020 */
2021static
2022void III_overlap(mad_fixed_t const output[36], mad_fixed_t overlap[18],
2023 mad_fixed_t sample[18][32], unsigned int sb)
2024{
2025 unsigned int i;
2026
2027# if defined(ASO_INTERLEAVE2)
2028 {
2029 register mad_fixed_t tmp1, tmp2;
2030
2031 tmp1 = overlap[0];
2032 tmp2 = overlap[1];
2033
2034 for (i = 0; i < 16; i += 2) {
2035 sample[i + 0][sb] = output[i + 0] + tmp1;
2036 overlap[i + 0] = output[i + 0 + 18];
2037 tmp1 = overlap[i + 2];
2038
2039 sample[i + 1][sb] = output[i + 1] + tmp2;
2040 overlap[i + 1] = output[i + 1 + 18];
2041 tmp2 = overlap[i + 3];
2042 }
2043
2044 sample[16][sb] = output[16] + tmp1;
2045 overlap[16] = output[16 + 18];
2046 sample[17][sb] = output[17] + tmp2;
2047 overlap[17] = output[17 + 18];
2048 }
2049# elif 0
2050 for (i = 0; i < 18; i += 2) {
2051 sample[i + 0][sb] = output[i + 0] + overlap[i + 0];
2052 overlap[i + 0] = output[i + 0 + 18];
2053
2054 sample[i + 1][sb] = output[i + 1] + overlap[i + 1];
2055 overlap[i + 1] = output[i + 1 + 18];
2056 }
2057# else
2058 for (i = 0; i < 18; ++i) {
2059 sample[i][sb] = output[i] + overlap[i];
2060 overlap[i] = output[i + 18];
2061 }
2062# endif
2063}
2064
2065/*
2066 * NAME:III_overlap_z()
2067 * DESCRIPTION:perform "overlap-add" of zero IMDCT outputs
2068 */
2069static inline
2070void III_overlap_z(mad_fixed_t overlap[18],
2071 mad_fixed_t sample[18][32], unsigned int sb)
2072{
2073 unsigned int i;
2074
2075# if defined(ASO_INTERLEAVE2)
2076 {
2077 register mad_fixed_t tmp1, tmp2;
2078
2079 tmp1 = overlap[0];
2080 tmp2 = overlap[1];
2081
2082 for (i = 0; i < 16; i += 2) {
2083 sample[i + 0][sb] = tmp1;
2084 overlap[i + 0] = 0;
2085 tmp1 = overlap[i + 2];
2086
2087 sample[i + 1][sb] = tmp2;
2088 overlap[i + 1] = 0;
2089 tmp2 = overlap[i + 3];
2090 }
2091
2092 sample[16][sb] = tmp1;
2093 overlap[16] = 0;
2094 sample[17][sb] = tmp2;
2095 overlap[17] = 0;
2096 }
2097# else
2098 for (i = 0; i < 18; ++i) {
2099 sample[i][sb] = overlap[i];
2100 overlap[i] = 0;
2101 }
2102# endif
2103}
2104
2105/*
2106 * NAME:III_freqinver()
2107 * DESCRIPTION:perform subband frequency inversion for odd sample lines
2108 */
2109static
2110void III_freqinver(mad_fixed_t sample[18][32], unsigned int sb)
2111{
2112 unsigned int i;
2113
2114# if 1 || defined(ASO_INTERLEAVE1) || defined(ASO_INTERLEAVE2)
2115 {
2116 register mad_fixed_t tmp1, tmp2;
2117
2118 tmp1 = sample[1][sb];
2119 tmp2 = sample[3][sb];
2120
2121 for (i = 1; i < 13; i += 4) {
2122 sample[i + 0][sb] = -tmp1;
2123 tmp1 = sample[i + 4][sb];
2124 sample[i + 2][sb] = -tmp2;
2125 tmp2 = sample[i + 6][sb];
2126 }
2127
2128 sample[13][sb] = -tmp1;
2129 tmp1 = sample[17][sb];
2130 sample[15][sb] = -tmp2;
2131 sample[17][sb] = -tmp1;
2132 }
2133# else
2134 for (i = 1; i < 18; i += 2)
2135 sample[i][sb] = -sample[i][sb];
2136# endif
2137}
2138
2139/*
2140 * NAME:III_decode()
2141 * DESCRIPTION:decode frame main_data
2142 */
2143static
2144int III_decode(struct mad_bitptr *ptr, struct mad_frame *frame,
2145 struct sideinfo *si, unsigned int nch)
2146{
2147 struct mad_header *header = &frame->header;
2148 unsigned int sfreqi, ngr, gr;
2149
2150 {
2151 unsigned int sfreq;
2152
2153 sfreq = header->samplerate;
2154 if (header->flags & MAD_FLAG_MPEG_2_5_EXT)
2155 sfreq *= 2;
2156
2157 /* 48000 => 0, 44100 => 1, 32000 => 2,
2158 24000 => 3, 22050 => 4, 16000 => 5 */
2159 sfreqi = ((sfreq >> 7) & 0x000f) +
2160 ((sfreq >> 15) & 0x0001) - 8;
2161
2162 if (header->flags & MAD_FLAG_MPEG_2_5_EXT)
2163 sfreqi += 3;
2164 }
2165
2166 /* scalefactors, Huffman decoding, requantization */
2167
2168 ngr = (header->flags & MAD_FLAG_LSF_EXT) ? 1 : 2;
2169
2170 for (gr = 0; gr < ngr; ++gr) {
2171 struct granule *granule = &si->gr[gr];
2172 unsigned char const *sfbwidth = 0;
2173 mad_fixed_t xr[2][576];
2174 unsigned int ch;
2175 enum mad_error error;
2176
2177 for (ch = 0; ch < nch; ++ch) {
2178 struct channel *channel = &granule->ch[ch];
2179 unsigned int part2_length;
2180
2181 sfbwidth = sfbwidth_table[sfreqi].l;
2182 if (channel->block_type == 2) {
2183 sfbwidth = (channel->flags & mixed_block_flag) ?
2184 sfbwidth_table[sfreqi].m : sfbwidth_table[sfreqi].s;
2185 }
2186
2187 if (header->flags & MAD_FLAG_LSF_EXT) {
2188 part2_length = III_scalefactors_lsf(ptr, channel,
2189 ch == 0 ? 0 : &si->gr[1].ch[1],
2190 header->mode_extension);
2191 }
2192 else {
2193 part2_length = III_scalefactors(ptr, channel, &si->gr[0].ch[ch],
2194 gr == 0 ? 0 : si->scfsi[ch]);
2195 }
2196
2197 error = III_huffdecode(ptr, xr[ch], channel, sfbwidth, part2_length);
2198 if (error)
2199 return error;
2200 }
2201
2202 /* joint stereo processing */
2203
2204 if (header->mode == MAD_MODE_JOINT_STEREO && header->mode_extension) {
2205 error = III_stereo(xr, granule, header, sfbwidth);
2206 if (error)
2207 return error;
2208 }
2209
2210 /* reordering, alias reduction, IMDCT, overlap-add, frequency inversion */
2211
2212 for (ch = 0; ch < nch; ++ch) {
2213 struct channel const *channel = &granule->ch[ch];
2214 mad_fixed_t (*sample)[32] = &frame->sbsample[ch][18 * gr];
2215 unsigned int sb, l, i, sblimit;
2216 mad_fixed_t output[36];
2217
2218 if (channel->block_type == 2) {
2219 III_reorder(xr[ch], channel, sfbwidth_table[sfreqi].s);
2220
2221# if !defined(OPT_STRICT)
2222 /*
2223 * According to ISO/IEC 11172-3, "Alias reduction is not applied for
2224 * granules with block_type == 2 (short block)." However, other
2225 * sources suggest alias reduction should indeed be performed on the
2226 * lower two subbands of mixed blocks. Most other implementations do
2227 * this, so by default we will too.
2228 */
2229 if (channel->flags & mixed_block_flag)
2230 III_aliasreduce(xr[ch], 36);
2231# endif
2232 }
2233 else
2234 III_aliasreduce(xr[ch], 576);
2235
2236 l = 0;
2237
2238 /* subbands 0-1 */
2239
2240 if (channel->block_type != 2 || (channel->flags & mixed_block_flag)) {
2241 unsigned int block_type;
2242
2243 block_type = channel->block_type;
2244 if (channel->flags & mixed_block_flag)
2245 block_type = 0;
2246
2247 /* long blocks */
2248 for (sb = 0; sb < 2; ++sb, l += 18) {
2249 III_imdct_l(&xr[ch][l], output, block_type);
2250 III_overlap(output, (*frame->overlap)[ch][sb], sample, sb);
2251 }
2252 }
2253 else {
2254 /* short blocks */
2255 for (sb = 0; sb < 2; ++sb, l += 18) {
2256 III_imdct_s(&xr[ch][l], output);
2257 III_overlap(output, (*frame->overlap)[ch][sb], sample, sb);
2258 }
2259 }
2260
2261 III_freqinver(sample, 1);
2262
2263 /* (nonzero) subbands 2-31 */
2264
2265 i = 576;
2266 while (i > 36 && xr[ch][i - 1] == 0)
2267 --i;
2268
2269 sblimit = 32 - (576 - i) / 18;
2270
2271 if (channel->block_type != 2) {
2272 /* long blocks */
2273 for (sb = 2; sb < sblimit; ++sb, l += 18) {
2274 III_imdct_l(&xr[ch][l], output, channel->block_type);
2275 III_overlap(output, (*frame->overlap)[ch][sb], sample, sb);
2276
2277 if (sb & 1)
2278 III_freqinver(sample, sb);
2279 }
2280 }
2281 else {
2282 /* short blocks */
2283 for (sb = 2; sb < sblimit; ++sb, l += 18) {
2284 III_imdct_s(&xr[ch][l], output);
2285 III_overlap(output, (*frame->overlap)[ch][sb], sample, sb);
2286
2287 if (sb & 1)
2288 III_freqinver(sample, sb);
2289 }
2290 }
2291
2292 /* remaining (zero) subbands */
2293
2294 for (sb = sblimit; sb < 32; ++sb) {
2295 III_overlap_z((*frame->overlap)[ch][sb], sample, sb);
2296
2297 if (sb & 1)
2298 III_freqinver(sample, sb);
2299 }
2300 }
2301 }
2302
2303 return 0;
2304}
2305
2306/*
2307 * NAME:layer->III()
2308 * DESCRIPTION:decode a single Layer III frame
2309 */
2310int mad_layer_III(struct mad_stream *stream, struct mad_frame *frame)
2311{
2312 struct mad_header *header = &frame->header;
2313 unsigned int nch, priv_bitlen, next_md_begin = 0;
2314 unsigned int si_len, data_bitlen, md_len;
2315 unsigned int frame_space, frame_used, frame_free;
2316 struct mad_bitptr ptr;
2317 struct sideinfo si;
2318 enum mad_error error;
2319 int result = 0;
2320
2321 /* allocate Layer III dynamic structures */
2322
2323 if (stream->main_data == 0) {
2324 stream->main_data = malloc(MAD_BUFFER_MDLEN);
2325 if (stream->main_data == 0) {
2326 stream->error = MAD_ERROR_NOMEM;
2327 return -1;
2328 }
2329 }
2330
2331 if (frame->overlap == 0) {
2332 frame->overlap = calloc(2 * 32 * 18, sizeof(mad_fixed_t));
2333 if (frame->overlap == 0) {
2334 stream->error = MAD_ERROR_NOMEM;
2335 return -1;
2336 }
2337 }
2338
2339 nch = MAD_NCHANNELS(header);
2340 si_len = (header->flags & MAD_FLAG_LSF_EXT) ?
2341 (nch == 1 ? 9 : 17) : (nch == 1 ? 17 : 32);
2342
2343 /* check frame sanity */
2344
2345 if (stream->next_frame - mad_bit_nextbyte(&stream->ptr) <
2346 (signed int) si_len) {
2347 stream->error = MAD_ERROR_BADFRAMELEN;
2348 stream->md_len = 0;
2349 return -1;
2350 }
2351
2352 /* check CRC word */
2353
2354 if (header->flags & MAD_FLAG_PROTECTION) {
2355 header->crc_check =
2356 mad_bit_crc(stream->ptr, si_len * CHAR_BIT, header->crc_check);
2357
2358 if (header->crc_check != header->crc_target &&
2359 !(frame->options & MAD_OPTION_IGNORECRC)) {
2360 stream->error = MAD_ERROR_BADCRC;
2361 result = -1;
2362 }
2363 }
2364
2365 /* decode frame side information */
2366
2367 error = III_sideinfo(&stream->ptr, nch, header->flags & MAD_FLAG_LSF_EXT,
2368 &si, &data_bitlen, &priv_bitlen);
2369 if (error && result == 0) {
2370 stream->error = error;
2371 result = -1;
2372 }
2373
2374 header->flags |= priv_bitlen;
2375 header->private_bits |= si.private_bits;
2376
2377 /* find main_data of next frame */
2378
2379 {
2380 struct mad_bitptr peek;
2381 unsigned long header;
2382
2383 mad_bit_init(&peek, stream->next_frame);
2384
2385 header = mad_bit_read(&peek, 32);
2386 if ((header & 0xffe60000L) /* syncword | layer */ == 0xffe20000L) {
2387 if (!(header & 0x00010000L)) /* protection_bit */
2388 mad_bit_skip(&peek, 16); /* crc_check */
2389
2390 next_md_begin =
2391 mad_bit_read(&peek, (header & 0x00080000L) /* ID */ ? 9 : 8);
2392 }
2393
2394 mad_bit_finish(&peek);
2395 }
2396
2397 /* find main_data of this frame */
2398
2399 frame_space = stream->next_frame - mad_bit_nextbyte(&stream->ptr);
2400
2401 if (next_md_begin > si.main_data_begin + frame_space)
2402 next_md_begin = 0;
2403
2404 md_len = si.main_data_begin + frame_space - next_md_begin;
2405
2406 frame_used = 0;
2407
2408 if (si.main_data_begin == 0) {
2409 ptr = stream->ptr;
2410 stream->md_len = 0;
2411
2412 frame_used = md_len;
2413 }
2414 else {
2415 if (si.main_data_begin > stream->md_len) {
2416 if (result == 0) {
2417 stream->error = MAD_ERROR_BADDATAPTR;
2418 result = -1;
2419 }
2420 }
2421 else {
2422 mad_bit_init(&ptr,
2423 *stream->main_data + stream->md_len - si.main_data_begin);
2424
2425 if (md_len > si.main_data_begin) {
2426 assert(stream->md_len + md_len -
2427 si.main_data_begin <= MAD_BUFFER_MDLEN);
2428
2429 memcpy(*stream->main_data + stream->md_len,
2430 mad_bit_nextbyte(&stream->ptr),
2431 frame_used = md_len - si.main_data_begin);
2432 stream->md_len += frame_used;
2433 }
2434 }
2435 }
2436
2437 frame_free = frame_space - frame_used;
2438
2439 /* decode main_data */
2440
2441 if (result == 0) {
2442 error = III_decode(&ptr, frame, &si, nch);
2443 if (error) {
2444 stream->error = error;
2445 result = -1;
2446 }
2447 }
2448
2449 /* designate ancillary bits */
2450
2451 stream->anc_ptr = ptr;
2452 stream->anc_bitlen = md_len * CHAR_BIT - data_bitlen;
2453
2454# if 0 && defined(DEBUG)
2455 fprintf(stderr,
2456 "main_data_begin:%u, md_len:%u, frame_free:%u, "
2457 "data_bitlen:%u, anc_bitlen: %u\n",
2458 si.main_data_begin, md_len, frame_free,
2459 data_bitlen, stream->anc_bitlen);
2460# endif
2461
2462 /* preload main_data buffer with up to 511 bytes for next frame(s) */
2463
2464 if (frame_free >= next_md_begin) {
2465 memcpy(*stream->main_data,
2466 stream->next_frame - next_md_begin, next_md_begin);
2467 stream->md_len = next_md_begin;
2468 }
2469 else {
2470 if (md_len < si.main_data_begin) {
2471 unsigned int extra;
2472
2473 extra = si.main_data_begin - md_len;
2474 if (extra + frame_free > next_md_begin)
2475 extra = next_md_begin - frame_free;
2476
2477 if (extra < stream->md_len) {
2478 memmove(*stream->main_data,
2479 *stream->main_data + stream->md_len - extra, extra);
2480 stream->md_len = extra;
2481 }
2482 }
2483 else
2484 stream->md_len = 0;
2485
2486 memcpy(*stream->main_data + stream->md_len,
2487 stream->next_frame - frame_free, frame_free);
2488 stream->md_len += frame_free;
2489 }
2490
2491 return result;
2492}
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 @@
1/*
2 * mad - MPEG audio decoder
3 * Copyright (C) 2000-2001 Robert Leslie
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * $Id$
20 */
21
22# ifndef LIBMAD_LAYER3_H
23# define LIBMAD_LAYER3_H
24
25# include "stream.h"
26# include "frame.h"
27
28int mad_layer_III(struct mad_stream *, struct mad_frame *);
29
30# 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 @@
1 TEMPLATE= lib
2 CONFIG += qt warn_on release
3 HEADERS = libmad_version.h fixed.h bit.h timer.h stream.h frame.h synth.h decoder.h \
4 layer12.h layer3.h huffman.h libmad_global.h mad.h libmadplugin.h libmadpluginimpl.h
5 SOURCES = version.c fixed.c bit.c timer.c stream.c frame.c synth.c decoder.c \
6 layer12.c layer3.c huffman.c libmadplugin.cpp libmadpluginimpl.cpp
7 TARGET = madplugin
8 DESTDIR = ../../plugins/codecs
9INCLUDEPATH += $(QPEDIR)/include ..
10DEPENDPATH += ../$(QPEDIR)/include ..
11LIBS += -lqpe -lm
12 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 @@
1/*
2 * mad - MPEG audio decoder
3 * Copyright (C) 2000-2001 Robert Leslie
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * $Id$
20 */
21
22# ifndef LIBMAD_GLOBAL_H
23# define LIBMAD_GLOBAL_H
24
25/* conditional debugging */
26
27# if defined(DEBUG) && defined(NDEBUG)
28# error "cannot define both DEBUG and NDEBUG"
29# endif
30
31# if defined(DEBUG)
32# include <stdio.h>
33# endif
34
35/* conditional features */
36
37# if defined(OPT_SPEED) && defined(OPT_ACCURACY)
38# error "cannot optimize for both speed and accuracy"
39# endif
40
41# if defined(OPT_SPEED) && !defined(OPT_SSO)
42# define OPT_SSO 1
43# endif
44
45# 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 @@
1/*
2 * mad - MPEG audio decoder
3 * Copyright (C) 2000-2001 Robert Leslie
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * $Id$
20 */
21
22# ifndef LIBMAD_VERSION_H
23# define LIBMAD_VERSION_H
24
25 # define MAD_VERSION_MAJOR0
26 # define MAD_VERSION_MINOR13
27 # define MAD_VERSION_PATCH0
28 # define MAD_VERSION_EXTRA" (beta)"
29
30 # define MAD_VERSION_STRINGIZE(str)#str
31 # define MAD_VERSION_STRING(num)MAD_VERSION_STRINGIZE(num)
32
33 # define MAD_VERSION MAD_VERSION_STRING(MAD_VERSION_MAJOR) "." \
34 MAD_VERSION_STRING(MAD_VERSION_MINOR) "." \
35 MAD_VERSION_STRING(MAD_VERSION_PATCH) \
36 MAD_VERSION_EXTRA
37
38 # define MAD_PUBLISHYEAR"2000-2001"
39 # define MAD_AUTHOR "Robert Leslie"
40 # define MAD_EMAIL "rob@mars.org"
41
42extern char const mad_version[];
43extern char const mad_copyright[];
44extern char const mad_author[];
45extern char const mad_build[];
46
47# 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 @@
1/**********************************************************************
2** Copyright (C) 2001 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#include <stdio.h>
21#include <stdarg.h>
22#include <stdlib.h>
23#include <sys/types.h>
24#include <sys/stat.h>
25#include <fcntl.h>
26#include <unistd.h>
27#include <string.h>
28#include <ctype.h>
29#include <errno.h>
30#include <time.h>
31#include <locale.h>
32#include <math.h>
33#include <assert.h>
34#include <qapplication.h>
35
36//#define HAVE_MMAP
37
38#if defined(HAVE_MMAP)
39# include <sys/mman.h>
40#endif
41#include "libmadplugin.h"
42
43
44extern "C" {
45#include "mad.h"
46}
47
48
49#define MPEG_BUFFER_SIZE 65536
50 //#define debugMsg(a) qDebug(a)
51#define debugMsg(a)
52
53
54class Input {
55public:
56 char const *path;
57 int fd;
58#if defined(HAVE_MMAP)
59 void *fdm;
60#endif
61 unsigned char *data;
62 unsigned long length;
63 int eof;
64};
65
66
67class Output {
68public:
69 mad_fixed_t attenuate;
70 struct filter *filters;
71 unsigned int channels_in;
72 unsigned int channels_out;
73 unsigned int speed_in;
74 unsigned int speed_out;
75 const char *path;
76};
77
78
79# if defined(HAVE_MMAP)
80static void *map_file(int fd, unsigned long *length)
81{
82 void *fdm;
83
84 *length += MAD_BUFFER_GUARD;
85
86 fdm = mmap(0, *length, PROT_READ, MAP_SHARED, fd, 0);
87 if (fdm == MAP_FAILED)
88 return 0;
89
90# if defined(HAVE_MADVISE)
91 madvise(fdm, *length, MADV_SEQUENTIAL);
92# endif
93
94 return fdm;
95}
96
97
98static int unmap_file(void *fdm, unsigned long length)
99{
100 if (munmap(fdm, length) == -1)
101 return -1;
102
103 return 0;
104}
105# endif
106
107
108static inline QString tr( const char *str ) {
109 // Apparently this is okay from a plugin as it runs in the process space of the owner of the plugin
110 return qApp->translate( "MediaPlayer", str, "libmad strings for mp3 file info" );
111}
112
113
114class LibMadPluginData {
115public:
116 Input input;
117 Output output;
118 int bad_last_frame;
119 struct mad_stream stream;
120 struct mad_frame frame;
121 struct mad_synth synth;
122 bool flush;
123};
124
125
126LibMadPlugin::LibMadPlugin() {
127 d = new LibMadPluginData;
128 d->input.fd = 0;
129#if defined(HAVE_MMAP)
130 d->input.fdm = 0;
131#endif
132 d->input.data = 0;
133 d->flush = TRUE;
134 info = tr( "No Song Open" );
135}
136
137
138LibMadPlugin::~LibMadPlugin() {
139 close();
140 delete d;
141}
142
143
144bool LibMadPlugin::isFileSupported( const QString& path ) {
145 debugMsg( "LibMadPlugin::isFileSupported" );
146
147 // Mpeg file extensions
148 //"mp2","mp3","m1v","m2v","m2s","mpg","vob","mpeg","ac3"
149 // Other media extensions
150 // "wav","mid","mod","s3m","ogg","avi","mov","sid"
151
152 char *ext = strrchr( path.latin1(), '.' );
153
154 // Test file extension
155 if ( ext ) {
156 if ( strncasecmp(ext, ".mp2", 4) == 0 )
157 return TRUE;
158 if ( strncasecmp(ext, ".mp3", 4) == 0 )
159 return TRUE;
160 }
161
162 return FALSE;
163}
164
165
166bool LibMadPlugin::open( const QString& path ) {
167 debugMsg( "LibMadPlugin::open" );
168
169 d->bad_last_frame = 0;
170 d->flush = TRUE;
171 info = QString( "" );
172
173 //qDebug( "Opening %s", path.latin1() );
174
175 d->input.path = path.latin1();
176 d->input.fd = ::open( d->input.path, O_RDONLY );
177 if (d->input.fd == -1) {
178 qDebug("error opening %s", d->input.path );
179 return FALSE;
180 }
181
182 printID3Tags();
183
184#if defined(HAVE_MMAP)
185 struct stat stat;
186 if (fstat(d->input.fd, &stat) == -1) {
187 qDebug("error calling fstat"); return FALSE;
188 }
189 if (S_ISREG(stat.st_mode) && stat.st_size > 0) {
190 d->input.length = stat.st_size;
191 d->input.fdm = map_file(d->input.fd, &d->input.length);
192 if (d->input.fdm == 0) {
193 qDebug("error mmapping file"); return FALSE;
194 }
195 d->input.data = (unsigned char *)d->input.fdm;
196 }
197#endif
198
199 if (d->input.data == 0) {
200 d->input.data = (unsigned char *)malloc(MPEG_BUFFER_SIZE);
201 if (d->input.data == 0) {
202 qDebug("error allocating input buffer");
203 return FALSE;
204 }
205 d->input.length = 0;
206 }
207
208 d->input.eof = 0;
209
210 mad_stream_init(&d->stream);
211 mad_frame_init(&d->frame);
212 mad_synth_init(&d->synth);
213
214 return TRUE;
215}
216
217
218bool LibMadPlugin::close() {
219 debugMsg( "LibMadPlugin::close" );
220
221 int result = TRUE;
222
223 mad_synth_finish(&d->synth);
224 mad_frame_finish(&d->frame);
225 mad_stream_finish(&d->stream);
226
227#if defined(HAVE_MMAP)
228 if (d->input.fdm) {
229 if (unmap_file(d->input.fdm, d->input.length) == -1) {
230 qDebug("error munmapping file");
231 result = FALSE;
232 }
233 d->input.fdm = 0;
234 d->input.data = 0;
235 }
236#endif
237
238 if (d->input.data) {
239 free(d->input.data);
240 d->input.data = 0;
241 }
242
243 if (::close(d->input.fd) == -1) {
244 qDebug("error closing file %s", d->input.path);
245 result = FALSE;
246 }
247
248 d->input.fd = 0;
249
250 return result;
251}
252
253
254bool LibMadPlugin::isOpen() {
255 debugMsg( "LibMadPlugin::isOpen" );
256 return ( d->input.fd != 0 );
257}
258
259
260int LibMadPlugin::audioStreams() {
261 debugMsg( "LibMadPlugin::audioStreams" );
262 return 1;
263}
264
265
266int LibMadPlugin::audioChannels( int ) {
267 debugMsg( "LibMadPlugin::audioChannels" );
268/*
269 long t; short t1[5]; audioReadSamples( t1, 2, 1, t, 0 );
270 qDebug( "LibMadPlugin::audioChannels: %i", d->frame.header.mode > 0 ? 2 : 1 );
271 return d->frame.header.mode > 0 ? 2 : 1;
272*/
273 return 2;
274}
275
276
277int LibMadPlugin::audioFrequency( int ) {
278 debugMsg( "LibMadPlugin::audioFrequency" );
279 long t; short t1[5]; audioReadSamples( t1, 2, 1, t, 0 );
280 qDebug( "LibMadPlugin::audioFrequency: %i", d->frame.header.samplerate );
281 return d->frame.header.samplerate;
282}
283
284
285int LibMadPlugin::audioSamples( int ) {
286 debugMsg( "LibMadPlugin::audioSamples" );
287/*
288 long t; short t1[5]; audioReadSamples( t1, 2, 1, t, 0 );
289 mad_header_decode( (struct mad_header *)&d->frame.header, &d->stream );
290 qDebug( "LibMadPlugin::audioSamples: %i*%i", d->frame.header.duration.seconds, d->frame.header.samplerate );
291 return d->frame.header.duration.seconds * d->frame.header.samplerate;
292*/
293 return 10000000;
294}
295
296
297bool LibMadPlugin::audioSetSample( long, int ) {
298 debugMsg( "LibMadPlugin::audioSetSample" );
299 return FALSE;
300}
301
302
303long LibMadPlugin::audioGetSample( int ) {
304 debugMsg( "LibMadPlugin::audioGetSample" );
305 return 0;
306}
307
308/*
309bool LibMadPlugin::audioReadSamples( short *, int, long, int ) {
310 debugMsg( "LibMadPlugin::audioReadSamples" );
311 return FALSE;
312}
313
314
315bool LibMadPlugin::audioReReadSamples( short *, int, long, int ) {
316 debugMsg( "LibMadPlugin::audioReReadSamples" );
317 return FALSE;
318}
319*/
320
321bool LibMadPlugin::read() {
322 debugMsg( "LibMadPlugin::read" );
323 int len;
324
325 if (d->input.eof)
326 return FALSE;
327
328#if defined(HAVE_MMAP)
329 if (d->input.fdm) {
330 unsigned long skip = 0;
331
332 if (d->stream.next_frame) {
333 struct stat stat;
334
335 if (fstat(d->input.fd, &stat) == -1)
336 return FALSE;
337
338 if (stat.st_size + MAD_BUFFER_GUARD <= (signed)d->input.length)
339 return FALSE;
340
341 // file size changed; update memory map
342 skip = d->stream.next_frame - d->input.data;
343
344 if (unmap_file(d->input.fdm, d->input.length) == -1) {
345 d->input.fdm = 0;
346 d->input.data = 0;
347 return FALSE;
348 }
349
350 d->input.length = stat.st_size;
351
352 d->input.fdm = map_file(d->input.fd, &d->input.length);
353 if (d->input.fdm == 0) {
354 d->input.data = 0;
355 return FALSE;
356 }
357
358 d->input.data = (unsigned char *)d->input.fdm;
359 }
360
361 mad_stream_buffer(&d->stream, d->input.data + skip, d->input.length - skip);
362
363 } else
364#endif
365 {
366 if (d->stream.next_frame) {
367 memmove(d->input.data, d->stream.next_frame,
368 d->input.length = &d->input.data[d->input.length] - d->stream.next_frame);
369 }
370
371 do {
372 len = ::read(d->input.fd, d->input.data + d->input.length, MPEG_BUFFER_SIZE - d->input.length);
373 }
374 while (len == -1 && errno == EINTR);
375
376 if (len == -1) {
377 qDebug("error reading audio");
378 return FALSE;
379 }
380 else if (len == 0) {
381 d->input.eof = 1;
382
383 assert(MPEG_BUFFER_SIZE - d->input.length >= MAD_BUFFER_GUARD);
384
385 while (len < MAD_BUFFER_GUARD)
386 d->input.data[d->input.length + len++] = 0;
387 }
388
389 mad_stream_buffer(&d->stream, d->input.data, d->input.length += len);
390 }
391
392 return TRUE;
393}
394
395
396static mad_fixed_t left_err, right_err;
397static const int bits = 16;
398static const int shift = MAD_F_FRACBITS + 1 - bits;
399
400
401inline long audio_linear_dither( mad_fixed_t sample, mad_fixed_t& error )
402{
403 sample += error;
404 mad_fixed_t quantized = (sample >= MAD_F_ONE) ? MAD_F_ONE - 1 : ( (sample < -MAD_F_ONE) ? -MAD_F_ONE : sample );
405 quantized &= ~((1L << shift) - 1);
406 error = sample - quantized;
407 return quantized >> shift;
408}
409
410
411inline void audio_pcm( short *data, unsigned int nsamples, mad_fixed_t *left, mad_fixed_t *right )
412{
413 if ( right ) {
414 while (nsamples--) {
415 data[0] = audio_linear_dither( *left++, left_err );
416 data[1] = audio_linear_dither( *right++, right_err );
417 data += 2;
418 }
419 } else {
420 while (nsamples--) {
421 data[0] = data[1] = audio_linear_dither( *left++, left_err );
422 data += 2;
423 }
424 }
425}
426
427
428bool LibMadPlugin::decode( short *output, long samples, long& samplesMade ) {
429 debugMsg( "LibMadPlugin::decode" );
430
431 static int buffered = 0;
432 static mad_fixed_t buffer[2][65536 * 2];
433 int offset = buffered;
434 samplesMade = 0;
435
436 static int maxBuffered = 8000; // 65536;
437
438 if ( samples > maxBuffered )
439 samples = maxBuffered;
440
441 if ( d->flush ) {
442 buffered = 0;
443 offset = 0;
444 d->flush = FALSE;
445 }
446
447 while ( buffered < maxBuffered ) {
448
449 while (mad_frame_decode(&d->frame, &d->stream) == -1) {
450 if (!MAD_RECOVERABLE(d->stream.error)) {
451 debugMsg( "feed me" );
452 return FALSE; // Feed me
453 }
454 if ( d->stream.error == MAD_ERROR_BADCRC ) {
455 mad_frame_mute(&d->frame);
456 qDebug( "error decoding, bad crc" );
457 }
458 }
459
460 mad_synth_frame(&d->synth, &d->frame);
461 int decodedSamples = d->synth.pcm.length;
462 memcpy( &(buffer[0][offset]), d->synth.pcm.samples[0], decodedSamples * sizeof(mad_fixed_t) );
463 if ( d->synth.pcm.channels == 2 )
464 memcpy( &(buffer[1][offset]), d->synth.pcm.samples[1], decodedSamples * sizeof(mad_fixed_t) );
465 offset += decodedSamples;
466 buffered += decodedSamples;
467 }
468
469 audio_pcm( output, samples, buffer[0], (d->synth.pcm.channels == 2) ? buffer[1] : 0 );
470// audio_pcm( output, samples, buffer[1], buffer[0] );
471// audio_pcm( output, samples, buffer[0], buffer[1] );
472 samplesMade = samples;
473 memmove( buffer[0], &(buffer[0][samples]), (buffered - samples) * sizeof(mad_fixed_t) );
474 if ( d->synth.pcm.channels == 2 )
475 memmove( buffer[1], &(buffer[1][samples]), (buffered - samples) * sizeof(mad_fixed_t) );
476 buffered -= samples;
477
478 return TRUE;
479}
480
481/*
482bool LibMadPlugin::audioReadMonoSamples( short *, long, long&, int ) {
483 debugMsg( "LibMadPlugin::audioReadMonoSamples" );
484 return FALSE;
485}
486
487
488bool LibMadPlugin::audioReadStereoSamples( short *output, long samples, long& samplesMade, int ) {
489*/
490bool LibMadPlugin::audioReadSamples( short *output, int /*channels*/, long samples, long& samplesMade, int ) {
491 debugMsg( "LibMadPlugin::audioReadStereoSamples" );
492
493 static bool needInput = TRUE;
494
495 if ( samples == 0 )
496 return TRUE;
497
498 do {
499 if ( needInput )
500 if ( !read() ) {
501 // if ( d->input.eof )
502 // needInput = FALSE;
503 // else
504 return TRUE;
505 }
506
507 needInput = FALSE;
508
509 if ( decode( output, samples, samplesMade ) )
510 return FALSE;
511 else
512 needInput = TRUE;
513 }
514 while ( ( samplesMade < samples ) && ( !d->input.eof ) );
515/*
516 static bool firstTimeThru = TRUE;
517
518 if ( firstTimeThru ) {
519 firstTimeThru = FALSE;
520 decode( output, samples, samplesMade );
521 return FALSE;
522 } else
523*/
524 return TRUE;
525}
526
527
528double LibMadPlugin::getTime() {
529 debugMsg( "LibMadPlugin::getTime" );
530 return 0.0;
531}
532
533
534void LibMadPlugin::printID3Tags() {
535 debugMsg( "LibMadPlugin::printID3Tags" );
536
537 char id3v1[128 + 1];
538
539 if ( ::lseek( d->input.fd, -128, SEEK_END ) == -1 ) {
540 qDebug( "error seeking to id3 tags" );
541 return;
542 }
543
544 if ( ::read( d->input.fd, id3v1, 128 ) != 128 ) {
545 qDebug( "error reading in id3 tags" );
546 return;
547 }
548
549 if ( ::strncmp( (const char *)id3v1, "TAG", 3 ) != 0 ) {
550 debugMsg( "sorry, no id3 tags" );
551 } else {
552 int len[5] = { 30, 30, 30, 4, 30 };
553 QString label[5] = { tr( "Title" ), tr( "Artist" ), tr( "Album" ), tr( "Year" ), tr( "Comment" ) };
554 char *ptr = id3v1 + 3, *ptr2 = ptr + len[0];
555 qDebug( "ID3 tags in file:" );
556 info = "";
557 for ( int i = 0; i < 5; ptr += len[i], i++, ptr2 += len[i] ) {
558 char push = *ptr2;
559 *ptr2 = '\0';
560 char *ptr3 = ptr2;
561 while ( ptr3-1 >= ptr && isspace(ptr3[-1]) ) ptr3--;
562 char push2 = *ptr3; *ptr3 = '\0';
563 if ( strcmp( ptr, "" ) )
564 info += ( i != 0 ? ", " : "" ) + label[i] + ": " + ptr;
565 //qDebug( info.latin1() );
566 *ptr3 = push2;
567 *ptr2 = push;
568 }
569 if (id3v1[126] == 0 && id3v1[127] != 0)
570 info += tr( ", Track: " ) + id3v1[127];
571 }
572
573 if ( ::lseek(d->input.fd, 0, SEEK_SET) == -1 ) {
574 qDebug( "error seeking back to beginning" );
575 return;
576 }
577}
578
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 @@
1/**********************************************************************
2** Copyright (C) 2001 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef LIBMAD_PLUGIN_H
21#define LIBMAD_PLUGIN_H
22
23
24#include <qstring.h>
25#include "mediaplayerplugininterface.h"
26
27
28class LibMadPluginData;
29
30
31class LibMadPlugin : public MediaPlayerDecoder {
32
33public:
34 LibMadPlugin();
35 ~LibMadPlugin();
36
37 const char *pluginName() { return "LibMadPlugin"; }
38 const char *pluginComment() { return "This is the libmad library that has been wrapped as a plugin"; }
39 double pluginVersion() { return 1.0; }
40
41 bool isFileSupported( const QString& );
42 bool open( const QString& );
43 bool close();
44 bool isOpen();
45 const QString &fileInfo() { return info; }
46
47 // If decoder doesn't support audio then return 0 here
48 int audioStreams();
49 int audioChannels( int stream );
50 int audioFrequency( int stream );
51 int audioSamples( int stream );
52 bool audioSetSample( long sample, int stream );
53 long audioGetSample( int stream );
54// bool audioReadMonoSamples( short *output, long samples, long& samplesRead, int stream );
55// bool audioReadStereoSamples( short *output, long samples, long& samplesRead, int stream );
56 bool audioReadSamples( short *output, int channels, long samples, long& samplesRead, int stream );
57// bool audioReadSamples( short *output, int channel, long samples, int stream );
58// bool audioReReadSamples( short *output, int channel, long samples, int stream );
59
60
61 bool read();
62 bool decode( short *output, long samples, long& samplesRead );
63 void printID3Tags();
64
65
66 // If decoder doesn't support video then return 0 here
67 int videoStreams() { return 0; }
68 int videoWidth( int ) { return 0; }
69 int videoHeight( int ) { return 0; }
70 double videoFrameRate( int ) { return 0.0; }
71 int videoFrames( int ) { return 0; }
72 bool videoSetFrame( long, int ) { return FALSE; }
73 long videoGetFrame( int ) { return 0; }
74 bool videoReadFrame( unsigned char **, int, int, int, int, ColorFormat, int ) { return FALSE; }
75 bool videoReadScaledFrame( unsigned char **, int, int, int, int, int, int, ColorFormat, int ) { return FALSE; }
76 bool videoReadYUVFrame( char *, char *, char *, int, int, int, int, int ) { return FALSE; }
77
78 // Profiling
79 double getTime();
80
81 // Ignore if these aren't supported
82 bool setSMP( int ) { return FALSE; }
83 bool setMMX( bool ) { return FALSE; }
84
85 // Capabilities
86 bool supportsAudio() { return TRUE; }
87 bool supportsVideo() { return FALSE; }
88 bool supportsYUV() { return FALSE; }
89 bool supportsMMX() { return TRUE; }
90 bool supportsSMP() { return FALSE; }
91 bool supportsStereo() { return TRUE; }
92 bool supportsScaling() { return FALSE; }
93
94private:
95 LibMadPluginData *d;
96 QString info;
97
98};
99
100
101#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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#include "libmadplugin.h"
21#include "libmadpluginimpl.h"
22
23
24LibMadPluginImpl::LibMadPluginImpl()
25 : libmadplugin(0), ref(0)
26{
27}
28
29
30LibMadPluginImpl::~LibMadPluginImpl()
31{
32 if ( libmadplugin )
33 delete libmadplugin;
34}
35
36
37MediaPlayerDecoder *LibMadPluginImpl::decoder()
38{
39 if ( !libmadplugin )
40 libmadplugin = new LibMadPlugin;
41 return libmadplugin;
42}
43
44
45MediaPlayerEncoder *LibMadPluginImpl::encoder()
46{
47 return NULL;
48}
49
50
51#ifndef QT_NO_COMPONENT
52
53
54QRESULT LibMadPluginImpl::queryInterface( const QUuid &uuid, QUnknownInterface **iface )
55{
56 *iface = 0;
57 if ( ( uuid == IID_QUnknown ) || ( uuid == IID_MediaPlayerPlugin ) )
58 *iface = this, (*iface)->addRef();
59 return QS_OK;
60}
61
62
63Q_EXPORT_INTERFACE()
64{
65 Q_CREATE_INSTANCE( LibMadPluginImpl )
66}
67
68
69#endif
70
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 @@
1/**********************************************************************
2** Copyright (C) 2001 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef LIBMAD_PLUGIN_IMPL_H
21#define LIBMAD_PLUGIN_IMPL_H
22
23
24#include "../mediaplayerplugininterface.h"
25
26
27class LibMadPlugin;
28
29
30class LibMadPluginImpl : public MediaPlayerPluginInterface
31{
32public:
33 LibMadPluginImpl();
34 virtual ~LibMadPluginImpl();
35
36#ifndef QT_NO_COMPONENT
37
38 QRESULT queryInterface( const QUuid&, QUnknownInterface** );
39 Q_REFCOUNT
40
41#endif
42
43 virtual MediaPlayerDecoder *decoder();
44 virtual MediaPlayerEncoder *encoder();
45
46private:
47 LibMadPlugin *libmadplugin;
48 ulong ref;
49};
50
51
52#endif
53
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 @@
1/*
2 * mad - MPEG audio decoder
3 * Copyright (C) 2000-2001 Robert Leslie
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * If you would like to negotiate alternate licensing terms, you may do
20 * so by contacting the author: Robert Leslie <rob@mars.org>
21 */
22
23# define SIZEOF_INT 4
24# define SIZEOF_LONG 4
25# define SIZEOF_LONG_LONG 8
26
27/* Id: version.h,v 1.16 2001/04/05 04:57:11 rob Exp */
28
29# ifndef LIBMAD_VERSION_H
30# define LIBMAD_VERSION_H
31
32 # define MAD_VERSION_MAJOR0
33 # define MAD_VERSION_MINOR13
34 # define MAD_VERSION_PATCH0
35 # define MAD_VERSION_EXTRA" (beta)"
36
37 # define MAD_VERSION_STRINGIZE(str)#str
38 # define MAD_VERSION_STRING(num)MAD_VERSION_STRINGIZE(num)
39
40 # define MAD_VERSION MAD_VERSION_STRING(MAD_VERSION_MAJOR) "." \
41 MAD_VERSION_STRING(MAD_VERSION_MINOR) "." \
42 MAD_VERSION_STRING(MAD_VERSION_PATCH) \
43 MAD_VERSION_EXTRA
44
45 # define MAD_PUBLISHYEAR"2000-2001"
46 # define MAD_AUTHOR "Robert Leslie"
47 # define MAD_EMAIL "rob@mars.org"
48
49extern char const mad_version[];
50extern char const mad_copyright[];
51extern char const mad_author[];
52extern char const mad_build[];
53
54# endif
55
56/* Id: fixed.h,v 1.23 2001/04/05 04:57:11 rob Exp */
57
58# ifndef LIBMAD_FIXED_H
59# define LIBMAD_FIXED_H
60
61# if SIZEOF_INT >= 4
62typedef signed int mad_fixed_t;
63
64typedef signed int mad_fixed64hi_t;
65typedef unsigned int mad_fixed64lo_t;
66# else
67typedef signed long mad_fixed_t;
68
69typedef signed long mad_fixed64hi_t;
70typedef unsigned long mad_fixed64lo_t;
71# endif
72
73/*
74 * Fixed-point format: 0xABBBBBBB
75 * A == whole part (sign + 3 bits)
76 * B == fractional part (28 bits)
77 *
78 * Values are signed two's complement, so the effective range is:
79 * 0x80000000 to 0x7fffffff
80 * -8.0 to +7.9999999962747097015380859375
81 *
82 * The smallest representable value is:
83 * 0x00000001 == 0.0000000037252902984619140625 (i.e. about 3.725e-9)
84 *
85 * 28 bits of fractional accuracy represent about
86 * 8.6 digits of decimal accuracy.
87 *
88 * Fixed-point numbers can be added or subtracted as normal
89 * integers, but multiplication requires shifting the 64-bit result
90 * from 56 fractional bits back to 28 (and rounding.)
91 *
92 * Changing the definition of MAD_F_FRACBITS is only partially
93 * supported, and must be done with care.
94 */
95
96 # define MAD_F_FRACBITS 28
97
98# if MAD_F_FRACBITS == 28
99 # define MAD_F(x) ((mad_fixed_t) (x##L))
100# else
101# if MAD_F_FRACBITS < 28
102# warning "MAD_F_FRACBITS < 28"
103 # define MAD_F(x) ((mad_fixed_t) \
104 (((x##L) + \
105 (1L << (28 - MAD_F_FRACBITS - 1))) >> \
106 (28 - MAD_F_FRACBITS)))
107# elif MAD_F_FRACBITS > 28
108# error "MAD_F_FRACBITS > 28 not currently supported"
109 # define MAD_F(x) ((mad_fixed_t) \
110 ((x##L) << (MAD_F_FRACBITS - 28)))
111# endif
112# endif
113
114 # define MAD_F_MIN ((mad_fixed_t) -0x80000000L)
115 # define MAD_F_MAX ((mad_fixed_t) +0x7fffffffL)
116
117 # define MAD_F_ONE MAD_F(0x10000000)
118
119 # define mad_f_tofixed(x)((mad_fixed_t) \
120 ((x) * (double) (1L << MAD_F_FRACBITS) + 0.5))
121 # define mad_f_todouble(x)((double) \
122 ((x) / (double) (1L << MAD_F_FRACBITS)))
123
124 # define mad_f_intpart(x)((x) >> MAD_F_FRACBITS)
125 # define mad_f_fracpart(x)((x) & ((1L << MAD_F_FRACBITS) - 1))
126 /* (x should be positive) */
127
128 # define mad_f_fromint(x)((x) << MAD_F_FRACBITS)
129
130 # define mad_f_add(x, y)((x) + (y))
131 # define mad_f_sub(x, y)((x) - (y))
132
133# if defined(FPM_64BIT)
134
135/*
136 * This version should be the most accurate if 64-bit (long long) types are
137 * supported by the compiler, although it may not be the most efficient.
138 */
139# if defined(OPT_ACCURACY)
140# define mad_f_mul(x, y) \
141 ((mad_fixed_t) \
142 ((((signed long long) (x) * (y)) + \
143 (1L << (MAD_F_SCALEBITS - 1))) >> MAD_F_SCALEBITS))
144# else
145# define mad_f_mul(x, y) \
146 ((mad_fixed_t) (((signed long long) (x) * (y)) >> MAD_F_SCALEBITS))
147# endif
148
149# define MAD_F_SCALEBITS MAD_F_FRACBITS
150
151/* --- Intel --------------------------------------------------------------- */
152
153# elif defined(FPM_INTEL)
154
155/*
156 * This Intel version is fast and accurate; the disposition of the least
157 * significant bit depends on OPT_ACCURACY via mad_f_scale64().
158 */
159# define MAD_F_MLX(hi, lo, x, y) \
160 asm ("imull %3" \
161 : "=a" (lo), "=d" (hi) \
162 : "%a" (x), "rm" (y) \
163 : "cc")
164
165# if defined(OPT_ACCURACY)
166/*
167 * This gives best accuracy but is not very fast.
168 */
169# define MAD_F_MLA(hi, lo, x, y) \
170 ({ mad_fixed64hi_t __hi; \
171 mad_fixed64lo_t __lo; \
172 MAD_F_MLX(__hi, __lo, (x), (y)); \
173 asm ("addl %2,%0\n\t" \
174 "adcl %3,%1" \
175 : "=rm" (lo), "=rm" (hi) \
176 : "r" (__lo), "r" (__hi), "0" (lo), "1" (hi) \
177 : "cc"); \
178 })
179# endif /* OPT_ACCURACY */
180
181# if defined(OPT_ACCURACY)
182/*
183 * Surprisingly, this is faster than SHRD followed by ADC.
184 */
185# define mad_f_scale64(hi, lo) \
186 ({ mad_fixed64hi_t __hi_; \
187 mad_fixed64lo_t __lo_; \
188 mad_fixed_t __result; \
189 asm ("addl %4,%2\n\t" \
190 "adcl %5,%3" \
191 : "=rm" (__lo_), "=rm" (__hi_) \
192 : "0" (lo), "1" (hi), \
193 "ir" (1L << (MAD_F_SCALEBITS - 1)), "ir" (0) \
194 : "cc"); \
195 asm ("shrdl %3,%2,%1" \
196 : "=rm" (__result) \
197 : "0" (__lo_), "r" (__hi_), "I" (MAD_F_SCALEBITS) \
198 : "cc"); \
199 __result; \
200 })
201# else
202# define mad_f_scale64(hi, lo) \
203 ({ mad_fixed_t __result; \
204 asm ("shrdl %3,%2,%1" \
205 : "=rm" (__result) \
206 : "0" (lo), "r" (hi), "I" (MAD_F_SCALEBITS) \
207 : "cc"); \
208 __result; \
209 })
210# endif /* OPT_ACCURACY */
211
212# define MAD_F_SCALEBITS MAD_F_FRACBITS
213
214/* --- ARM ----------------------------------------------------------------- */
215
216# elif defined(FPM_ARM)
217
218/*
219 * This ARM V4 version is as accurate as FPM_64BIT but much faster. The
220 * least significant bit is properly rounded at no CPU cycle cost!
221 */
222# if 1
223/*
224 * There's a bug somewhere, possibly in the compiler, that sometimes makes
225 * this necessary instead of the default implementation via MAD_F_MLX and
226 * mad_f_scale64. It may be related to the use (or lack) of
227 * -finline-functions and/or -fstrength-reduce.
228 *
229 * This is also apparently faster than MAD_F_MLX/mad_f_scale64.
230 */
231# define mad_f_mul(x, y) \
232 ({ mad_fixed64hi_t __hi; \
233 mad_fixed64lo_t __lo; \
234 mad_fixed_t __result; \
235 asm ("smull%0, %1, %3, %4\n\t" \
236 "movs%0, %0, lsr %5\n\t" \
237 "adc%2, %0, %1, lsl %6" \
238 : "=&r" (__lo), "=&r" (__hi), "=r" (__result) \
239 : "%r" (x), "r" (y), \
240 "M" (MAD_F_SCALEBITS), "M" (32 - MAD_F_SCALEBITS) \
241 : "cc"); \
242 __result; \
243 })
244# endif
245
246# define MAD_F_MLX(hi, lo, x, y) \
247 asm ("smull%0, %1, %2, %3" \
248 : "=&r" (lo), "=&r" (hi) \
249 : "%r" (x), "r" (y))
250
251# define MAD_F_MLA(hi, lo, x, y) \
252 asm ("smlal%0, %1, %2, %3" \
253 : "+r" (lo), "+r" (hi) \
254 : "%r" (x), "r" (y))
255
256# define mad_f_scale64(hi, lo) \
257 ({ mad_fixed_t __result; \
258 asm ("movs%0, %1, lsr %3\n\t" \
259 "adc%0, %0, %2, lsl %4" \
260 : "=r" (__result) \
261 : "r" (lo), "r" (hi), \
262 "M" (MAD_F_SCALEBITS), "M" (32 - MAD_F_SCALEBITS) \
263 : "cc"); \
264 __result; \
265 })
266
267# define MAD_F_SCALEBITS MAD_F_FRACBITS
268
269/* --- MIPS ---------------------------------------------------------------- */
270
271# elif defined(FPM_MIPS)
272
273/*
274 * This MIPS version is fast and accurate; the disposition of the least
275 * significant bit depends on OPT_ACCURACY via mad_f_scale64().
276 */
277# define MAD_F_MLX(hi, lo, x, y) \
278 asm ("mult%2,%3" \
279 : "=l" (lo), "=h" (hi) \
280 : "%r" (x), "r" (y))
281
282# if defined(HAVE_MADD_ASM)
283# define MAD_F_MLA(hi, lo, x, y) \
284 asm ("madd%2,%3" \
285 : "+l" (lo), "+h" (hi) \
286 : "%r" (x), "r" (y))
287# elif defined(HAVE_MADD16_ASM)
288/*
289 * This loses significant accuracy due to the 16-bit integer limit in the
290 * multiply/accumulate instruction.
291 */
292# define MAD_F_ML0(hi, lo, x, y) \
293 asm ("mult%2,%3" \
294 : "=l" (lo), "=h" (hi) \
295 : "%r" ((x) >> 12), "r" ((y) >> 16))
296# define MAD_F_MLA(hi, lo, x, y) \
297 asm ("madd16%2,%3" \
298 : "+l" (lo), "+h" (hi) \
299 : "%r" ((x) >> 12), "r" ((y) >> 16))
300# define MAD_F_MLZ(hi, lo) ((mad_fixed_t) (lo))
301# endif
302
303# if defined(OPT_SPEED)
304# define mad_f_scale64(hi, lo) \
305 ((mad_fixed_t) ((hi) << (32 - MAD_F_SCALEBITS)))
306# define MAD_F_SCALEBITS MAD_F_FRACBITS
307# endif
308
309/* --- SPARC --------------------------------------------------------------- */
310
311# elif defined(FPM_SPARC)
312
313/*
314 * This SPARC V8 version is fast and accurate; the disposition of the least
315 * significant bit depends on OPT_ACCURACY via mad_f_scale64().
316 */
317# define MAD_F_MLX(hi, lo, x, y) \
318 asm ("smul %2, %3, %0\n\t" \
319 "rd %%y, %1" \
320 : "=r" (lo), "=r" (hi) \
321 : "%r" (x), "rI" (y))
322
323/* --- PowerPC ------------------------------------------------------------- */
324
325# elif defined(FPM_PPC)
326
327/*
328 * This PowerPC version is tuned for the 4xx embedded processors. It is
329 * effectively a tuned version of FPM_64BIT. It is a little faster and just
330 * as accurate. The disposition of the least significant bit depends on
331 * OPT_ACCURACY via mad_f_scale64().
332 */
333# define MAD_F_MLX(hi, lo, x, y) \
334 asm ("mulhw %1, %2, %3\n\t" \
335 "mullw %0, %2, %3" \
336 : "=&r" (lo), "=&r" (hi) \
337 : "%r" (x), "r" (y))
338
339# define MAD_F_MLA(hi, lo, x, y) \
340 ({ mad_fixed64hi_t __hi; \
341 mad_fixed64lo_t __lo; \
342 MAD_F_MLX(__hi, __lo, (x), (y)); \
343 asm ("addc %0, %2, %3\n\t" \
344 "adde %1, %4, %5" \
345 : "=r" (lo), "=r" (hi) \
346 : "%r" (__lo), "0" (lo), "%r" (__hi), "1" (hi)); \
347 })
348
349# if defined(OPT_ACCURACY)
350/*
351 * This is accurate and ~2 - 2.5 times slower than the unrounded version.
352 *
353 * The __volatile__ improves the generated code by another 5% (fewer spills
354 * to memory); eventually they should be removed.
355 */
356# define mad_f_scale64(hi, lo) \
357 ({ mad_fixed_t __result; \
358 mad_fixed64hi_t __hi_; \
359 mad_fixed64lo_t __lo_; \
360 asm __volatile__ ("addc %0, %2, %4\n\t" \
361 "addze %1, %3" \
362 : "=r" (__lo_), "=r" (__hi_) \
363 : "r" (lo), "r" (hi), "r" (1 << (MAD_F_SCALEBITS - 1))); \
364 asm __volatile__ ("rlwinm %0, %2,32-%3,0,%3-1\n\t" \
365 "rlwimi %0, %1,32-%3,%3,31" \
366 : "=&r" (__result) \
367 : "r" (__lo_), "r" (__hi_), "I" (MAD_F_SCALEBITS)); \
368 __result; \
369 })
370# else
371# define mad_f_scale64(hi, lo) \
372 ({ mad_fixed_t __result; \
373 asm ("rlwinm %0, %2,32-%3,0,%3-1\n\t" \
374 "rlwimi %0, %1,32-%3,%3,31" \
375 : "=r" (__result) \
376 : "r" (lo), "r" (hi), "I" (MAD_F_SCALEBITS)); \
377 __result; \
378 })
379# endif /* OPT_ACCURACY */
380
381# define MAD_F_SCALEBITS MAD_F_FRACBITS
382
383/* --- Default ------------------------------------------------------------- */
384
385# elif defined(FPM_DEFAULT)
386
387/*
388 * This version is the most portable but it loses significant accuracy.
389 * Furthermore, accuracy is biased against the second argument, so care
390 * should be taken when ordering operands.
391 *
392 * The scale factors are constant as this is not used with SSO.
393 *
394 * Pre-rounding is required to stay within the limits of compliance.
395 */
396 # define mad_f_mul(x, y)((((x) + (1L << 11)) >> 12) * \
397 (((y) + (1L << 15)) >> 16))
398
399/* ------------------------------------------------------------------------- */
400
401# else
402# error "no FPM selected"
403# endif
404
405/* default implementations */
406
407# if !defined(mad_f_mul)
408# define mad_f_mul(x, y) \
409 ({ mad_fixed64hi_t __hi; \
410 mad_fixed64lo_t __lo; \
411 MAD_F_MLX(__hi, __lo, (x), (y)); \
412 mad_f_scale64(__hi, __lo); \
413 })
414# endif
415
416# if !defined(MAD_F_MLA)
417 # define MAD_F_ML0(hi, lo, x, y)((lo) = mad_f_mul((x), (y)))
418 # define MAD_F_MLA(hi, lo, x, y)((lo) += mad_f_mul((x), (y)))
419 # define MAD_F_MLZ(hi, lo) ((void) (hi), (mad_fixed_t) (lo))
420# endif
421
422# if !defined(MAD_F_ML0)
423 # define MAD_F_ML0(hi, lo, x, y)MAD_F_MLX((hi), (lo), (x), (y))
424# endif
425
426# if !defined(MAD_F_MLZ)
427 # define MAD_F_MLZ(hi, lo) mad_f_scale64((hi), (lo))
428# endif
429
430# if !defined(mad_f_scale64)
431# if defined(OPT_ACCURACY)
432# define mad_f_scale64(hi, lo) \
433 ((((mad_fixed_t) \
434 (((hi) << (32 - (MAD_F_SCALEBITS - 1))) | \
435 ((lo) >> (MAD_F_SCALEBITS - 1)))) + 1) >> 1)
436# else
437# define mad_f_scale64(hi, lo) \
438 ((mad_fixed_t) \
439 (((hi) << (32 - MAD_F_SCALEBITS)) | \
440 ((lo) >> MAD_F_SCALEBITS)))
441# endif
442# define MAD_F_SCALEBITS MAD_F_FRACBITS
443# endif
444
445/* miscellaneous C routines */
446
447mad_fixed_t mad_f_abs(mad_fixed_t);
448
449# endif
450
451/* Id: bit.h,v 1.7 2001/04/05 04:57:11 rob Exp */
452
453# ifndef LIBMAD_BIT_H
454# define LIBMAD_BIT_H
455
456struct mad_bitptr {
457 unsigned char const *byte;
458 unsigned short cache;
459 unsigned short left;
460};
461
462void mad_bit_init(struct mad_bitptr *, unsigned char const *);
463
464 # define mad_bit_finish(bitptr) /* nothing */
465
466unsigned int mad_bit_length(struct mad_bitptr const *,
467 struct mad_bitptr const *);
468
469# define mad_bit_bitsleft(bitptr) ((bitptr)->left)
470unsigned char const *mad_bit_nextbyte(struct mad_bitptr const *);
471
472void mad_bit_skip(struct mad_bitptr *, unsigned int);
473unsigned long mad_bit_read(struct mad_bitptr *, unsigned int);
474void mad_bit_write(struct mad_bitptr *, unsigned int, unsigned long);
475
476unsigned short mad_bit_crc(struct mad_bitptr, unsigned int, unsigned short);
477
478# endif
479
480/* Id: timer.h,v 1.10 2001/04/05 04:57:11 rob Exp */
481
482# ifndef LIBMAD_TIMER_H
483# define LIBMAD_TIMER_H
484
485typedef struct {
486 signed long seconds; /* whole seconds */
487 unsigned long fraction;/* 1/MAD_TIMER_RESOLUTION seconds */
488} mad_timer_t;
489
490extern mad_timer_t const mad_timer_zero;
491
492 # define MAD_TIMER_RESOLUTION352800000UL
493
494enum mad_units {
495 MAD_UNITS_HOURS = -2,
496 MAD_UNITS_MINUTES = -1,
497 MAD_UNITS_SECONDS = 0,
498
499 /* metric units */
500
501 MAD_UNITS_DECISECONDS = 10,
502 MAD_UNITS_CENTISECONDS = 100,
503 MAD_UNITS_MILLISECONDS = 1000,
504
505 /* audio sample units */
506
507 MAD_UNITS_8000_HZ = 8000,
508 MAD_UNITS_11025_HZ = 11025,
509 MAD_UNITS_12000_HZ = 12000,
510
511 MAD_UNITS_16000_HZ = 16000,
512 MAD_UNITS_22050_HZ = 22050,
513 MAD_UNITS_24000_HZ = 24000,
514
515 MAD_UNITS_32000_HZ = 32000,
516 MAD_UNITS_44100_HZ = 44100,
517 MAD_UNITS_48000_HZ = 48000,
518
519 /* video frame/field units */
520
521 MAD_UNITS_24_FPS = 24,
522 MAD_UNITS_25_FPS = 25,
523 MAD_UNITS_30_FPS = 30,
524 MAD_UNITS_48_FPS = 48,
525 MAD_UNITS_50_FPS = 50,
526 MAD_UNITS_60_FPS = 60,
527
528 /* CD audio frames */
529
530 MAD_UNITS_75_FPS = 75,
531
532 /* video drop-frame units */
533
534 MAD_UNITS_23_976_FPS = -24,
535 MAD_UNITS_24_975_FPS = -25,
536 MAD_UNITS_29_97_FPS = -30,
537 MAD_UNITS_47_952_FPS = -48,
538 MAD_UNITS_49_95_FPS = -50,
539 MAD_UNITS_59_94_FPS = -60
540};
541
542 # define mad_timer_reset(timer)(*(timer) = mad_timer_zero)
543
544int mad_timer_compare(mad_timer_t, mad_timer_t);
545
546 # define mad_timer_sign(timer)mad_timer_compare((timer), mad_timer_zero)
547
548void mad_timer_negate(mad_timer_t *);
549mad_timer_t mad_timer_abs(mad_timer_t);
550
551void mad_timer_set(mad_timer_t *, unsigned long, unsigned long, unsigned long);
552void mad_timer_add(mad_timer_t *, mad_timer_t);
553void mad_timer_multiply(mad_timer_t *, signed long);
554
555signed long mad_timer_count(mad_timer_t, enum mad_units);
556unsigned long mad_timer_fraction(mad_timer_t, unsigned long);
557void mad_timer_string(mad_timer_t, char *, char const *,
558 enum mad_units, enum mad_units, unsigned long);
559
560# endif
561
562/* Id: stream.h,v 1.12 2001/04/10 05:18:21 rob Exp */
563
564# ifndef LIBMAD_STREAM_H
565# define LIBMAD_STREAM_H
566
567 # define MAD_BUFFER_GUARD8
568 # define MAD_BUFFER_MDLEN(511 + 2048 + MAD_BUFFER_GUARD)
569
570enum mad_error {
571 MAD_ERROR_BUFLEN = 0x0001,/* input buffer too small (or EOF) */
572 MAD_ERROR_BUFPTR = 0x0002,/* invalid (null) buffer pointer */
573
574 MAD_ERROR_NOMEM = 0x0031,/* not enough memory */
575
576 MAD_ERROR_LOSTSYNC = 0x0101,/* lost synchronization */
577 MAD_ERROR_BADLAYER = 0x0102,/* reserved header layer value */
578 MAD_ERROR_BADBITRATE = 0x0103,/* forbidden bitrate value */
579 MAD_ERROR_BADSAMPLERATE = 0x0104,/* reserved sample frequency value */
580 MAD_ERROR_BADEMPHASIS = 0x0105,/* reserved emphasis value */
581
582 MAD_ERROR_BADCRC = 0x0201,/* CRC check failed */
583 MAD_ERROR_BADBITALLOC = 0x0211,/* forbidden bit allocation value */
584 MAD_ERROR_BADSCALEFACTOR = 0x0221,/* bad scalefactor index */
585 MAD_ERROR_BADFRAMELEN = 0x0231,/* bad frame length */
586 MAD_ERROR_BADBIGVALUES = 0x0232,/* bad big_values count */
587 MAD_ERROR_BADBLOCKTYPE = 0x0233,/* reserved block_type */
588 MAD_ERROR_BADSCFSI = 0x0234,/* bad scalefactor selection info */
589 MAD_ERROR_BADDATAPTR = 0x0235,/* bad main_data_begin pointer */
590 MAD_ERROR_BADPART3LEN = 0x0236,/* bad audio data length */
591 MAD_ERROR_BADHUFFTABLE = 0x0237,/* bad Huffman table select */
592 MAD_ERROR_BADHUFFDATA = 0x0238,/* Huffman data overrun */
593 MAD_ERROR_BADSTEREO = 0x0239/* incompatible block_type for JS */
594};
595
596 # define MAD_RECOVERABLE(error)((error) & 0xff00)
597
598struct mad_stream {
599 unsigned char const *buffer; /* input bitstream buffer */
600 unsigned char const *bufend; /* end of buffer */
601 unsigned long skiplen; /* bytes to skip before next frame */
602
603 int sync; /* stream sync found */
604 unsigned long freerate; /* free bitrate (fixed) */
605
606 unsigned char const *this_frame;/* start of current frame */
607 unsigned char const *next_frame;/* start of next frame */
608 struct mad_bitptr ptr; /* current processing bit pointer */
609
610 struct mad_bitptr anc_ptr; /* ancillary bits pointer */
611 unsigned int anc_bitlen; /* number of ancillary bits */
612
613 unsigned char (*main_data)[MAD_BUFFER_MDLEN];
614 /* Layer III main_data() */
615 unsigned int md_len; /* bytes in main_data */
616
617 int options; /* decoding options (see below) */
618 enum mad_error error; /* error code (see above) */
619};
620
621enum {
622 MAD_OPTION_IGNORECRC = 0x0001,/* ignore CRC errors */
623 MAD_OPTION_HALFSAMPLERATE = 0x0002,/* generate PCM at 1/2 sample rate */
624# if 0 /* not yet implemented */
625 MAD_OPTION_LEFTCHANNEL = 0x0010,/* decode left channel only */
626 MAD_OPTION_RIGHTCHANNEL = 0x0020,/* decode right channel only */
627 MAD_OPTION_SINGLECHANNEL = 0x0030,/* combine channels */
628# endif
629};
630
631void mad_stream_init(struct mad_stream *);
632void mad_stream_finish(struct mad_stream *);
633
634# define mad_stream_options(stream, opts) ((stream)->options = (opts))
635
636void mad_stream_buffer(struct mad_stream *,
637 unsigned char const *, unsigned long);
638void mad_stream_skip(struct mad_stream *, unsigned long);
639
640int mad_stream_sync(struct mad_stream *);
641
642# endif
643
644/* Id: frame.h,v 1.13 2001/04/05 04:57:11 rob Exp */
645
646# ifndef LIBMAD_FRAME_H
647# define LIBMAD_FRAME_H
648
649enum mad_layer {
650 MAD_LAYER_I = 1, /* Layer I */
651 MAD_LAYER_II = 2, /* Layer II */
652 MAD_LAYER_III = 3 /* Layer III */
653};
654
655enum mad_mode {
656 MAD_MODE_SINGLE_CHANNEL = 0, /* single channel */
657 MAD_MODE_DUAL_CHANNEL = 1, /* dual channel */
658 MAD_MODE_JOINT_STEREO = 2, /* joint (MS/intensity) stereo */
659 MAD_MODE_STEREO = 3 /* normal LR stereo */
660};
661
662enum mad_emphasis {
663 MAD_EMPHASIS_NONE = 0, /* no emphasis */
664 MAD_EMPHASIS_50_15_US = 1, /* 50/15 microseconds emphasis */
665 MAD_EMPHASIS_CCITT_J_17 = 3 /* CCITT J.17 emphasis */
666};
667
668struct mad_frame {
669 struct mad_header {
670 enum mad_layer layer; /* audio layer (1, 2, or 3) */
671 enum mad_mode mode; /* channel mode (see above) */
672 int mode_extension; /* additional mode info */
673 enum mad_emphasis emphasis; /* de-emphasis to use (see above) */
674
675 unsigned long bitrate; /* stream bitrate (bps) */
676 unsigned int samplerate; /* sampling frequency (Hz) */
677
678 unsigned short crc_check; /* frame CRC accumulator */
679 unsigned short crc_target; /* final target CRC checksum */
680
681 int flags; /* flags (see below) */
682 int private_bits; /* private bits (see below) */
683
684 mad_timer_t duration; /* audio playing time of frame */
685 } header;
686
687 int options; /* decoding options (from stream) */
688
689 mad_fixed_t sbsample[2][36][32];/* synthesis subband filter samples */
690 mad_fixed_t (*overlap)[2][32][18];/* Layer III block overlap data */
691};
692
693 # define MAD_NCHANNELS(header) ((header)->mode ? 2 : 1)
694# define MAD_NSBSAMPLES(header) \
695 ((header)->layer == MAD_LAYER_I ? 12 : \
696 (((header)->layer == MAD_LAYER_III && \
697 ((header)->flags & MAD_FLAG_LSF_EXT)) ? 18 : 36))
698
699enum {
700 MAD_FLAG_NPRIVATE_III = 0x0007,/* number of Layer III private bits */
701 MAD_FLAG_INCOMPLETE = 0x0008,/* header but not data is decoded */
702
703 MAD_FLAG_PROTECTION = 0x0010,/* frame has CRC protection */
704 MAD_FLAG_COPYRIGHT = 0x0020,/* frame is copyright */
705 MAD_FLAG_ORIGINAL = 0x0040,/* frame is original (else copy) */
706 MAD_FLAG_PADDING = 0x0080,/* frame has additional slot */
707
708 MAD_FLAG_I_STEREO = 0x0100,/* uses intensity joint stereo */
709 MAD_FLAG_MS_STEREO = 0x0200,/* uses middle/side joint stereo */
710 MAD_FLAG_FREEFORMAT = 0x0400,/* uses free format bitrate */
711
712 MAD_FLAG_LSF_EXT = 0x1000,/* lower sampling freq. extension */
713 MAD_FLAG_MC_EXT = 0x2000,/* multichannel audio extension */
714 MAD_FLAG_MPEG_2_5_EXT = 0x4000/* MPEG 2.5 (unofficial) extension */
715};
716
717enum {
718 MAD_PRIVATE_HEADER = 0x0100,/* header private bit */
719 MAD_PRIVATE_III = 0x001f/* Layer III private bits (up to 5) */
720};
721
722void mad_header_init(struct mad_header *);
723
724# define mad_header_finish(header) /* nothing */
725
726int mad_header_decode(struct mad_header *, struct mad_stream *);
727
728void mad_frame_init(struct mad_frame *);
729void mad_frame_finish(struct mad_frame *);
730
731int mad_frame_decode(struct mad_frame *, struct mad_stream *);
732
733void mad_frame_mute(struct mad_frame *);
734
735# endif
736
737/* Id: synth.h,v 1.8 2001/04/05 04:57:11 rob Exp */
738
739# ifndef LIBMAD_SYNTH_H
740# define LIBMAD_SYNTH_H
741
742struct mad_synth {
743 mad_fixed_t filter[2][2][2][16][8];/* polyphase filterbank outputs */
744 /* [ch][eo][peo][s][v] */
745
746 unsigned int phase; /* current processing phase */
747
748 struct mad_pcm {
749 unsigned int samplerate; /* sampling frequency (Hz) */
750 unsigned short channels; /* number of channels */
751 unsigned short length; /* number of samples per channel */
752 mad_fixed_t samples[2][1152];/* PCM output samples */
753 } pcm;
754};
755
756void mad_synth_init(struct mad_synth *);
757
758# define mad_synth_finish(synth) /* nothing */
759
760void mad_synth_mute(struct mad_synth *);
761
762void mad_synth_frame(struct mad_synth *, struct mad_frame const *);
763
764# endif
765
766/* Id: decoder.h,v 1.9 2001/04/05 04:57:11 rob Exp */
767
768# ifndef LIBMAD_DECODER_H
769# define LIBMAD_DECODER_H
770
771enum mad_decoder_mode {
772 MAD_DECODER_MODE_SYNC = 0,
773 MAD_DECODER_MODE_ASYNC
774};
775
776enum mad_flow {
777 MAD_FLOW_CONTINUE = 0x0000,
778 MAD_FLOW_STOP = 0x0010,
779 MAD_FLOW_BREAK = 0x0011,
780 MAD_FLOW_IGNORE = 0x0020
781};
782
783struct mad_decoder {
784 enum mad_decoder_mode mode;
785
786 int options;
787
788 struct {
789 long pid;
790 int in;
791 int out;
792 } async;
793
794 struct {
795 struct mad_stream stream;
796 struct mad_frame frame;
797 struct mad_synth synth;
798 } *sync;
799
800 void *cb_data;
801
802 enum mad_flow (*input_func)(void *, struct mad_stream *);
803 enum mad_flow (*header_func)(void *, struct mad_header const *);
804 enum mad_flow (*filter_func)(void *, struct mad_frame *);
805 enum mad_flow (*output_func)(void *,
806 struct mad_header const *, struct mad_pcm *);
807 enum mad_flow (*error_func)(void *, struct mad_stream *, struct mad_frame *);
808 enum mad_flow (*message_func)(void *, void *, unsigned int *);
809};
810
811void mad_decoder_init(struct mad_decoder *, void *,
812 enum mad_flow (*)(void *, struct mad_stream *),
813 enum mad_flow (*)(void *, struct mad_header const *),
814 enum mad_flow (*)(void *, struct mad_frame *),
815 enum mad_flow (*)(void *,
816 struct mad_header const *,
817 struct mad_pcm *),
818 enum mad_flow (*)(void *,
819 struct mad_stream *,
820 struct mad_frame *),
821 enum mad_flow (*)(void *, void *, unsigned int *));
822int mad_decoder_finish(struct mad_decoder *);
823
824# define mad_decoder_options(decoder, opts) ((decoder)->options = (opts))
825
826int mad_decoder_run(struct mad_decoder *, enum mad_decoder_mode);
827int mad_decoder_message(struct mad_decoder *, void *, unsigned int *);
828
829# endif
830
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 @@
1/*
2 * mad - MPEG audio decoder
3 * Copyright (C) 2000-2001 Robert Leslie
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * $Id$
20 */
21
22/*
23 * These are the Layer II classes of quantization.
24 * The table is derived from Table B.4 of ISO/IEC 11172-3.
25 */
26
27 { 3, 2, 5,
28 MAD_F(0x15555555) /* 1.33333333333 => 1.33333333209, e 0.00000000124 */,
29 MAD_F(0x08000000) /* 0.50000000000 => 0.50000000000, e 0.00000000000 */ },
30 { 5, 3, 7,
31 MAD_F(0x1999999a) /* 1.60000000000 => 1.60000000149, e -0.00000000149 */,
32 MAD_F(0x08000000) /* 0.50000000000 => 0.50000000000, e 0.00000000000 */ },
33 { 7, 0, 3,
34 MAD_F(0x12492492) /* 1.14285714286 => 1.14285714179, e 0.00000000107 */,
35 MAD_F(0x04000000) /* 0.25000000000 => 0.25000000000, e 0.00000000000 */ },
36 { 9, 4, 10,
37 MAD_F(0x1c71c71c) /* 1.77777777777 => 1.77777777612, e 0.00000000165 */,
38 MAD_F(0x08000000) /* 0.50000000000 => 0.50000000000, e 0.00000000000 */ },
39 { 15, 0, 4,
40 MAD_F(0x11111111) /* 1.06666666666 => 1.06666666642, e 0.00000000024 */,
41 MAD_F(0x02000000) /* 0.12500000000 => 0.12500000000, e 0.00000000000 */ },
42 { 31, 0, 5,
43 MAD_F(0x10842108) /* 1.03225806452 => 1.03225806355, e 0.00000000097 */,
44 MAD_F(0x01000000) /* 0.06250000000 => 0.06250000000, e 0.00000000000 */ },
45 { 63, 0, 6,
46 MAD_F(0x10410410) /* 1.01587301587 => 1.01587301493, e 0.00000000094 */,
47 MAD_F(0x00800000) /* 0.03125000000 => 0.03125000000, e 0.00000000000 */ },
48 { 127, 0, 7,
49 MAD_F(0x10204081) /* 1.00787401575 => 1.00787401572, e 0.00000000003 */,
50 MAD_F(0x00400000) /* 0.01562500000 => 0.01562500000, e 0.00000000000 */ },
51 { 255, 0, 8,
52 MAD_F(0x10101010) /* 1.00392156863 => 1.00392156839, e 0.00000000024 */,
53 MAD_F(0x00200000) /* 0.00781250000 => 0.00781250000, e 0.00000000000 */ },
54 { 511, 0, 9,
55 MAD_F(0x10080402) /* 1.00195694716 => 1.00195694715, e 0.00000000001 */,
56 MAD_F(0x00100000) /* 0.00390625000 => 0.00390625000, e 0.00000000000 */ },
57 { 1023, 0, 10,
58 MAD_F(0x10040100) /* 1.00097751711 => 1.00097751617, e 0.00000000094 */,
59 MAD_F(0x00080000) /* 0.00195312500 => 0.00195312500, e 0.00000000000 */ },
60 { 2047, 0, 11,
61 MAD_F(0x10020040) /* 1.00048851979 => 1.00048851967, e 0.00000000012 */,
62 MAD_F(0x00040000) /* 0.00097656250 => 0.00097656250, e 0.00000000000 */ },
63 { 4095, 0, 12,
64 MAD_F(0x10010010) /* 1.00024420024 => 1.00024420023, e 0.00000000001 */,
65 MAD_F(0x00020000) /* 0.00048828125 => 0.00048828125, e 0.00000000000 */ },
66 { 8191, 0, 13,
67 MAD_F(0x10008004) /* 1.00012208522 => 1.00012208521, e 0.00000000001 */,
68 MAD_F(0x00010000) /* 0.00024414063 => 0.00024414062, e 0.00000000000 */ },
69 { 16383, 0, 14,
70 MAD_F(0x10004001) /* 1.00006103888 => 1.00006103888, e -0.00000000000 */,
71 MAD_F(0x00008000) /* 0.00012207031 => 0.00012207031, e -0.00000000000 */ },
72 { 32767, 0, 15,
73 MAD_F(0x10002000) /* 1.00003051851 => 1.00003051758, e 0.00000000093 */,
74 MAD_F(0x00004000) /* 0.00006103516 => 0.00006103516, e 0.00000000000 */ },
75 { 65535, 0, 16,
76 MAD_F(0x10001000) /* 1.00001525902 => 1.00001525879, e 0.00000000023 */,
77 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 @@
1Files: plugins/codecs/libmadplugin.so.1.0.0 plugins/codecs/libmadplugin.so.1.0 plugins/codecs/libmadplugin.so.1 plugins/codecs/libmadplugin.so
2Priority: optional
3Section: qpe/plugins
4Maintainer: John Ryland <jryland@trolltech.com>
5Architecture: arm
6Version: $QPE_VERSION-3
7Depends: qpe-base ($QPE_VERSION)
8Description: MP3 file plugin using libmad
9 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 @@
1/*
2 * mad - MPEG audio decoder
3 * Copyright (C) 2000-2001 Robert Leslie
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * $Id$
20 */
21
22/*
23 * This is the lookup table used to compute x^(4/3) for Layer III
24 * requantization. To maintain the best possible accuracy, the value is
25 * stored as a normalized mantissa with exponent. The requantization
26 * algorithm recombines these parts with appropriate scaling.
27 */
28
29 /* 0 */ { MAD_F(0x00000000) /* 0.000000000 */, 0 },
30 /* 1 */ { MAD_F(0x04000000) /* 0.250000000 */, 2 },
31 /* 2 */ { MAD_F(0x050a28be) /* 0.314980262 */, 3 },
32 /* 3 */ { MAD_F(0x0453a5cd) /* 0.270421794 */, 4 },
33 /* 4 */ { MAD_F(0x06597fa9) /* 0.396850263 */, 4 },
34 /* 5 */ { MAD_F(0x04466275) /* 0.267183742 */, 5 },
35 /* 6 */ { MAD_F(0x05738c72) /* 0.340710111 */, 5 },
36 /* 7 */ { MAD_F(0x06b1fc81) /* 0.418453696 */, 5 },
37 /* 8 */ { MAD_F(0x04000000) /* 0.250000000 */, 6 },
38 /* 9 */ { MAD_F(0x04ae20d7) /* 0.292511788 */, 6 },
39 /* 10 */ { MAD_F(0x0562d694) /* 0.336630420 */, 6 },
40 /* 11 */ { MAD_F(0x061dae96) /* 0.382246578 */, 6 },
41 /* 12 */ { MAD_F(0x06de47f4) /* 0.429267841 */, 6 },
42 /* 13 */ { MAD_F(0x07a44f7a) /* 0.477614858 */, 6 },
43 /* 14 */ { MAD_F(0x0437be65) /* 0.263609310 */, 7 },
44 /* 15 */ { MAD_F(0x049fc824) /* 0.289009227 */, 7 },
45
46 /* 16 */ { MAD_F(0x050a28be) /* 0.314980262 */, 7 },
47 /* 17 */ { MAD_F(0x0576c6f5) /* 0.341498336 */, 7 },
48 /* 18 */ { MAD_F(0x05e58c0b) /* 0.368541759 */, 7 },
49 /* 19 */ { MAD_F(0x06566361) /* 0.396090870 */, 7 },
50 /* 20 */ { MAD_F(0x06c93a2e) /* 0.424127753 */, 7 },
51 /* 21 */ { MAD_F(0x073dff3e) /* 0.452635998 */, 7 },
52 /* 22 */ { MAD_F(0x07b4a2bc) /* 0.481600510 */, 7 },
53 /* 23 */ { MAD_F(0x04168b05) /* 0.255503674 */, 8 },
54 /* 24 */ { MAD_F(0x0453a5cd) /* 0.270421794 */, 8 },
55 /* 25 */ { MAD_F(0x04919b6a) /* 0.285548607 */, 8 },
56 /* 26 */ { MAD_F(0x04d065fb) /* 0.300878507 */, 8 },
57 /* 27 */ { MAD_F(0x05100000) /* 0.316406250 */, 8 },
58 /* 28 */ { MAD_F(0x05506451) /* 0.332126919 */, 8 },
59 /* 29 */ { MAD_F(0x05918e15) /* 0.348035890 */, 8 },
60 /* 30 */ { MAD_F(0x05d378bb) /* 0.364128809 */, 8 },
61 /* 31 */ { MAD_F(0x06161ff3) /* 0.380401563 */, 8 },
62
63 /* 32 */ { MAD_F(0x06597fa9) /* 0.396850263 */, 8 },
64 /* 33 */ { MAD_F(0x069d9400) /* 0.413471222 */, 8 },
65 /* 34 */ { MAD_F(0x06e2594c) /* 0.430260942 */, 8 },
66 /* 35 */ { MAD_F(0x0727cc11) /* 0.447216097 */, 8 },
67 /* 36 */ { MAD_F(0x076de8fc) /* 0.464333519 */, 8 },
68 /* 37 */ { MAD_F(0x07b4ace3) /* 0.481610189 */, 8 },
69 /* 38 */ { MAD_F(0x07fc14bf) /* 0.499043224 */, 8 },
70 /* 39 */ { MAD_F(0x04220ed7) /* 0.258314934 */, 9 },
71 /* 40 */ { MAD_F(0x04466275) /* 0.267183742 */, 9 },
72 /* 41 */ { MAD_F(0x046b03e7) /* 0.276126771 */, 9 },
73 /* 42 */ { MAD_F(0x048ff1e8) /* 0.285142811 */, 9 },
74 /* 43 */ { MAD_F(0x04b52b3f) /* 0.294230696 */, 9 },
75 /* 44 */ { MAD_F(0x04daaec0) /* 0.303389310 */, 9 },
76 /* 45 */ { MAD_F(0x05007b49) /* 0.312617576 */, 9 },
77 /* 46 */ { MAD_F(0x05268fc6) /* 0.321914457 */, 9 },
78 /* 47 */ { MAD_F(0x054ceb2a) /* 0.331278957 */, 9 },
79
80 /* 48 */ { MAD_F(0x05738c72) /* 0.340710111 */, 9 },
81 /* 49 */ { MAD_F(0x059a72a5) /* 0.350206992 */, 9 },
82 /* 50 */ { MAD_F(0x05c19cd3) /* 0.359768701 */, 9 },
83 /* 51 */ { MAD_F(0x05e90a12) /* 0.369394372 */, 9 },
84 /* 52 */ { MAD_F(0x0610b982) /* 0.379083164 */, 9 },
85 /* 53 */ { MAD_F(0x0638aa48) /* 0.388834268 */, 9 },
86 /* 54 */ { MAD_F(0x0660db91) /* 0.398646895 */, 9 },
87 /* 55 */ { MAD_F(0x06894c90) /* 0.408520284 */, 9 },
88 /* 56 */ { MAD_F(0x06b1fc81) /* 0.418453696 */, 9 },
89 /* 57 */ { MAD_F(0x06daeaa1) /* 0.428446415 */, 9 },
90 /* 58 */ { MAD_F(0x07041636) /* 0.438497744 */, 9 },
91 /* 59 */ { MAD_F(0x072d7e8b) /* 0.448607009 */, 9 },
92 /* 60 */ { MAD_F(0x075722ef) /* 0.458773552 */, 9 },
93 /* 61 */ { MAD_F(0x078102b8) /* 0.468996735 */, 9 },
94 /* 62 */ { MAD_F(0x07ab1d3e) /* 0.479275937 */, 9 },
95 /* 63 */ { MAD_F(0x07d571e0) /* 0.489610555 */, 9 },
96
97 /* 64 */ { MAD_F(0x04000000) /* 0.250000000 */, 10 },
98 /* 65 */ { MAD_F(0x04156381) /* 0.255221850 */, 10 },
99 /* 66 */ { MAD_F(0x042ae32a) /* 0.260470548 */, 10 },
100 /* 67 */ { MAD_F(0x04407eb1) /* 0.265745823 */, 10 },
101 /* 68 */ { MAD_F(0x045635cf) /* 0.271047409 */, 10 },
102 /* 69 */ { MAD_F(0x046c083e) /* 0.276375048 */, 10 },
103 /* 70 */ { MAD_F(0x0481f5bb) /* 0.281728487 */, 10 },
104 /* 71 */ { MAD_F(0x0497fe03) /* 0.287107481 */, 10 },
105 /* 72 */ { MAD_F(0x04ae20d7) /* 0.292511788 */, 10 },
106 /* 73 */ { MAD_F(0x04c45df6) /* 0.297941173 */, 10 },
107 /* 74 */ { MAD_F(0x04dab524) /* 0.303395408 */, 10 },
108 /* 75 */ { MAD_F(0x04f12624) /* 0.308874267 */, 10 },
109 /* 76 */ { MAD_F(0x0507b0bc) /* 0.314377532 */, 10 },
110 /* 77 */ { MAD_F(0x051e54b1) /* 0.319904987 */, 10 },
111 /* 78 */ { MAD_F(0x053511cb) /* 0.325456423 */, 10 },
112 /* 79 */ { MAD_F(0x054be7d4) /* 0.331031635 */, 10 },
113
114 /* 80 */ { MAD_F(0x0562d694) /* 0.336630420 */, 10 },
115 /* 81 */ { MAD_F(0x0579ddd8) /* 0.342252584 */, 10 },
116 /* 82 */ { MAD_F(0x0590fd6c) /* 0.347897931 */, 10 },
117 /* 83 */ { MAD_F(0x05a8351c) /* 0.353566275 */, 10 },
118 /* 84 */ { MAD_F(0x05bf84b8) /* 0.359257429 */, 10 },
119 /* 85 */ { MAD_F(0x05d6ec0e) /* 0.364971213 */, 10 },
120 /* 86 */ { MAD_F(0x05ee6aef) /* 0.370707448 */, 10 },
121 /* 87 */ { MAD_F(0x0606012b) /* 0.376465960 */, 10 },
122 /* 88 */ { MAD_F(0x061dae96) /* 0.382246578 */, 10 },
123 /* 89 */ { MAD_F(0x06357302) /* 0.388049134 */, 10 },
124 /* 90 */ { MAD_F(0x064d4e43) /* 0.393873464 */, 10 },
125 /* 91 */ { MAD_F(0x0665402d) /* 0.399719406 */, 10 },
126 /* 92 */ { MAD_F(0x067d4896) /* 0.405586801 */, 10 },
127 /* 93 */ { MAD_F(0x06956753) /* 0.411475493 */, 10 },
128 /* 94 */ { MAD_F(0x06ad9c3d) /* 0.417385331 */, 10 },
129 /* 95 */ { MAD_F(0x06c5e72b) /* 0.423316162 */, 10 },
130
131 /* 96 */ { MAD_F(0x06de47f4) /* 0.429267841 */, 10 },
132 /* 97 */ { MAD_F(0x06f6be73) /* 0.435240221 */, 10 },
133 /* 98 */ { MAD_F(0x070f4a80) /* 0.441233161 */, 10 },
134 /* 99 */ { MAD_F(0x0727ebf7) /* 0.447246519 */, 10 },
135 /* 100 */ { MAD_F(0x0740a2b2) /* 0.453280160 */, 10 },
136 /* 101 */ { MAD_F(0x07596e8d) /* 0.459333946 */, 10 },
137 /* 102 */ { MAD_F(0x07724f64) /* 0.465407744 */, 10 },
138 /* 103 */ { MAD_F(0x078b4514) /* 0.471501425 */, 10 },
139 /* 104 */ { MAD_F(0x07a44f7a) /* 0.477614858 */, 10 },
140 /* 105 */ { MAD_F(0x07bd6e75) /* 0.483747918 */, 10 },
141 /* 106 */ { MAD_F(0x07d6a1e2) /* 0.489900479 */, 10 },
142 /* 107 */ { MAD_F(0x07efe9a1) /* 0.496072418 */, 10 },
143 /* 108 */ { MAD_F(0x0404a2c9) /* 0.251131807 */, 11 },
144 /* 109 */ { MAD_F(0x04115aca) /* 0.254236974 */, 11 },
145 /* 110 */ { MAD_F(0x041e1cc4) /* 0.257351652 */, 11 },
146 /* 111 */ { MAD_F(0x042ae8a7) /* 0.260475783 */, 11 },
147
148 /* 112 */ { MAD_F(0x0437be65) /* 0.263609310 */, 11 },
149 /* 113 */ { MAD_F(0x04449dee) /* 0.266752177 */, 11 },
150 /* 114 */ { MAD_F(0x04518733) /* 0.269904329 */, 11 },
151 /* 115 */ { MAD_F(0x045e7a26) /* 0.273065710 */, 11 },
152 /* 116 */ { MAD_F(0x046b76b9) /* 0.276236269 */, 11 },
153 /* 117 */ { MAD_F(0x04787cdc) /* 0.279415952 */, 11 },
154 /* 118 */ { MAD_F(0x04858c83) /* 0.282604707 */, 11 },
155 /* 119 */ { MAD_F(0x0492a59f) /* 0.285802482 */, 11 },
156 /* 120 */ { MAD_F(0x049fc824) /* 0.289009227 */, 11 },
157 /* 121 */ { MAD_F(0x04acf402) /* 0.292224893 */, 11 },
158 /* 122 */ { MAD_F(0x04ba292e) /* 0.295449429 */, 11 },
159 /* 123 */ { MAD_F(0x04c7679a) /* 0.298682788 */, 11 },
160 /* 124 */ { MAD_F(0x04d4af3a) /* 0.301924921 */, 11 },
161 /* 125 */ { MAD_F(0x04e20000) /* 0.305175781 */, 11 },
162 /* 126 */ { MAD_F(0x04ef59e0) /* 0.308435322 */, 11 },
163 /* 127 */ { MAD_F(0x04fcbcce) /* 0.311703498 */, 11 },
164
165 /* 128 */ { MAD_F(0x050a28be) /* 0.314980262 */, 11 },
166 /* 129 */ { MAD_F(0x05179da4) /* 0.318265572 */, 11 },
167 /* 130 */ { MAD_F(0x05251b73) /* 0.321559381 */, 11 },
168 /* 131 */ { MAD_F(0x0532a220) /* 0.324861647 */, 11 },
169 /* 132 */ { MAD_F(0x054031a0) /* 0.328172327 */, 11 },
170 /* 133 */ { MAD_F(0x054dc9e7) /* 0.331491377 */, 11 },
171 /* 134 */ { MAD_F(0x055b6ae9) /* 0.334818756 */, 11 },
172 /* 135 */ { MAD_F(0x0569149c) /* 0.338154423 */, 11 },
173 /* 136 */ { MAD_F(0x0576c6f5) /* 0.341498336 */, 11 },
174 /* 137 */ { MAD_F(0x058481e9) /* 0.344850455 */, 11 },
175 /* 138 */ { MAD_F(0x0592456d) /* 0.348210741 */, 11 },
176 /* 139 */ { MAD_F(0x05a01176) /* 0.351579152 */, 11 },
177 /* 140 */ { MAD_F(0x05ade5fa) /* 0.354955651 */, 11 },
178 /* 141 */ { MAD_F(0x05bbc2ef) /* 0.358340200 */, 11 },
179 /* 142 */ { MAD_F(0x05c9a84a) /* 0.361732758 */, 11 },
180 /* 143 */ { MAD_F(0x05d79601) /* 0.365133291 */, 11 },
181
182 /* 144 */ { MAD_F(0x05e58c0b) /* 0.368541759 */, 11 },
183 /* 145 */ { MAD_F(0x05f38a5d) /* 0.371958126 */, 11 },
184 /* 146 */ { MAD_F(0x060190ee) /* 0.375382356 */, 11 },
185 /* 147 */ { MAD_F(0x060f9fb3) /* 0.378814413 */, 11 },
186 /* 148 */ { MAD_F(0x061db6a5) /* 0.382254261 */, 11 },
187 /* 149 */ { MAD_F(0x062bd5b8) /* 0.385701865 */, 11 },
188 /* 150 */ { MAD_F(0x0639fce4) /* 0.389157191 */, 11 },
189 /* 151 */ { MAD_F(0x06482c1f) /* 0.392620204 */, 11 },
190 /* 152 */ { MAD_F(0x06566361) /* 0.396090870 */, 11 },
191 /* 153 */ { MAD_F(0x0664a2a0) /* 0.399569155 */, 11 },
192 /* 154 */ { MAD_F(0x0672e9d4) /* 0.403055027 */, 11 },
193 /* 155 */ { MAD_F(0x068138f3) /* 0.406548452 */, 11 },
194 /* 156 */ { MAD_F(0x068f8ff5) /* 0.410049398 */, 11 },
195 /* 157 */ { MAD_F(0x069deed1) /* 0.413557833 */, 11 },
196 /* 158 */ { MAD_F(0x06ac557f) /* 0.417073724 */, 11 },
197 /* 159 */ { MAD_F(0x06bac3f6) /* 0.420597041 */, 11 },
198
199 /* 160 */ { MAD_F(0x06c93a2e) /* 0.424127753 */, 11 },
200 /* 161 */ { MAD_F(0x06d7b81f) /* 0.427665827 */, 11 },
201 /* 162 */ { MAD_F(0x06e63dc0) /* 0.431211234 */, 11 },
202 /* 163 */ { MAD_F(0x06f4cb09) /* 0.434763944 */, 11 },
203 /* 164 */ { MAD_F(0x07035ff3) /* 0.438323927 */, 11 },
204 /* 165 */ { MAD_F(0x0711fc75) /* 0.441891153 */, 11 },
205 /* 166 */ { MAD_F(0x0720a087) /* 0.445465593 */, 11 },
206 /* 167 */ { MAD_F(0x072f4c22) /* 0.449047217 */, 11 },
207 /* 168 */ { MAD_F(0x073dff3e) /* 0.452635998 */, 11 },
208 /* 169 */ { MAD_F(0x074cb9d3) /* 0.456231906 */, 11 },
209 /* 170 */ { MAD_F(0x075b7bdb) /* 0.459834914 */, 11 },
210 /* 171 */ { MAD_F(0x076a454c) /* 0.463444993 */, 11 },
211 /* 172 */ { MAD_F(0x07791620) /* 0.467062117 */, 11 },
212 /* 173 */ { MAD_F(0x0787ee50) /* 0.470686258 */, 11 },
213 /* 174 */ { MAD_F(0x0796cdd4) /* 0.474317388 */, 11 },
214 /* 175 */ { MAD_F(0x07a5b4a5) /* 0.477955481 */, 11 },
215
216 /* 176 */ { MAD_F(0x07b4a2bc) /* 0.481600510 */, 11 },
217 /* 177 */ { MAD_F(0x07c39812) /* 0.485252449 */, 11 },
218 /* 178 */ { MAD_F(0x07d294a0) /* 0.488911273 */, 11 },
219 /* 179 */ { MAD_F(0x07e1985f) /* 0.492576954 */, 11 },
220 /* 180 */ { MAD_F(0x07f0a348) /* 0.496249468 */, 11 },
221 /* 181 */ { MAD_F(0x07ffb554) /* 0.499928790 */, 11 },
222 /* 182 */ { MAD_F(0x0407673f) /* 0.251807447 */, 12 },
223 /* 183 */ { MAD_F(0x040ef75e) /* 0.253653877 */, 12 },
224 /* 184 */ { MAD_F(0x04168b05) /* 0.255503674 */, 12 },
225 /* 185 */ { MAD_F(0x041e2230) /* 0.257356825 */, 12 },
226 /* 186 */ { MAD_F(0x0425bcdd) /* 0.259213318 */, 12 },
227 /* 187 */ { MAD_F(0x042d5b07) /* 0.261073141 */, 12 },
228 /* 188 */ { MAD_F(0x0434fcad) /* 0.262936282 */, 12 },
229 /* 189 */ { MAD_F(0x043ca1c9) /* 0.264802730 */, 12 },
230 /* 190 */ { MAD_F(0x04444a5a) /* 0.266672472 */, 12 },
231 /* 191 */ { MAD_F(0x044bf65d) /* 0.268545497 */, 12 },
232
233 /* 192 */ { MAD_F(0x0453a5cd) /* 0.270421794 */, 12 },
234 /* 193 */ { MAD_F(0x045b58a9) /* 0.272301352 */, 12 },
235 /* 194 */ { MAD_F(0x04630eed) /* 0.274184158 */, 12 },
236 /* 195 */ { MAD_F(0x046ac896) /* 0.276070203 */, 12 },
237 /* 196 */ { MAD_F(0x047285a2) /* 0.277959474 */, 12 },
238 /* 197 */ { MAD_F(0x047a460c) /* 0.279851960 */, 12 },
239 /* 198 */ { MAD_F(0x048209d3) /* 0.281747652 */, 12 },
240 /* 199 */ { MAD_F(0x0489d0f4) /* 0.283646538 */, 12 },
241 /* 200 */ { MAD_F(0x04919b6a) /* 0.285548607 */, 12 },
242 /* 201 */ { MAD_F(0x04996935) /* 0.287453849 */, 12 },
243 /* 202 */ { MAD_F(0x04a13a50) /* 0.289362253 */, 12 },
244 /* 203 */ { MAD_F(0x04a90eba) /* 0.291273810 */, 12 },
245 /* 204 */ { MAD_F(0x04b0e66e) /* 0.293188507 */, 12 },
246 /* 205 */ { MAD_F(0x04b8c16c) /* 0.295106336 */, 12 },
247 /* 206 */ { MAD_F(0x04c09faf) /* 0.297027285 */, 12 },
248 /* 207 */ { MAD_F(0x04c88135) /* 0.298951346 */, 12 },
249
250 /* 208 */ { MAD_F(0x04d065fb) /* 0.300878507 */, 12 },
251 /* 209 */ { MAD_F(0x04d84dff) /* 0.302808759 */, 12 },
252 /* 210 */ { MAD_F(0x04e0393e) /* 0.304742092 */, 12 },
253 /* 211 */ { MAD_F(0x04e827b6) /* 0.306678497 */, 12 },
254 /* 212 */ { MAD_F(0x04f01963) /* 0.308617963 */, 12 },
255 /* 213 */ { MAD_F(0x04f80e44) /* 0.310560480 */, 12 },
256 /* 214 */ { MAD_F(0x05000655) /* 0.312506041 */, 12 },
257 /* 215 */ { MAD_F(0x05080195) /* 0.314454634 */, 12 },
258 /* 216 */ { MAD_F(0x05100000) /* 0.316406250 */, 12 },
259 /* 217 */ { MAD_F(0x05180194) /* 0.318360880 */, 12 },
260 /* 218 */ { MAD_F(0x0520064f) /* 0.320318516 */, 12 },
261 /* 219 */ { MAD_F(0x05280e2d) /* 0.322279147 */, 12 },
262 /* 220 */ { MAD_F(0x0530192e) /* 0.324242764 */, 12 },
263 /* 221 */ { MAD_F(0x0538274e) /* 0.326209359 */, 12 },
264 /* 222 */ { MAD_F(0x0540388a) /* 0.328178922 */, 12 },
265 /* 223 */ { MAD_F(0x05484ce2) /* 0.330151445 */, 12 },
266
267 /* 224 */ { MAD_F(0x05506451) /* 0.332126919 */, 12 },
268 /* 225 */ { MAD_F(0x05587ed5) /* 0.334105334 */, 12 },
269 /* 226 */ { MAD_F(0x05609c6e) /* 0.336086683 */, 12 },
270 /* 227 */ { MAD_F(0x0568bd17) /* 0.338070956 */, 12 },
271 /* 228 */ { MAD_F(0x0570e0cf) /* 0.340058145 */, 12 },
272 /* 229 */ { MAD_F(0x05790793) /* 0.342048241 */, 12 },
273 /* 230 */ { MAD_F(0x05813162) /* 0.344041237 */, 12 },
274 /* 231 */ { MAD_F(0x05895e39) /* 0.346037122 */, 12 },
275 /* 232 */ { MAD_F(0x05918e15) /* 0.348035890 */, 12 },
276 /* 233 */ { MAD_F(0x0599c0f4) /* 0.350037532 */, 12 },
277 /* 234 */ { MAD_F(0x05a1f6d5) /* 0.352042040 */, 12 },
278 /* 235 */ { MAD_F(0x05aa2fb5) /* 0.354049405 */, 12 },
279 /* 236 */ { MAD_F(0x05b26b92) /* 0.356059619 */, 12 },
280 /* 237 */ { MAD_F(0x05baaa69) /* 0.358072674 */, 12 },
281 /* 238 */ { MAD_F(0x05c2ec39) /* 0.360088563 */, 12 },
282 /* 239 */ { MAD_F(0x05cb3100) /* 0.362107278 */, 12 },
283
284 /* 240 */ { MAD_F(0x05d378bb) /* 0.364128809 */, 12 },
285 /* 241 */ { MAD_F(0x05dbc368) /* 0.366153151 */, 12 },
286 /* 242 */ { MAD_F(0x05e41105) /* 0.368180294 */, 12 },
287 /* 243 */ { MAD_F(0x05ec6190) /* 0.370210231 */, 12 },
288 /* 244 */ { MAD_F(0x05f4b507) /* 0.372242955 */, 12 },
289 /* 245 */ { MAD_F(0x05fd0b68) /* 0.374278458 */, 12 },
290 /* 246 */ { MAD_F(0x060564b1) /* 0.376316732 */, 12 },
291 /* 247 */ { MAD_F(0x060dc0e0) /* 0.378357769 */, 12 },
292 /* 248 */ { MAD_F(0x06161ff3) /* 0.380401563 */, 12 },
293 /* 249 */ { MAD_F(0x061e81e8) /* 0.382448106 */, 12 },
294 /* 250 */ { MAD_F(0x0626e6bc) /* 0.384497391 */, 12 },
295 /* 251 */ { MAD_F(0x062f4e6f) /* 0.386549409 */, 12 },
296 /* 252 */ { MAD_F(0x0637b8fd) /* 0.388604155 */, 12 },
297 /* 253 */ { MAD_F(0x06402666) /* 0.390661620 */, 12 },
298 /* 254 */ { MAD_F(0x064896a7) /* 0.392721798 */, 12 },
299 /* 255 */ { MAD_F(0x065109be) /* 0.394784681 */, 12 },
300
301 /* 256 */ { MAD_F(0x06597fa9) /* 0.396850263 */, 12 },
302 /* 257 */ { MAD_F(0x0661f867) /* 0.398918536 */, 12 },
303 /* 258 */ { MAD_F(0x066a73f5) /* 0.400989493 */, 12 },
304 /* 259 */ { MAD_F(0x0672f252) /* 0.403063128 */, 12 },
305 /* 260 */ { MAD_F(0x067b737c) /* 0.405139433 */, 12 },
306 /* 261 */ { MAD_F(0x0683f771) /* 0.407218402 */, 12 },
307 /* 262 */ { MAD_F(0x068c7e2f) /* 0.409300027 */, 12 },
308 /* 263 */ { MAD_F(0x069507b5) /* 0.411384303 */, 12 },
309 /* 264 */ { MAD_F(0x069d9400) /* 0.413471222 */, 12 },
310 /* 265 */ { MAD_F(0x06a6230f) /* 0.415560778 */, 12 },
311 /* 266 */ { MAD_F(0x06aeb4e0) /* 0.417652964 */, 12 },
312 /* 267 */ { MAD_F(0x06b74971) /* 0.419747773 */, 12 },
313 /* 268 */ { MAD_F(0x06bfe0c0) /* 0.421845199 */, 12 },
314 /* 269 */ { MAD_F(0x06c87acc) /* 0.423945235 */, 12 },
315 /* 270 */ { MAD_F(0x06d11794) /* 0.426047876 */, 12 },
316 /* 271 */ { MAD_F(0x06d9b714) /* 0.428153114 */, 12 },
317
318 /* 272 */ { MAD_F(0x06e2594c) /* 0.430260942 */, 12 },
319 /* 273 */ { MAD_F(0x06eafe3a) /* 0.432371356 */, 12 },
320 /* 274 */ { MAD_F(0x06f3a5dc) /* 0.434484348 */, 12 },
321 /* 275 */ { MAD_F(0x06fc5030) /* 0.436599912 */, 12 },
322 /* 276 */ { MAD_F(0x0704fd35) /* 0.438718042 */, 12 },
323 /* 277 */ { MAD_F(0x070dacea) /* 0.440838732 */, 12 },
324 /* 278 */ { MAD_F(0x07165f4b) /* 0.442961975 */, 12 },
325 /* 279 */ { MAD_F(0x071f1459) /* 0.445087765 */, 12 },
326 /* 280 */ { MAD_F(0x0727cc11) /* 0.447216097 */, 12 },
327 /* 281 */ { MAD_F(0x07308671) /* 0.449346964 */, 12 },
328 /* 282 */ { MAD_F(0x07394378) /* 0.451480360 */, 12 },
329 /* 283 */ { MAD_F(0x07420325) /* 0.453616280 */, 12 },
330 /* 284 */ { MAD_F(0x074ac575) /* 0.455754717 */, 12 },
331 /* 285 */ { MAD_F(0x07538a67) /* 0.457895665 */, 12 },
332 /* 286 */ { MAD_F(0x075c51fa) /* 0.460039119 */, 12 },
333 /* 287 */ { MAD_F(0x07651c2c) /* 0.462185072 */, 12 },
334
335 /* 288 */ { MAD_F(0x076de8fc) /* 0.464333519 */, 12 },
336 /* 289 */ { MAD_F(0x0776b867) /* 0.466484455 */, 12 },
337 /* 290 */ { MAD_F(0x077f8a6d) /* 0.468637872 */, 12 },
338 /* 291 */ { MAD_F(0x07885f0b) /* 0.470793767 */, 12 },
339 /* 292 */ { MAD_F(0x07913641) /* 0.472952132 */, 12 },
340 /* 293 */ { MAD_F(0x079a100c) /* 0.475112962 */, 12 },
341 /* 294 */ { MAD_F(0x07a2ec6c) /* 0.477276252 */, 12 },
342 /* 295 */ { MAD_F(0x07abcb5f) /* 0.479441997 */, 12 },
343 /* 296 */ { MAD_F(0x07b4ace3) /* 0.481610189 */, 12 },
344 /* 297 */ { MAD_F(0x07bd90f6) /* 0.483780825 */, 12 },
345 /* 298 */ { MAD_F(0x07c67798) /* 0.485953899 */, 12 },
346 /* 299 */ { MAD_F(0x07cf60c7) /* 0.488129404 */, 12 },
347 /* 300 */ { MAD_F(0x07d84c81) /* 0.490307336 */, 12 },
348 /* 301 */ { MAD_F(0x07e13ac5) /* 0.492487690 */, 12 },
349 /* 302 */ { MAD_F(0x07ea2b92) /* 0.494670459 */, 12 },
350 /* 303 */ { MAD_F(0x07f31ee6) /* 0.496855639 */, 12 },
351
352 /* 304 */ { MAD_F(0x07fc14bf) /* 0.499043224 */, 12 },
353 /* 305 */ { MAD_F(0x0402868e) /* 0.250616605 */, 13 },
354 /* 306 */ { MAD_F(0x040703ff) /* 0.251712795 */, 13 },
355 /* 307 */ { MAD_F(0x040b82b0) /* 0.252810180 */, 13 },
356 /* 308 */ { MAD_F(0x041002a1) /* 0.253908756 */, 13 },
357 /* 309 */ { MAD_F(0x041483d1) /* 0.255008523 */, 13 },
358 /* 310 */ { MAD_F(0x04190640) /* 0.256109476 */, 13 },
359 /* 311 */ { MAD_F(0x041d89ed) /* 0.257211614 */, 13 },
360 /* 312 */ { MAD_F(0x04220ed7) /* 0.258314934 */, 13 },
361 /* 313 */ { MAD_F(0x042694fe) /* 0.259419433 */, 13 },
362 /* 314 */ { MAD_F(0x042b1c60) /* 0.260525110 */, 13 },
363 /* 315 */ { MAD_F(0x042fa4fe) /* 0.261631960 */, 13 },
364 /* 316 */ { MAD_F(0x04342ed7) /* 0.262739982 */, 13 },
365 /* 317 */ { MAD_F(0x0438b9e9) /* 0.263849174 */, 13 },
366 /* 318 */ { MAD_F(0x043d4635) /* 0.264959533 */, 13 },
367 /* 319 */ { MAD_F(0x0441d3b9) /* 0.266071056 */, 13 },
368
369 /* 320 */ { MAD_F(0x04466275) /* 0.267183742 */, 13 },
370 /* 321 */ { MAD_F(0x044af269) /* 0.268297587 */, 13 },
371 /* 322 */ { MAD_F(0x044f8393) /* 0.269412589 */, 13 },
372 /* 323 */ { MAD_F(0x045415f3) /* 0.270528746 */, 13 },
373 /* 324 */ { MAD_F(0x0458a989) /* 0.271646056 */, 13 },
374 /* 325 */ { MAD_F(0x045d3e53) /* 0.272764515 */, 13 },
375 /* 326 */ { MAD_F(0x0461d451) /* 0.273884123 */, 13 },
376 /* 327 */ { MAD_F(0x04666b83) /* 0.275004875 */, 13 },
377 /* 328 */ { MAD_F(0x046b03e7) /* 0.276126771 */, 13 },
378 /* 329 */ { MAD_F(0x046f9d7e) /* 0.277249808 */, 13 },
379 /* 330 */ { MAD_F(0x04743847) /* 0.278373983 */, 13 },
380 /* 331 */ { MAD_F(0x0478d440) /* 0.279499294 */, 13 },
381 /* 332 */ { MAD_F(0x047d716a) /* 0.280625739 */, 13 },
382 /* 333 */ { MAD_F(0x04820fc3) /* 0.281753315 */, 13 },
383 /* 334 */ { MAD_F(0x0486af4c) /* 0.282882021 */, 13 },
384 /* 335 */ { MAD_F(0x048b5003) /* 0.284011853 */, 13 },
385
386 /* 336 */ { MAD_F(0x048ff1e8) /* 0.285142811 */, 13 },
387 /* 337 */ { MAD_F(0x049494fb) /* 0.286274891 */, 13 },
388 /* 338 */ { MAD_F(0x0499393a) /* 0.287408091 */, 13 },
389 /* 339 */ { MAD_F(0x049ddea5) /* 0.288542409 */, 13 },
390 /* 340 */ { MAD_F(0x04a2853c) /* 0.289677844 */, 13 },
391 /* 341 */ { MAD_F(0x04a72cfe) /* 0.290814392 */, 13 },
392 /* 342 */ { MAD_F(0x04abd5ea) /* 0.291952051 */, 13 },
393 /* 343 */ { MAD_F(0x04b08000) /* 0.293090820 */, 13 },
394 /* 344 */ { MAD_F(0x04b52b3f) /* 0.294230696 */, 13 },
395 /* 345 */ { MAD_F(0x04b9d7a7) /* 0.295371678 */, 13 },
396 /* 346 */ { MAD_F(0x04be8537) /* 0.296513762 */, 13 },
397 /* 347 */ { MAD_F(0x04c333ee) /* 0.297656947 */, 13 },
398 /* 348 */ { MAD_F(0x04c7e3cc) /* 0.298801231 */, 13 },
399 /* 349 */ { MAD_F(0x04cc94d1) /* 0.299946611 */, 13 },
400 /* 350 */ { MAD_F(0x04d146fb) /* 0.301093085 */, 13 },
401 /* 351 */ { MAD_F(0x04d5fa4b) /* 0.302240653 */, 13 },
402
403 /* 352 */ { MAD_F(0x04daaec0) /* 0.303389310 */, 13 },
404 /* 353 */ { MAD_F(0x04df6458) /* 0.304539056 */, 13 },
405 /* 354 */ { MAD_F(0x04e41b14) /* 0.305689888 */, 13 },
406 /* 355 */ { MAD_F(0x04e8d2f3) /* 0.306841804 */, 13 },
407 /* 356 */ { MAD_F(0x04ed8bf5) /* 0.307994802 */, 13 },
408 /* 357 */ { MAD_F(0x04f24618) /* 0.309148880 */, 13 },
409 /* 358 */ { MAD_F(0x04f7015d) /* 0.310304037 */, 13 },
410 /* 359 */ { MAD_F(0x04fbbdc3) /* 0.311460269 */, 13 },
411 /* 360 */ { MAD_F(0x05007b49) /* 0.312617576 */, 13 },
412 /* 361 */ { MAD_F(0x050539ef) /* 0.313775954 */, 13 },
413 /* 362 */ { MAD_F(0x0509f9b4) /* 0.314935403 */, 13 },
414 /* 363 */ { MAD_F(0x050eba98) /* 0.316095920 */, 13 },
415 /* 364 */ { MAD_F(0x05137c9a) /* 0.317257503 */, 13 },
416 /* 365 */ { MAD_F(0x05183fba) /* 0.318420150 */, 13 },
417 /* 366 */ { MAD_F(0x051d03f7) /* 0.319583859 */, 13 },
418 /* 367 */ { MAD_F(0x0521c950) /* 0.320748629 */, 13 },
419
420 /* 368 */ { MAD_F(0x05268fc6) /* 0.321914457 */, 13 },
421 /* 369 */ { MAD_F(0x052b5757) /* 0.323081342 */, 13 },
422 /* 370 */ { MAD_F(0x05302003) /* 0.324249281 */, 13 },
423 /* 371 */ { MAD_F(0x0534e9ca) /* 0.325418273 */, 13 },
424 /* 372 */ { MAD_F(0x0539b4ab) /* 0.326588316 */, 13 },
425 /* 373 */ { MAD_F(0x053e80a6) /* 0.327759407 */, 13 },
426 /* 374 */ { MAD_F(0x05434db9) /* 0.328931546 */, 13 },
427 /* 375 */ { MAD_F(0x05481be5) /* 0.330104730 */, 13 },
428 /* 376 */ { MAD_F(0x054ceb2a) /* 0.331278957 */, 13 },
429 /* 377 */ { MAD_F(0x0551bb85) /* 0.332454225 */, 13 },
430 /* 378 */ { MAD_F(0x05568cf8) /* 0.333630533 */, 13 },
431 /* 379 */ { MAD_F(0x055b5f81) /* 0.334807879 */, 13 },
432 /* 380 */ { MAD_F(0x05603321) /* 0.335986261 */, 13 },
433 /* 381 */ { MAD_F(0x056507d6) /* 0.337165677 */, 13 },
434 /* 382 */ { MAD_F(0x0569dda0) /* 0.338346125 */, 13 },
435 /* 383 */ { MAD_F(0x056eb47f) /* 0.339527604 */, 13 },
436
437 /* 384 */ { MAD_F(0x05738c72) /* 0.340710111 */, 13 },
438 /* 385 */ { MAD_F(0x05786578) /* 0.341893646 */, 13 },
439 /* 386 */ { MAD_F(0x057d3f92) /* 0.343078205 */, 13 },
440 /* 387 */ { MAD_F(0x05821abf) /* 0.344263788 */, 13 },
441 /* 388 */ { MAD_F(0x0586f6fd) /* 0.345450393 */, 13 },
442 /* 389 */ { MAD_F(0x058bd44e) /* 0.346638017 */, 13 },
443 /* 390 */ { MAD_F(0x0590b2b0) /* 0.347826659 */, 13 },
444 /* 391 */ { MAD_F(0x05959222) /* 0.349016318 */, 13 },
445 /* 392 */ { MAD_F(0x059a72a5) /* 0.350206992 */, 13 },
446 /* 393 */ { MAD_F(0x059f5438) /* 0.351398678 */, 13 },
447 /* 394 */ { MAD_F(0x05a436da) /* 0.352591376 */, 13 },
448 /* 395 */ { MAD_F(0x05a91a8c) /* 0.353785083 */, 13 },
449 /* 396 */ { MAD_F(0x05adff4c) /* 0.354979798 */, 13 },
450 /* 397 */ { MAD_F(0x05b2e51a) /* 0.356175519 */, 13 },
451 /* 398 */ { MAD_F(0x05b7cbf5) /* 0.357372244 */, 13 },
452 /* 399 */ { MAD_F(0x05bcb3de) /* 0.358569972 */, 13 },
453
454 /* 400 */ { MAD_F(0x05c19cd3) /* 0.359768701 */, 13 },
455 /* 401 */ { MAD_F(0x05c686d5) /* 0.360968429 */, 13 },
456 /* 402 */ { MAD_F(0x05cb71e2) /* 0.362169156 */, 13 },
457 /* 403 */ { MAD_F(0x05d05dfb) /* 0.363370878 */, 13 },
458 /* 404 */ { MAD_F(0x05d54b1f) /* 0.364573594 */, 13 },
459 /* 405 */ { MAD_F(0x05da394d) /* 0.365777304 */, 13 },
460 /* 406 */ { MAD_F(0x05df2885) /* 0.366982004 */, 13 },
461 /* 407 */ { MAD_F(0x05e418c7) /* 0.368187694 */, 13 },
462 /* 408 */ { MAD_F(0x05e90a12) /* 0.369394372 */, 13 },
463 /* 409 */ { MAD_F(0x05edfc66) /* 0.370602036 */, 13 },
464 /* 410 */ { MAD_F(0x05f2efc2) /* 0.371810684 */, 13 },
465 /* 411 */ { MAD_F(0x05f7e426) /* 0.373020316 */, 13 },
466 /* 412 */ { MAD_F(0x05fcd992) /* 0.374230929 */, 13 },
467 /* 413 */ { MAD_F(0x0601d004) /* 0.375442522 */, 13 },
468 /* 414 */ { MAD_F(0x0606c77d) /* 0.376655093 */, 13 },
469 /* 415 */ { MAD_F(0x060bbffd) /* 0.377868641 */, 13 },
470
471 /* 416 */ { MAD_F(0x0610b982) /* 0.379083164 */, 13 },
472 /* 417 */ { MAD_F(0x0615b40c) /* 0.380298661 */, 13 },
473 /* 418 */ { MAD_F(0x061aaf9c) /* 0.381515130 */, 13 },
474 /* 419 */ { MAD_F(0x061fac2f) /* 0.382732569 */, 13 },
475 /* 420 */ { MAD_F(0x0624a9c7) /* 0.383950977 */, 13 },
476 /* 421 */ { MAD_F(0x0629a863) /* 0.385170352 */, 13 },
477 /* 422 */ { MAD_F(0x062ea802) /* 0.386390694 */, 13 },
478 /* 423 */ { MAD_F(0x0633a8a3) /* 0.387611999 */, 13 },
479 /* 424 */ { MAD_F(0x0638aa48) /* 0.388834268 */, 13 },
480 /* 425 */ { MAD_F(0x063dacee) /* 0.390057497 */, 13 },
481 /* 426 */ { MAD_F(0x0642b096) /* 0.391281687 */, 13 },
482 /* 427 */ { MAD_F(0x0647b53f) /* 0.392506834 */, 13 },
483 /* 428 */ { MAD_F(0x064cbae9) /* 0.393732939 */, 13 },
484 /* 429 */ { MAD_F(0x0651c193) /* 0.394959999 */, 13 },
485 /* 430 */ { MAD_F(0x0656c93d) /* 0.396188012 */, 13 },
486 /* 431 */ { MAD_F(0x065bd1e7) /* 0.397416978 */, 13 },
487
488 /* 432 */ { MAD_F(0x0660db91) /* 0.398646895 */, 13 },
489 /* 433 */ { MAD_F(0x0665e639) /* 0.399877761 */, 13 },
490 /* 434 */ { MAD_F(0x066af1df) /* 0.401109575 */, 13 },
491 /* 435 */ { MAD_F(0x066ffe84) /* 0.402342335 */, 13 },
492 /* 436 */ { MAD_F(0x06750c26) /* 0.403576041 */, 13 },
493 /* 437 */ { MAD_F(0x067a1ac6) /* 0.404810690 */, 13 },
494 /* 438 */ { MAD_F(0x067f2a62) /* 0.406046281 */, 13 },
495 /* 439 */ { MAD_F(0x06843afb) /* 0.407282813 */, 13 },
496 /* 440 */ { MAD_F(0x06894c90) /* 0.408520284 */, 13 },
497 /* 441 */ { MAD_F(0x068e5f21) /* 0.409758693 */, 13 },
498 /* 442 */ { MAD_F(0x069372ae) /* 0.410998038 */, 13 },
499 /* 443 */ { MAD_F(0x06988735) /* 0.412238319 */, 13 },
500 /* 444 */ { MAD_F(0x069d9cb7) /* 0.413479532 */, 13 },
501 /* 445 */ { MAD_F(0x06a2b333) /* 0.414721679 */, 13 },
502 /* 446 */ { MAD_F(0x06a7caa9) /* 0.415964756 */, 13 },
503 /* 447 */ { MAD_F(0x06ace318) /* 0.417208762 */, 13 },
504
505 /* 448 */ { MAD_F(0x06b1fc81) /* 0.418453696 */, 13 },
506 /* 449 */ { MAD_F(0x06b716e2) /* 0.419699557 */, 13 },
507 /* 450 */ { MAD_F(0x06bc323b) /* 0.420946343 */, 13 },
508 /* 451 */ { MAD_F(0x06c14e8d) /* 0.422194054 */, 13 },
509 /* 452 */ { MAD_F(0x06c66bd6) /* 0.423442686 */, 13 },
510 /* 453 */ { MAD_F(0x06cb8a17) /* 0.424692240 */, 13 },
511 /* 454 */ { MAD_F(0x06d0a94e) /* 0.425942714 */, 13 },
512 /* 455 */ { MAD_F(0x06d5c97c) /* 0.427194106 */, 13 },
513 /* 456 */ { MAD_F(0x06daeaa1) /* 0.428446415 */, 13 },
514 /* 457 */ { MAD_F(0x06e00cbb) /* 0.429699640 */, 13 },
515 /* 458 */ { MAD_F(0x06e52fca) /* 0.430953779 */, 13 },
516 /* 459 */ { MAD_F(0x06ea53cf) /* 0.432208832 */, 13 },
517 /* 460 */ { MAD_F(0x06ef78c8) /* 0.433464796 */, 13 },
518 /* 461 */ { MAD_F(0x06f49eb6) /* 0.434721671 */, 13 },
519 /* 462 */ { MAD_F(0x06f9c597) /* 0.435979455 */, 13 },
520 /* 463 */ { MAD_F(0x06feed6d) /* 0.437238146 */, 13 },
521
522 /* 464 */ { MAD_F(0x07041636) /* 0.438497744 */, 13 },
523 /* 465 */ { MAD_F(0x07093ff2) /* 0.439758248 */, 13 },
524 /* 466 */ { MAD_F(0x070e6aa0) /* 0.441019655 */, 13 },
525 /* 467 */ { MAD_F(0x07139641) /* 0.442281965 */, 13 },
526 /* 468 */ { MAD_F(0x0718c2d3) /* 0.443545176 */, 13 },
527 /* 469 */ { MAD_F(0x071df058) /* 0.444809288 */, 13 },
528 /* 470 */ { MAD_F(0x07231ecd) /* 0.446074298 */, 13 },
529 /* 471 */ { MAD_F(0x07284e34) /* 0.447340205 */, 13 },
530 /* 472 */ { MAD_F(0x072d7e8b) /* 0.448607009 */, 13 },
531 /* 473 */ { MAD_F(0x0732afd2) /* 0.449874708 */, 13 },
532 /* 474 */ { MAD_F(0x0737e209) /* 0.451143300 */, 13 },
533 /* 475 */ { MAD_F(0x073d1530) /* 0.452412785 */, 13 },
534 /* 476 */ { MAD_F(0x07424946) /* 0.453683161 */, 13 },
535 /* 477 */ { MAD_F(0x07477e4b) /* 0.454954427 */, 13 },
536 /* 478 */ { MAD_F(0x074cb43e) /* 0.456226581 */, 13 },
537 /* 479 */ { MAD_F(0x0751eb20) /* 0.457499623 */, 13 },
538
539 /* 480 */ { MAD_F(0x075722ef) /* 0.458773552 */, 13 },
540 /* 481 */ { MAD_F(0x075c5bac) /* 0.460048365 */, 13 },
541 /* 482 */ { MAD_F(0x07619557) /* 0.461324062 */, 13 },
542 /* 483 */ { MAD_F(0x0766cfee) /* 0.462600642 */, 13 },
543 /* 484 */ { MAD_F(0x076c0b72) /* 0.463878102 */, 13 },
544 /* 485 */ { MAD_F(0x077147e2) /* 0.465156443 */, 13 },
545 /* 486 */ { MAD_F(0x0776853e) /* 0.466435663 */, 13 },
546 /* 487 */ { MAD_F(0x077bc385) /* 0.467715761 */, 13 },
547 /* 488 */ { MAD_F(0x078102b8) /* 0.468996735 */, 13 },
548 /* 489 */ { MAD_F(0x078642d6) /* 0.470278584 */, 13 },
549 /* 490 */ { MAD_F(0x078b83de) /* 0.471561307 */, 13 },
550 /* 491 */ { MAD_F(0x0790c5d1) /* 0.472844904 */, 13 },
551 /* 492 */ { MAD_F(0x079608ae) /* 0.474129372 */, 13 },
552 /* 493 */ { MAD_F(0x079b4c74) /* 0.475414710 */, 13 },
553 /* 494 */ { MAD_F(0x07a09124) /* 0.476700918 */, 13 },
554 /* 495 */ { MAD_F(0x07a5d6bd) /* 0.477987994 */, 13 },
555
556 /* 496 */ { MAD_F(0x07ab1d3e) /* 0.479275937 */, 13 },
557 /* 497 */ { MAD_F(0x07b064a8) /* 0.480564746 */, 13 },
558 /* 498 */ { MAD_F(0x07b5acfb) /* 0.481854420 */, 13 },
559 /* 499 */ { MAD_F(0x07baf635) /* 0.483144957 */, 13 },
560 /* 500 */ { MAD_F(0x07c04056) /* 0.484436356 */, 13 },
561 /* 501 */ { MAD_F(0x07c58b5f) /* 0.485728617 */, 13 },
562 /* 502 */ { MAD_F(0x07cad74e) /* 0.487021738 */, 13 },
563 /* 503 */ { MAD_F(0x07d02424) /* 0.488315717 */, 13 },
564 /* 504 */ { MAD_F(0x07d571e0) /* 0.489610555 */, 13 },
565 /* 505 */ { MAD_F(0x07dac083) /* 0.490906249 */, 13 },
566 /* 506 */ { MAD_F(0x07e0100a) /* 0.492202799 */, 13 },
567 /* 507 */ { MAD_F(0x07e56078) /* 0.493500203 */, 13 },
568 /* 508 */ { MAD_F(0x07eab1ca) /* 0.494798460 */, 13 },
569 /* 509 */ { MAD_F(0x07f00401) /* 0.496097570 */, 13 },
570 /* 510 */ { MAD_F(0x07f5571d) /* 0.497397530 */, 13 },
571 /* 511 */ { MAD_F(0x07faab1c) /* 0.498698341 */, 13 },
572
573 /* 512 */ { MAD_F(0x04000000) /* 0.250000000 */, 14 },
574 /* 513 */ { MAD_F(0x0402aae3) /* 0.250651254 */, 14 },
575 /* 514 */ { MAD_F(0x04055638) /* 0.251302930 */, 14 },
576 /* 515 */ { MAD_F(0x040801ff) /* 0.251955030 */, 14 },
577 /* 516 */ { MAD_F(0x040aae37) /* 0.252607552 */, 14 },
578 /* 517 */ { MAD_F(0x040d5ae0) /* 0.253260495 */, 14 },
579 /* 518 */ { MAD_F(0x041007fa) /* 0.253913860 */, 14 },
580 /* 519 */ { MAD_F(0x0412b586) /* 0.254567645 */, 14 },
581 /* 520 */ { MAD_F(0x04156381) /* 0.255221850 */, 14 },
582 /* 521 */ { MAD_F(0x041811ee) /* 0.255876475 */, 14 },
583 /* 522 */ { MAD_F(0x041ac0cb) /* 0.256531518 */, 14 },
584 /* 523 */ { MAD_F(0x041d7018) /* 0.257186980 */, 14 },
585 /* 524 */ { MAD_F(0x04201fd5) /* 0.257842860 */, 14 },
586 /* 525 */ { MAD_F(0x0422d003) /* 0.258499157 */, 14 },
587 /* 526 */ { MAD_F(0x042580a0) /* 0.259155872 */, 14 },
588 /* 527 */ { MAD_F(0x042831ad) /* 0.259813002 */, 14 },
589
590 /* 528 */ { MAD_F(0x042ae32a) /* 0.260470548 */, 14 },
591 /* 529 */ { MAD_F(0x042d9516) /* 0.261128510 */, 14 },
592 /* 530 */ { MAD_F(0x04304772) /* 0.261786886 */, 14 },
593 /* 531 */ { MAD_F(0x0432fa3d) /* 0.262445676 */, 14 },
594 /* 532 */ { MAD_F(0x0435ad76) /* 0.263104880 */, 14 },
595 /* 533 */ { MAD_F(0x0438611f) /* 0.263764497 */, 14 },
596 /* 534 */ { MAD_F(0x043b1536) /* 0.264424527 */, 14 },
597 /* 535 */ { MAD_F(0x043dc9bc) /* 0.265084969 */, 14 },
598 /* 536 */ { MAD_F(0x04407eb1) /* 0.265745823 */, 14 },
599 /* 537 */ { MAD_F(0x04433414) /* 0.266407088 */, 14 },
600 /* 538 */ { MAD_F(0x0445e9e5) /* 0.267068763 */, 14 },
601 /* 539 */ { MAD_F(0x0448a024) /* 0.267730848 */, 14 },
602 /* 540 */ { MAD_F(0x044b56d1) /* 0.268393343 */, 14 },
603 /* 541 */ { MAD_F(0x044e0dec) /* 0.269056248 */, 14 },
604 /* 542 */ { MAD_F(0x0450c575) /* 0.269719560 */, 14 },
605 /* 543 */ { MAD_F(0x04537d6b) /* 0.270383281 */, 14 },
606
607 /* 544 */ { MAD_F(0x045635cf) /* 0.271047409 */, 14 },
608 /* 545 */ { MAD_F(0x0458ee9f) /* 0.271711944 */, 14 },
609 /* 546 */ { MAD_F(0x045ba7dd) /* 0.272376886 */, 14 },
610 /* 547 */ { MAD_F(0x045e6188) /* 0.273042234 */, 14 },
611 /* 548 */ { MAD_F(0x04611ba0) /* 0.273707988 */, 14 },
612 /* 549 */ { MAD_F(0x0463d625) /* 0.274374147 */, 14 },
613 /* 550 */ { MAD_F(0x04669116) /* 0.275040710 */, 14 },
614 /* 551 */ { MAD_F(0x04694c74) /* 0.275707677 */, 14 },
615 /* 552 */ { MAD_F(0x046c083e) /* 0.276375048 */, 14 },
616 /* 553 */ { MAD_F(0x046ec474) /* 0.277042822 */, 14 },
617 /* 554 */ { MAD_F(0x04718116) /* 0.277710999 */, 14 },
618 /* 555 */ { MAD_F(0x04743e25) /* 0.278379578 */, 14 },
619 /* 556 */ { MAD_F(0x0476fb9f) /* 0.279048558 */, 14 },
620 /* 557 */ { MAD_F(0x0479b984) /* 0.279717940 */, 14 },
621 /* 558 */ { MAD_F(0x047c77d6) /* 0.280387722 */, 14 },
622 /* 559 */ { MAD_F(0x047f3693) /* 0.281057905 */, 14 },
623
624 /* 560 */ { MAD_F(0x0481f5bb) /* 0.281728487 */, 14 },
625 /* 561 */ { MAD_F(0x0484b54e) /* 0.282399469 */, 14 },
626 /* 562 */ { MAD_F(0x0487754c) /* 0.283070849 */, 14 },
627 /* 563 */ { MAD_F(0x048a35b6) /* 0.283742628 */, 14 },
628 /* 564 */ { MAD_F(0x048cf68a) /* 0.284414805 */, 14 },
629 /* 565 */ { MAD_F(0x048fb7c8) /* 0.285087379 */, 14 },
630 /* 566 */ { MAD_F(0x04927972) /* 0.285760350 */, 14 },
631 /* 567 */ { MAD_F(0x04953b85) /* 0.286433717 */, 14 },
632 /* 568 */ { MAD_F(0x0497fe03) /* 0.287107481 */, 14 },
633 /* 569 */ { MAD_F(0x049ac0eb) /* 0.287781640 */, 14 },
634 /* 570 */ { MAD_F(0x049d843e) /* 0.288456194 */, 14 },
635 /* 571 */ { MAD_F(0x04a047fa) /* 0.289131142 */, 14 },
636 /* 572 */ { MAD_F(0x04a30c20) /* 0.289806485 */, 14 },
637 /* 573 */ { MAD_F(0x04a5d0af) /* 0.290482221 */, 14 },
638 /* 574 */ { MAD_F(0x04a895a8) /* 0.291158351 */, 14 },
639 /* 575 */ { MAD_F(0x04ab5b0b) /* 0.291834873 */, 14 },
640
641 /* 576 */ { MAD_F(0x04ae20d7) /* 0.292511788 */, 14 },
642 /* 577 */ { MAD_F(0x04b0e70c) /* 0.293189094 */, 14 },
643 /* 578 */ { MAD_F(0x04b3adaa) /* 0.293866792 */, 14 },
644 /* 579 */ { MAD_F(0x04b674b1) /* 0.294544881 */, 14 },
645 /* 580 */ { MAD_F(0x04b93c21) /* 0.295223360 */, 14 },
646 /* 581 */ { MAD_F(0x04bc03fa) /* 0.295902229 */, 14 },
647 /* 582 */ { MAD_F(0x04becc3b) /* 0.296581488 */, 14 },
648 /* 583 */ { MAD_F(0x04c194e4) /* 0.297261136 */, 14 },
649 /* 584 */ { MAD_F(0x04c45df6) /* 0.297941173 */, 14 },
650 /* 585 */ { MAD_F(0x04c72771) /* 0.298621598 */, 14 },
651 /* 586 */ { MAD_F(0x04c9f153) /* 0.299302411 */, 14 },
652 /* 587 */ { MAD_F(0x04ccbb9d) /* 0.299983611 */, 14 },
653 /* 588 */ { MAD_F(0x04cf864f) /* 0.300665198 */, 14 },
654 /* 589 */ { MAD_F(0x04d25169) /* 0.301347172 */, 14 },
655 /* 590 */ { MAD_F(0x04d51ceb) /* 0.302029532 */, 14 },
656 /* 591 */ { MAD_F(0x04d7e8d4) /* 0.302712277 */, 14 },
657
658 /* 592 */ { MAD_F(0x04dab524) /* 0.303395408 */, 14 },
659 /* 593 */ { MAD_F(0x04dd81dc) /* 0.304078923 */, 14 },
660 /* 594 */ { MAD_F(0x04e04efb) /* 0.304762823 */, 14 },
661 /* 595 */ { MAD_F(0x04e31c81) /* 0.305447106 */, 14 },
662 /* 596 */ { MAD_F(0x04e5ea6e) /* 0.306131773 */, 14 },
663 /* 597 */ { MAD_F(0x04e8b8c2) /* 0.306816823 */, 14 },
664 /* 598 */ { MAD_F(0x04eb877c) /* 0.307502256 */, 14 },
665 /* 599 */ { MAD_F(0x04ee569d) /* 0.308188071 */, 14 },
666 /* 600 */ { MAD_F(0x04f12624) /* 0.308874267 */, 14 },
667 /* 601 */ { MAD_F(0x04f3f612) /* 0.309560845 */, 14 },
668 /* 602 */ { MAD_F(0x04f6c666) /* 0.310247804 */, 14 },
669 /* 603 */ { MAD_F(0x04f99721) /* 0.310935143 */, 14 },
670 /* 604 */ { MAD_F(0x04fc6841) /* 0.311622862 */, 14 },
671 /* 605 */ { MAD_F(0x04ff39c7) /* 0.312310961 */, 14 },
672 /* 606 */ { MAD_F(0x05020bb3) /* 0.312999439 */, 14 },
673 /* 607 */ { MAD_F(0x0504de05) /* 0.313688296 */, 14 },
674
675 /* 608 */ { MAD_F(0x0507b0bc) /* 0.314377532 */, 14 },
676 /* 609 */ { MAD_F(0x050a83d8) /* 0.315067145 */, 14 },
677 /* 610 */ { MAD_F(0x050d575b) /* 0.315757136 */, 14 },
678 /* 611 */ { MAD_F(0x05102b42) /* 0.316447504 */, 14 },
679 /* 612 */ { MAD_F(0x0512ff8e) /* 0.317138249 */, 14 },
680 /* 613 */ { MAD_F(0x0515d440) /* 0.317829370 */, 14 },
681 /* 614 */ { MAD_F(0x0518a956) /* 0.318520867 */, 14 },
682 /* 615 */ { MAD_F(0x051b7ed1) /* 0.319212739 */, 14 },
683 /* 616 */ { MAD_F(0x051e54b1) /* 0.319904987 */, 14 },
684 /* 617 */ { MAD_F(0x05212af5) /* 0.320597609 */, 14 },
685 /* 618 */ { MAD_F(0x0524019e) /* 0.321290606 */, 14 },
686 /* 619 */ { MAD_F(0x0526d8ab) /* 0.321983976 */, 14 },
687 /* 620 */ { MAD_F(0x0529b01d) /* 0.322677720 */, 14 },
688 /* 621 */ { MAD_F(0x052c87f2) /* 0.323371837 */, 14 },
689 /* 622 */ { MAD_F(0x052f602c) /* 0.324066327 */, 14 },
690 /* 623 */ { MAD_F(0x053238ca) /* 0.324761189 */, 14 },
691
692 /* 624 */ { MAD_F(0x053511cb) /* 0.325456423 */, 14 },
693 /* 625 */ { MAD_F(0x0537eb30) /* 0.326152028 */, 14 },
694 /* 626 */ { MAD_F(0x053ac4f9) /* 0.326848005 */, 14 },
695 /* 627 */ { MAD_F(0x053d9f25) /* 0.327544352 */, 14 },
696 /* 628 */ { MAD_F(0x054079b5) /* 0.328241070 */, 14 },
697 /* 629 */ { MAD_F(0x054354a8) /* 0.328938157 */, 14 },
698 /* 630 */ { MAD_F(0x05462ffe) /* 0.329635614 */, 14 },
699 /* 631 */ { MAD_F(0x05490bb7) /* 0.330333440 */, 14 },
700 /* 632 */ { MAD_F(0x054be7d4) /* 0.331031635 */, 14 },
701 /* 633 */ { MAD_F(0x054ec453) /* 0.331730198 */, 14 },
702 /* 634 */ { MAD_F(0x0551a134) /* 0.332429129 */, 14 },
703 /* 635 */ { MAD_F(0x05547e79) /* 0.333128427 */, 14 },
704 /* 636 */ { MAD_F(0x05575c20) /* 0.333828093 */, 14 },
705 /* 637 */ { MAD_F(0x055a3a2a) /* 0.334528126 */, 14 },
706 /* 638 */ { MAD_F(0x055d1896) /* 0.335228525 */, 14 },
707 /* 639 */ { MAD_F(0x055ff764) /* 0.335929290 */, 14 },
708
709 /* 640 */ { MAD_F(0x0562d694) /* 0.336630420 */, 14 },
710 /* 641 */ { MAD_F(0x0565b627) /* 0.337331916 */, 14 },
711 /* 642 */ { MAD_F(0x0568961b) /* 0.338033777 */, 14 },
712 /* 643 */ { MAD_F(0x056b7671) /* 0.338736002 */, 14 },
713 /* 644 */ { MAD_F(0x056e5729) /* 0.339438592 */, 14 },
714 /* 645 */ { MAD_F(0x05713843) /* 0.340141545 */, 14 },
715 /* 646 */ { MAD_F(0x057419be) /* 0.340844862 */, 14 },
716 /* 647 */ { MAD_F(0x0576fb9a) /* 0.341548541 */, 14 },
717 /* 648 */ { MAD_F(0x0579ddd8) /* 0.342252584 */, 14 },
718 /* 649 */ { MAD_F(0x057cc077) /* 0.342956988 */, 14 },
719 /* 650 */ { MAD_F(0x057fa378) /* 0.343661754 */, 14 },
720 /* 651 */ { MAD_F(0x058286d9) /* 0.344366882 */, 14 },
721 /* 652 */ { MAD_F(0x05856a9b) /* 0.345072371 */, 14 },
722 /* 653 */ { MAD_F(0x05884ebe) /* 0.345778221 */, 14 },
723 /* 654 */ { MAD_F(0x058b3342) /* 0.346484431 */, 14 },
724 /* 655 */ { MAD_F(0x058e1827) /* 0.347191002 */, 14 },
725
726 /* 656 */ { MAD_F(0x0590fd6c) /* 0.347897931 */, 14 },
727 /* 657 */ { MAD_F(0x0593e311) /* 0.348605221 */, 14 },
728 /* 658 */ { MAD_F(0x0596c917) /* 0.349312869 */, 14 },
729 /* 659 */ { MAD_F(0x0599af7d) /* 0.350020876 */, 14 },
730 /* 660 */ { MAD_F(0x059c9643) /* 0.350729240 */, 14 },
731 /* 661 */ { MAD_F(0x059f7d6a) /* 0.351437963 */, 14 },
732 /* 662 */ { MAD_F(0x05a264f0) /* 0.352147044 */, 14 },
733 /* 663 */ { MAD_F(0x05a54cd6) /* 0.352856481 */, 14 },
734 /* 664 */ { MAD_F(0x05a8351c) /* 0.353566275 */, 14 },
735 /* 665 */ { MAD_F(0x05ab1dc2) /* 0.354276426 */, 14 },
736 /* 666 */ { MAD_F(0x05ae06c7) /* 0.354986932 */, 14 },
737 /* 667 */ { MAD_F(0x05b0f02b) /* 0.355697795 */, 14 },
738 /* 668 */ { MAD_F(0x05b3d9f0) /* 0.356409012 */, 14 },
739 /* 669 */ { MAD_F(0x05b6c413) /* 0.357120585 */, 14 },
740 /* 670 */ { MAD_F(0x05b9ae95) /* 0.357832512 */, 14 },
741 /* 671 */ { MAD_F(0x05bc9977) /* 0.358544794 */, 14 },
742
743 /* 672 */ { MAD_F(0x05bf84b8) /* 0.359257429 */, 14 },
744 /* 673 */ { MAD_F(0x05c27057) /* 0.359970419 */, 14 },
745 /* 674 */ { MAD_F(0x05c55c56) /* 0.360683761 */, 14 },
746 /* 675 */ { MAD_F(0x05c848b3) /* 0.361397456 */, 14 },
747 /* 676 */ { MAD_F(0x05cb356e) /* 0.362111504 */, 14 },
748 /* 677 */ { MAD_F(0x05ce2289) /* 0.362825904 */, 14 },
749 /* 678 */ { MAD_F(0x05d11001) /* 0.363540655 */, 14 },
750 /* 679 */ { MAD_F(0x05d3fdd8) /* 0.364255759 */, 14 },
751 /* 680 */ { MAD_F(0x05d6ec0e) /* 0.364971213 */, 14 },
752 /* 681 */ { MAD_F(0x05d9daa1) /* 0.365687018 */, 14 },
753 /* 682 */ { MAD_F(0x05dcc993) /* 0.366403174 */, 14 },
754 /* 683 */ { MAD_F(0x05dfb8e2) /* 0.367119680 */, 14 },
755 /* 684 */ { MAD_F(0x05e2a890) /* 0.367836535 */, 14 },
756 /* 685 */ { MAD_F(0x05e5989b) /* 0.368553740 */, 14 },
757 /* 686 */ { MAD_F(0x05e88904) /* 0.369271294 */, 14 },
758 /* 687 */ { MAD_F(0x05eb79cb) /* 0.369989197 */, 14 },
759
760 /* 688 */ { MAD_F(0x05ee6aef) /* 0.370707448 */, 14 },
761 /* 689 */ { MAD_F(0x05f15c70) /* 0.371426047 */, 14 },
762 /* 690 */ { MAD_F(0x05f44e4f) /* 0.372144994 */, 14 },
763 /* 691 */ { MAD_F(0x05f7408b) /* 0.372864289 */, 14 },
764 /* 692 */ { MAD_F(0x05fa3324) /* 0.373583930 */, 14 },
765 /* 693 */ { MAD_F(0x05fd261b) /* 0.374303918 */, 14 },
766 /* 694 */ { MAD_F(0x0600196e) /* 0.375024253 */, 14 },
767 /* 695 */ { MAD_F(0x06030d1e) /* 0.375744934 */, 14 },
768 /* 696 */ { MAD_F(0x0606012b) /* 0.376465960 */, 14 },
769 /* 697 */ { MAD_F(0x0608f595) /* 0.377187332 */, 14 },
770 /* 698 */ { MAD_F(0x060bea5c) /* 0.377909049 */, 14 },
771 /* 699 */ { MAD_F(0x060edf7f) /* 0.378631110 */, 14 },
772 /* 700 */ { MAD_F(0x0611d4fe) /* 0.379353516 */, 14 },
773 /* 701 */ { MAD_F(0x0614cada) /* 0.380076266 */, 14 },
774 /* 702 */ { MAD_F(0x0617c112) /* 0.380799360 */, 14 },
775 /* 703 */ { MAD_F(0x061ab7a6) /* 0.381522798 */, 14 },
776
777 /* 704 */ { MAD_F(0x061dae96) /* 0.382246578 */, 14 },
778 /* 705 */ { MAD_F(0x0620a5e3) /* 0.382970701 */, 14 },
779 /* 706 */ { MAD_F(0x06239d8b) /* 0.383695167 */, 14 },
780 /* 707 */ { MAD_F(0x0626958f) /* 0.384419975 */, 14 },
781 /* 708 */ { MAD_F(0x06298def) /* 0.385145124 */, 14 },
782 /* 709 */ { MAD_F(0x062c86aa) /* 0.385870615 */, 14 },
783 /* 710 */ { MAD_F(0x062f7fc1) /* 0.386596448 */, 14 },
784 /* 711 */ { MAD_F(0x06327934) /* 0.387322621 */, 14 },
785 /* 712 */ { MAD_F(0x06357302) /* 0.388049134 */, 14 },
786 /* 713 */ { MAD_F(0x06386d2b) /* 0.388775988 */, 14 },
787 /* 714 */ { MAD_F(0x063b67b0) /* 0.389503182 */, 14 },
788 /* 715 */ { MAD_F(0x063e6290) /* 0.390230715 */, 14 },
789 /* 716 */ { MAD_F(0x06415dcb) /* 0.390958588 */, 14 },
790 /* 717 */ { MAD_F(0x06445960) /* 0.391686799 */, 14 },
791 /* 718 */ { MAD_F(0x06475551) /* 0.392415349 */, 14 },
792 /* 719 */ { MAD_F(0x064a519c) /* 0.393144238 */, 14 },
793
794 /* 720 */ { MAD_F(0x064d4e43) /* 0.393873464 */, 14 },
795 /* 721 */ { MAD_F(0x06504b44) /* 0.394603028 */, 14 },
796 /* 722 */ { MAD_F(0x0653489f) /* 0.395332930 */, 14 },
797 /* 723 */ { MAD_F(0x06564655) /* 0.396063168 */, 14 },
798 /* 724 */ { MAD_F(0x06594465) /* 0.396793743 */, 14 },
799 /* 725 */ { MAD_F(0x065c42d0) /* 0.397524655 */, 14 },
800 /* 726 */ { MAD_F(0x065f4195) /* 0.398255903 */, 14 },
801 /* 727 */ { MAD_F(0x066240b4) /* 0.398987487 */, 14 },
802 /* 728 */ { MAD_F(0x0665402d) /* 0.399719406 */, 14 },
803 /* 729 */ { MAD_F(0x06684000) /* 0.400451660 */, 14 },
804 /* 730 */ { MAD_F(0x066b402d) /* 0.401184249 */, 14 },
805 /* 731 */ { MAD_F(0x066e40b3) /* 0.401917173 */, 14 },
806 /* 732 */ { MAD_F(0x06714194) /* 0.402650431 */, 14 },
807 /* 733 */ { MAD_F(0x067442ce) /* 0.403384024 */, 14 },
808 /* 734 */ { MAD_F(0x06774462) /* 0.404117949 */, 14 },
809 /* 735 */ { MAD_F(0x067a464f) /* 0.404852209 */, 14 },
810
811 /* 736 */ { MAD_F(0x067d4896) /* 0.405586801 */, 14 },
812 /* 737 */ { MAD_F(0x06804b36) /* 0.406321726 */, 14 },
813 /* 738 */ { MAD_F(0x06834e2f) /* 0.407056983 */, 14 },
814 /* 739 */ { MAD_F(0x06865181) /* 0.407792573 */, 14 },
815 /* 740 */ { MAD_F(0x0689552c) /* 0.408528495 */, 14 },
816 /* 741 */ { MAD_F(0x068c5931) /* 0.409264748 */, 14 },
817 /* 742 */ { MAD_F(0x068f5d8e) /* 0.410001332 */, 14 },
818 /* 743 */ { MAD_F(0x06926245) /* 0.410738247 */, 14 },
819 /* 744 */ { MAD_F(0x06956753) /* 0.411475493 */, 14 },
820 /* 745 */ { MAD_F(0x06986cbb) /* 0.412213070 */, 14 },
821 /* 746 */ { MAD_F(0x069b727b) /* 0.412950976 */, 14 },
822 /* 747 */ { MAD_F(0x069e7894) /* 0.413689213 */, 14 },
823 /* 748 */ { MAD_F(0x06a17f05) /* 0.414427779 */, 14 },
824 /* 749 */ { MAD_F(0x06a485cf) /* 0.415166674 */, 14 },
825 /* 750 */ { MAD_F(0x06a78cf1) /* 0.415905897 */, 14 },
826 /* 751 */ { MAD_F(0x06aa946b) /* 0.416645450 */, 14 },
827
828 /* 752 */ { MAD_F(0x06ad9c3d) /* 0.417385331 */, 14 },
829 /* 753 */ { MAD_F(0x06b0a468) /* 0.418125540 */, 14 },
830 /* 754 */ { MAD_F(0x06b3acea) /* 0.418866076 */, 14 },
831 /* 755 */ { MAD_F(0x06b6b5c4) /* 0.419606940 */, 14 },
832 /* 756 */ { MAD_F(0x06b9bef6) /* 0.420348132 */, 14 },
833 /* 757 */ { MAD_F(0x06bcc880) /* 0.421089650 */, 14 },
834 /* 758 */ { MAD_F(0x06bfd261) /* 0.421831494 */, 14 },
835 /* 759 */ { MAD_F(0x06c2dc9a) /* 0.422573665 */, 14 },
836 /* 760 */ { MAD_F(0x06c5e72b) /* 0.423316162 */, 14 },
837 /* 761 */ { MAD_F(0x06c8f213) /* 0.424058985 */, 14 },
838 /* 762 */ { MAD_F(0x06cbfd52) /* 0.424802133 */, 14 },
839 /* 763 */ { MAD_F(0x06cf08e9) /* 0.425545607 */, 14 },
840 /* 764 */ { MAD_F(0x06d214d7) /* 0.426289405 */, 14 },
841 /* 765 */ { MAD_F(0x06d5211c) /* 0.427033528 */, 14 },
842 /* 766 */ { MAD_F(0x06d82db8) /* 0.427777975 */, 14 },
843 /* 767 */ { MAD_F(0x06db3aaa) /* 0.428522746 */, 14 },
844
845 /* 768 */ { MAD_F(0x06de47f4) /* 0.429267841 */, 14 },
846 /* 769 */ { MAD_F(0x06e15595) /* 0.430013259 */, 14 },
847 /* 770 */ { MAD_F(0x06e4638d) /* 0.430759001 */, 14 },
848 /* 771 */ { MAD_F(0x06e771db) /* 0.431505065 */, 14 },
849 /* 772 */ { MAD_F(0x06ea807f) /* 0.432251452 */, 14 },
850 /* 773 */ { MAD_F(0x06ed8f7b) /* 0.432998162 */, 14 },
851 /* 774 */ { MAD_F(0x06f09ecc) /* 0.433745193 */, 14 },
852 /* 775 */ { MAD_F(0x06f3ae75) /* 0.434492546 */, 14 },
853 /* 776 */ { MAD_F(0x06f6be73) /* 0.435240221 */, 14 },
854 /* 777 */ { MAD_F(0x06f9cec8) /* 0.435988217 */, 14 },
855 /* 778 */ { MAD_F(0x06fcdf72) /* 0.436736534 */, 14 },
856 /* 779 */ { MAD_F(0x06fff073) /* 0.437485172 */, 14 },
857 /* 780 */ { MAD_F(0x070301ca) /* 0.438234130 */, 14 },
858 /* 781 */ { MAD_F(0x07061377) /* 0.438983408 */, 14 },
859 /* 782 */ { MAD_F(0x0709257a) /* 0.439733006 */, 14 },
860 /* 783 */ { MAD_F(0x070c37d2) /* 0.440482924 */, 14 },
861
862 /* 784 */ { MAD_F(0x070f4a80) /* 0.441233161 */, 14 },
863 /* 785 */ { MAD_F(0x07125d84) /* 0.441983717 */, 14 },
864 /* 786 */ { MAD_F(0x071570de) /* 0.442734592 */, 14 },
865 /* 787 */ { MAD_F(0x0718848d) /* 0.443485785 */, 14 },
866 /* 788 */ { MAD_F(0x071b9891) /* 0.444237296 */, 14 },
867 /* 789 */ { MAD_F(0x071eaceb) /* 0.444989126 */, 14 },
868 /* 790 */ { MAD_F(0x0721c19a) /* 0.445741273 */, 14 },
869 /* 791 */ { MAD_F(0x0724d69e) /* 0.446493738 */, 14 },
870 /* 792 */ { MAD_F(0x0727ebf7) /* 0.447246519 */, 14 },
871 /* 793 */ { MAD_F(0x072b01a6) /* 0.447999618 */, 14 },
872 /* 794 */ { MAD_F(0x072e17a9) /* 0.448753033 */, 14 },
873 /* 795 */ { MAD_F(0x07312e01) /* 0.449506765 */, 14 },
874 /* 796 */ { MAD_F(0x073444ae) /* 0.450260813 */, 14 },
875 /* 797 */ { MAD_F(0x07375bb0) /* 0.451015176 */, 14 },
876 /* 798 */ { MAD_F(0x073a7307) /* 0.451769856 */, 14 },
877 /* 799 */ { MAD_F(0x073d8ab2) /* 0.452524850 */, 14 },
878
879 /* 800 */ { MAD_F(0x0740a2b2) /* 0.453280160 */, 14 },
880 /* 801 */ { MAD_F(0x0743bb06) /* 0.454035784 */, 14 },
881 /* 802 */ { MAD_F(0x0746d3af) /* 0.454791723 */, 14 },
882 /* 803 */ { MAD_F(0x0749ecac) /* 0.455547976 */, 14 },
883 /* 804 */ { MAD_F(0x074d05fe) /* 0.456304543 */, 14 },
884 /* 805 */ { MAD_F(0x07501fa3) /* 0.457061423 */, 14 },
885 /* 806 */ { MAD_F(0x0753399d) /* 0.457818618 */, 14 },
886 /* 807 */ { MAD_F(0x075653eb) /* 0.458576125 */, 14 },
887 /* 808 */ { MAD_F(0x07596e8d) /* 0.459333946 */, 14 },
888 /* 809 */ { MAD_F(0x075c8983) /* 0.460092079 */, 14 },
889 /* 810 */ { MAD_F(0x075fa4cc) /* 0.460850524 */, 14 },
890 /* 811 */ { MAD_F(0x0762c06a) /* 0.461609282 */, 14 },
891 /* 812 */ { MAD_F(0x0765dc5b) /* 0.462368352 */, 14 },
892 /* 813 */ { MAD_F(0x0768f8a0) /* 0.463127733 */, 14 },
893 /* 814 */ { MAD_F(0x076c1538) /* 0.463887426 */, 14 },
894 /* 815 */ { MAD_F(0x076f3224) /* 0.464647430 */, 14 },
895
896 /* 816 */ { MAD_F(0x07724f64) /* 0.465407744 */, 14 },
897 /* 817 */ { MAD_F(0x07756cf7) /* 0.466168370 */, 14 },
898 /* 818 */ { MAD_F(0x07788add) /* 0.466929306 */, 14 },
899 /* 819 */ { MAD_F(0x077ba916) /* 0.467690552 */, 14 },
900 /* 820 */ { MAD_F(0x077ec7a3) /* 0.468452108 */, 14 },
901 /* 821 */ { MAD_F(0x0781e683) /* 0.469213973 */, 14 },
902 /* 822 */ { MAD_F(0x078505b5) /* 0.469976148 */, 14 },
903 /* 823 */ { MAD_F(0x0788253b) /* 0.470738632 */, 14 },
904 /* 824 */ { MAD_F(0x078b4514) /* 0.471501425 */, 14 },
905 /* 825 */ { MAD_F(0x078e653f) /* 0.472264527 */, 14 },
906 /* 826 */ { MAD_F(0x079185be) /* 0.473027937 */, 14 },
907 /* 827 */ { MAD_F(0x0794a68f) /* 0.473791655 */, 14 },
908 /* 828 */ { MAD_F(0x0797c7b2) /* 0.474555681 */, 14 },
909 /* 829 */ { MAD_F(0x079ae929) /* 0.475320014 */, 14 },
910 /* 830 */ { MAD_F(0x079e0af1) /* 0.476084655 */, 14 },
911 /* 831 */ { MAD_F(0x07a12d0c) /* 0.476849603 */, 14 },
912
913 /* 832 */ { MAD_F(0x07a44f7a) /* 0.477614858 */, 14 },
914 /* 833 */ { MAD_F(0x07a7723a) /* 0.478380420 */, 14 },
915 /* 834 */ { MAD_F(0x07aa954c) /* 0.479146288 */, 14 },
916 /* 835 */ { MAD_F(0x07adb8b0) /* 0.479912463 */, 14 },
917 /* 836 */ { MAD_F(0x07b0dc67) /* 0.480678943 */, 14 },
918 /* 837 */ { MAD_F(0x07b4006f) /* 0.481445729 */, 14 },
919 /* 838 */ { MAD_F(0x07b724ca) /* 0.482212820 */, 14 },
920 /* 839 */ { MAD_F(0x07ba4976) /* 0.482980216 */, 14 },
921 /* 840 */ { MAD_F(0x07bd6e75) /* 0.483747918 */, 14 },
922 /* 841 */ { MAD_F(0x07c093c5) /* 0.484515924 */, 14 },
923 /* 842 */ { MAD_F(0x07c3b967) /* 0.485284235 */, 14 },
924 /* 843 */ { MAD_F(0x07c6df5a) /* 0.486052849 */, 14 },
925 /* 844 */ { MAD_F(0x07ca059f) /* 0.486821768 */, 14 },
926 /* 845 */ { MAD_F(0x07cd2c36) /* 0.487590991 */, 14 },
927 /* 846 */ { MAD_F(0x07d0531e) /* 0.488360517 */, 14 },
928 /* 847 */ { MAD_F(0x07d37a57) /* 0.489130346 */, 14 },
929
930 /* 848 */ { MAD_F(0x07d6a1e2) /* 0.489900479 */, 14 },
931 /* 849 */ { MAD_F(0x07d9c9be) /* 0.490670914 */, 14 },
932 /* 850 */ { MAD_F(0x07dcf1ec) /* 0.491441651 */, 14 },
933 /* 851 */ { MAD_F(0x07e01a6a) /* 0.492212691 */, 14 },
934 /* 852 */ { MAD_F(0x07e3433a) /* 0.492984033 */, 14 },
935 /* 853 */ { MAD_F(0x07e66c5a) /* 0.493755677 */, 14 },
936 /* 854 */ { MAD_F(0x07e995cc) /* 0.494527623 */, 14 },
937 /* 855 */ { MAD_F(0x07ecbf8e) /* 0.495299870 */, 14 },
938 /* 856 */ { MAD_F(0x07efe9a1) /* 0.496072418 */, 14 },
939 /* 857 */ { MAD_F(0x07f31405) /* 0.496845266 */, 14 },
940 /* 858 */ { MAD_F(0x07f63eba) /* 0.497618416 */, 14 },
941 /* 859 */ { MAD_F(0x07f969c0) /* 0.498391866 */, 14 },
942 /* 860 */ { MAD_F(0x07fc9516) /* 0.499165616 */, 14 },
943 /* 861 */ { MAD_F(0x07ffc0bc) /* 0.499939666 */, 14 },
944 /* 862 */ { MAD_F(0x04017659) /* 0.250357008 */, 15 },
945 /* 863 */ { MAD_F(0x04030c7d) /* 0.250744333 */, 15 },
946
947 /* 864 */ { MAD_F(0x0404a2c9) /* 0.251131807 */, 15 },
948 /* 865 */ { MAD_F(0x0406393d) /* 0.251519431 */, 15 },
949 /* 866 */ { MAD_F(0x0407cfd9) /* 0.251907204 */, 15 },
950 /* 867 */ { MAD_F(0x0409669d) /* 0.252295127 */, 15 },
951 /* 868 */ { MAD_F(0x040afd89) /* 0.252683198 */, 15 },
952 /* 869 */ { MAD_F(0x040c949e) /* 0.253071419 */, 15 },
953 /* 870 */ { MAD_F(0x040e2bda) /* 0.253459789 */, 15 },
954 /* 871 */ { MAD_F(0x040fc33e) /* 0.253848307 */, 15 },
955 /* 872 */ { MAD_F(0x04115aca) /* 0.254236974 */, 15 },
956 /* 873 */ { MAD_F(0x0412f27e) /* 0.254625790 */, 15 },
957 /* 874 */ { MAD_F(0x04148a5a) /* 0.255014755 */, 15 },
958 /* 875 */ { MAD_F(0x0416225d) /* 0.255403867 */, 15 },
959 /* 876 */ { MAD_F(0x0417ba89) /* 0.255793128 */, 15 },
960 /* 877 */ { MAD_F(0x041952dc) /* 0.256182537 */, 15 },
961 /* 878 */ { MAD_F(0x041aeb57) /* 0.256572095 */, 15 },
962 /* 879 */ { MAD_F(0x041c83fa) /* 0.256961800 */, 15 },
963
964 /* 880 */ { MAD_F(0x041e1cc4) /* 0.257351652 */, 15 },
965 /* 881 */ { MAD_F(0x041fb5b6) /* 0.257741653 */, 15 },
966 /* 882 */ { MAD_F(0x04214ed0) /* 0.258131801 */, 15 },
967 /* 883 */ { MAD_F(0x0422e811) /* 0.258522097 */, 15 },
968 /* 884 */ { MAD_F(0x04248179) /* 0.258912540 */, 15 },
969 /* 885 */ { MAD_F(0x04261b0a) /* 0.259303130 */, 15 },
970 /* 886 */ { MAD_F(0x0427b4c2) /* 0.259693868 */, 15 },
971 /* 887 */ { MAD_F(0x04294ea1) /* 0.260084752 */, 15 },
972 /* 888 */ { MAD_F(0x042ae8a7) /* 0.260475783 */, 15 },
973 /* 889 */ { MAD_F(0x042c82d6) /* 0.260866961 */, 15 },
974 /* 890 */ { MAD_F(0x042e1d2b) /* 0.261258286 */, 15 },
975 /* 891 */ { MAD_F(0x042fb7a8) /* 0.261649758 */, 15 },
976 /* 892 */ { MAD_F(0x0431524c) /* 0.262041376 */, 15 },
977 /* 893 */ { MAD_F(0x0432ed17) /* 0.262433140 */, 15 },
978 /* 894 */ { MAD_F(0x0434880a) /* 0.262825051 */, 15 },
979 /* 895 */ { MAD_F(0x04362324) /* 0.263217107 */, 15 },
980
981 /* 896 */ { MAD_F(0x0437be65) /* 0.263609310 */, 15 },
982 /* 897 */ { MAD_F(0x043959cd) /* 0.264001659 */, 15 },
983 /* 898 */ { MAD_F(0x043af55d) /* 0.264394153 */, 15 },
984 /* 899 */ { MAD_F(0x043c9113) /* 0.264786794 */, 15 },
985 /* 900 */ { MAD_F(0x043e2cf1) /* 0.265179580 */, 15 },
986 /* 901 */ { MAD_F(0x043fc8f6) /* 0.265572511 */, 15 },
987 /* 902 */ { MAD_F(0x04416522) /* 0.265965588 */, 15 },
988 /* 903 */ { MAD_F(0x04430174) /* 0.266358810 */, 15 },
989 /* 904 */ { MAD_F(0x04449dee) /* 0.266752177 */, 15 },
990 /* 905 */ { MAD_F(0x04463a8f) /* 0.267145689 */, 15 },
991 /* 906 */ { MAD_F(0x0447d756) /* 0.267539347 */, 15 },
992 /* 907 */ { MAD_F(0x04497445) /* 0.267933149 */, 15 },
993 /* 908 */ { MAD_F(0x044b115a) /* 0.268327096 */, 15 },
994 /* 909 */ { MAD_F(0x044cae96) /* 0.268721187 */, 15 },
995 /* 910 */ { MAD_F(0x044e4bf9) /* 0.269115423 */, 15 },
996 /* 911 */ { MAD_F(0x044fe983) /* 0.269509804 */, 15 },
997
998 /* 912 */ { MAD_F(0x04518733) /* 0.269904329 */, 15 },
999 /* 913 */ { MAD_F(0x0453250a) /* 0.270298998 */, 15 },
1000 /* 914 */ { MAD_F(0x0454c308) /* 0.270693811 */, 15 },
1001 /* 915 */ { MAD_F(0x0456612d) /* 0.271088768 */, 15 },
1002 /* 916 */ { MAD_F(0x0457ff78) /* 0.271483869 */, 15 },
1003 /* 917 */ { MAD_F(0x04599dea) /* 0.271879114 */, 15 },
1004 /* 918 */ { MAD_F(0x045b3c82) /* 0.272274503 */, 15 },
1005 /* 919 */ { MAD_F(0x045cdb41) /* 0.272670035 */, 15 },
1006 /* 920 */ { MAD_F(0x045e7a26) /* 0.273065710 */, 15 },
1007 /* 921 */ { MAD_F(0x04601932) /* 0.273461530 */, 15 },
1008 /* 922 */ { MAD_F(0x0461b864) /* 0.273857492 */, 15 },
1009 /* 923 */ { MAD_F(0x046357bd) /* 0.274253597 */, 15 },
1010 /* 924 */ { MAD_F(0x0464f73c) /* 0.274649846 */, 15 },
1011 /* 925 */ { MAD_F(0x046696e2) /* 0.275046238 */, 15 },
1012 /* 926 */ { MAD_F(0x046836ae) /* 0.275442772 */, 15 },
1013 /* 927 */ { MAD_F(0x0469d6a0) /* 0.275839449 */, 15 },
1014
1015 /* 928 */ { MAD_F(0x046b76b9) /* 0.276236269 */, 15 },
1016 /* 929 */ { MAD_F(0x046d16f7) /* 0.276633232 */, 15 },
1017 /* 930 */ { MAD_F(0x046eb75c) /* 0.277030337 */, 15 },
1018 /* 931 */ { MAD_F(0x047057e8) /* 0.277427584 */, 15 },
1019 /* 932 */ { MAD_F(0x0471f899) /* 0.277824973 */, 15 },
1020 /* 933 */ { MAD_F(0x04739971) /* 0.278222505 */, 15 },
1021 /* 934 */ { MAD_F(0x04753a6f) /* 0.278620179 */, 15 },
1022 /* 935 */ { MAD_F(0x0476db92) /* 0.279017995 */, 15 },
1023 /* 936 */ { MAD_F(0x04787cdc) /* 0.279415952 */, 15 },
1024 /* 937 */ { MAD_F(0x047a1e4c) /* 0.279814051 */, 15 },
1025 /* 938 */ { MAD_F(0x047bbfe2) /* 0.280212292 */, 15 },
1026 /* 939 */ { MAD_F(0x047d619e) /* 0.280610675 */, 15 },
1027 /* 940 */ { MAD_F(0x047f0380) /* 0.281009199 */, 15 },
1028 /* 941 */ { MAD_F(0x0480a588) /* 0.281407864 */, 15 },
1029 /* 942 */ { MAD_F(0x048247b6) /* 0.281806670 */, 15 },
1030 /* 943 */ { MAD_F(0x0483ea0a) /* 0.282205618 */, 15 },
1031
1032 /* 944 */ { MAD_F(0x04858c83) /* 0.282604707 */, 15 },
1033 /* 945 */ { MAD_F(0x04872f22) /* 0.283003936 */, 15 },
1034 /* 946 */ { MAD_F(0x0488d1e8) /* 0.283403307 */, 15 },
1035 /* 947 */ { MAD_F(0x048a74d3) /* 0.283802818 */, 15 },
1036 /* 948 */ { MAD_F(0x048c17e3) /* 0.284202470 */, 15 },
1037 /* 949 */ { MAD_F(0x048dbb1a) /* 0.284602263 */, 15 },
1038 /* 950 */ { MAD_F(0x048f5e76) /* 0.285002195 */, 15 },
1039 /* 951 */ { MAD_F(0x049101f8) /* 0.285402269 */, 15 },
1040 /* 952 */ { MAD_F(0x0492a59f) /* 0.285802482 */, 15 },
1041 /* 953 */ { MAD_F(0x0494496c) /* 0.286202836 */, 15 },
1042 /* 954 */ { MAD_F(0x0495ed5f) /* 0.286603329 */, 15 },
1043 /* 955 */ { MAD_F(0x04979177) /* 0.287003963 */, 15 },
1044 /* 956 */ { MAD_F(0x049935b5) /* 0.287404737 */, 15 },
1045 /* 957 */ { MAD_F(0x049ada19) /* 0.287805650 */, 15 },
1046 /* 958 */ { MAD_F(0x049c7ea1) /* 0.288206703 */, 15 },
1047 /* 959 */ { MAD_F(0x049e2350) /* 0.288607895 */, 15 },
1048
1049 /* 960 */ { MAD_F(0x049fc824) /* 0.289009227 */, 15 },
1050 /* 961 */ { MAD_F(0x04a16d1d) /* 0.289410699 */, 15 },
1051 /* 962 */ { MAD_F(0x04a3123b) /* 0.289812309 */, 15 },
1052 /* 963 */ { MAD_F(0x04a4b77f) /* 0.290214059 */, 15 },
1053 /* 964 */ { MAD_F(0x04a65ce8) /* 0.290615948 */, 15 },
1054 /* 965 */ { MAD_F(0x04a80277) /* 0.291017976 */, 15 },
1055 /* 966 */ { MAD_F(0x04a9a82b) /* 0.291420143 */, 15 },
1056 /* 967 */ { MAD_F(0x04ab4e04) /* 0.291822449 */, 15 },
1057 /* 968 */ { MAD_F(0x04acf402) /* 0.292224893 */, 15 },
1058 /* 969 */ { MAD_F(0x04ae9a26) /* 0.292627476 */, 15 },
1059 /* 970 */ { MAD_F(0x04b0406e) /* 0.293030197 */, 15 },
1060 /* 971 */ { MAD_F(0x04b1e6dc) /* 0.293433057 */, 15 },
1061 /* 972 */ { MAD_F(0x04b38d6f) /* 0.293836055 */, 15 },
1062 /* 973 */ { MAD_F(0x04b53427) /* 0.294239192 */, 15 },
1063 /* 974 */ { MAD_F(0x04b6db05) /* 0.294642466 */, 15 },
1064 /* 975 */ { MAD_F(0x04b88207) /* 0.295045879 */, 15 },
1065
1066 /* 976 */ { MAD_F(0x04ba292e) /* 0.295449429 */, 15 },
1067 /* 977 */ { MAD_F(0x04bbd07a) /* 0.295853118 */, 15 },
1068 /* 978 */ { MAD_F(0x04bd77ec) /* 0.296256944 */, 15 },
1069 /* 979 */ { MAD_F(0x04bf1f82) /* 0.296660907 */, 15 },
1070 /* 980 */ { MAD_F(0x04c0c73d) /* 0.297065009 */, 15 },
1071 /* 981 */ { MAD_F(0x04c26f1d) /* 0.297469248 */, 15 },
1072 /* 982 */ { MAD_F(0x04c41722) /* 0.297873624 */, 15 },
1073 /* 983 */ { MAD_F(0x04c5bf4c) /* 0.298278137 */, 15 },
1074 /* 984 */ { MAD_F(0x04c7679a) /* 0.298682788 */, 15 },
1075 /* 985 */ { MAD_F(0x04c9100d) /* 0.299087576 */, 15 },
1076 /* 986 */ { MAD_F(0x04cab8a6) /* 0.299492500 */, 15 },
1077 /* 987 */ { MAD_F(0x04cc6163) /* 0.299897562 */, 15 },
1078 /* 988 */ { MAD_F(0x04ce0a44) /* 0.300302761 */, 15 },
1079 /* 989 */ { MAD_F(0x04cfb34b) /* 0.300708096 */, 15 },
1080 /* 990 */ { MAD_F(0x04d15c76) /* 0.301113568 */, 15 },
1081 /* 991 */ { MAD_F(0x04d305c5) /* 0.301519176 */, 15 },
1082
1083 /* 992 */ { MAD_F(0x04d4af3a) /* 0.301924921 */, 15 },
1084 /* 993 */ { MAD_F(0x04d658d2) /* 0.302330802 */, 15 },
1085 /* 994 */ { MAD_F(0x04d80290) /* 0.302736820 */, 15 },
1086 /* 995 */ { MAD_F(0x04d9ac72) /* 0.303142973 */, 15 },
1087 /* 996 */ { MAD_F(0x04db5679) /* 0.303549263 */, 15 },
1088 /* 997 */ { MAD_F(0x04dd00a4) /* 0.303955689 */, 15 },
1089 /* 998 */ { MAD_F(0x04deaaf3) /* 0.304362251 */, 15 },
1090 /* 999 */ { MAD_F(0x04e05567) /* 0.304768948 */, 15 },
1091 /* 1000 */ { MAD_F(0x04e20000) /* 0.305175781 */, 15 },
1092 /* 1001 */ { MAD_F(0x04e3aabd) /* 0.305582750 */, 15 },
1093 /* 1002 */ { MAD_F(0x04e5559e) /* 0.305989854 */, 15 },
1094 /* 1003 */ { MAD_F(0x04e700a3) /* 0.306397094 */, 15 },
1095 /* 1004 */ { MAD_F(0x04e8abcd) /* 0.306804470 */, 15 },
1096 /* 1005 */ { MAD_F(0x04ea571c) /* 0.307211980 */, 15 },
1097 /* 1006 */ { MAD_F(0x04ec028e) /* 0.307619626 */, 15 },
1098 /* 1007 */ { MAD_F(0x04edae25) /* 0.308027406 */, 15 },
1099
1100 /* 1008 */ { MAD_F(0x04ef59e0) /* 0.308435322 */, 15 },
1101 /* 1009 */ { MAD_F(0x04f105bf) /* 0.308843373 */, 15 },
1102 /* 1010 */ { MAD_F(0x04f2b1c3) /* 0.309251558 */, 15 },
1103 /* 1011 */ { MAD_F(0x04f45dea) /* 0.309659879 */, 15 },
1104 /* 1012 */ { MAD_F(0x04f60a36) /* 0.310068333 */, 15 },
1105 /* 1013 */ { MAD_F(0x04f7b6a6) /* 0.310476923 */, 15 },
1106 /* 1014 */ { MAD_F(0x04f9633a) /* 0.310885647 */, 15 },
1107 /* 1015 */ { MAD_F(0x04fb0ff2) /* 0.311294505 */, 15 },
1108 /* 1016 */ { MAD_F(0x04fcbcce) /* 0.311703498 */, 15 },
1109 /* 1017 */ { MAD_F(0x04fe69ce) /* 0.312112625 */, 15 },
1110 /* 1018 */ { MAD_F(0x050016f3) /* 0.312521885 */, 15 },
1111 /* 1019 */ { MAD_F(0x0501c43b) /* 0.312931280 */, 15 },
1112 /* 1020 */ { MAD_F(0x050371a7) /* 0.313340809 */, 15 },
1113 /* 1021 */ { MAD_F(0x05051f37) /* 0.313750472 */, 15 },
1114 /* 1022 */ { MAD_F(0x0506cceb) /* 0.314160269 */, 15 },
1115 /* 1023 */ { MAD_F(0x05087ac2) /* 0.314570199 */, 15 },
1116
1117 /* 1024 */ { MAD_F(0x050a28be) /* 0.314980262 */, 15 },
1118 /* 1025 */ { MAD_F(0x050bd6de) /* 0.315390460 */, 15 },
1119 /* 1026 */ { MAD_F(0x050d8521) /* 0.315800790 */, 15 },
1120 /* 1027 */ { MAD_F(0x050f3388) /* 0.316211255 */, 15 },
1121 /* 1028 */ { MAD_F(0x0510e213) /* 0.316621852 */, 15 },
1122 /* 1029 */ { MAD_F(0x051290c2) /* 0.317032582 */, 15 },
1123 /* 1030 */ { MAD_F(0x05143f94) /* 0.317443446 */, 15 },
1124 /* 1031 */ { MAD_F(0x0515ee8a) /* 0.317854442 */, 15 },
1125 /* 1032 */ { MAD_F(0x05179da4) /* 0.318265572 */, 15 },
1126 /* 1033 */ { MAD_F(0x05194ce1) /* 0.318676834 */, 15 },
1127 /* 1034 */ { MAD_F(0x051afc42) /* 0.319088229 */, 15 },
1128 /* 1035 */ { MAD_F(0x051cabc7) /* 0.319499756 */, 15 },
1129 /* 1036 */ { MAD_F(0x051e5b6f) /* 0.319911417 */, 15 },
1130 /* 1037 */ { MAD_F(0x05200b3a) /* 0.320323209 */, 15 },
1131 /* 1038 */ { MAD_F(0x0521bb2a) /* 0.320735134 */, 15 },
1132 /* 1039 */ { MAD_F(0x05236b3d) /* 0.321147192 */, 15 },
1133
1134 /* 1040 */ { MAD_F(0x05251b73) /* 0.321559381 */, 15 },
1135 /* 1041 */ { MAD_F(0x0526cbcd) /* 0.321971703 */, 15 },
1136 /* 1042 */ { MAD_F(0x05287c4a) /* 0.322384156 */, 15 },
1137 /* 1043 */ { MAD_F(0x052a2cea) /* 0.322796742 */, 15 },
1138 /* 1044 */ { MAD_F(0x052bddae) /* 0.323209460 */, 15 },
1139 /* 1045 */ { MAD_F(0x052d8e96) /* 0.323622309 */, 15 },
1140 /* 1046 */ { MAD_F(0x052f3fa1) /* 0.324035290 */, 15 },
1141 /* 1047 */ { MAD_F(0x0530f0cf) /* 0.324448403 */, 15 },
1142 /* 1048 */ { MAD_F(0x0532a220) /* 0.324861647 */, 15 },
1143 /* 1049 */ { MAD_F(0x05345395) /* 0.325275023 */, 15 },
1144 /* 1050 */ { MAD_F(0x0536052d) /* 0.325688530 */, 15 },
1145 /* 1051 */ { MAD_F(0x0537b6e8) /* 0.326102168 */, 15 },
1146 /* 1052 */ { MAD_F(0x053968c6) /* 0.326515938 */, 15 },
1147 /* 1053 */ { MAD_F(0x053b1ac8) /* 0.326929839 */, 15 },
1148 /* 1054 */ { MAD_F(0x053ccced) /* 0.327343870 */, 15 },
1149 /* 1055 */ { MAD_F(0x053e7f35) /* 0.327758033 */, 15 },
1150
1151 /* 1056 */ { MAD_F(0x054031a0) /* 0.328172327 */, 15 },
1152 /* 1057 */ { MAD_F(0x0541e42e) /* 0.328586751 */, 15 },
1153 /* 1058 */ { MAD_F(0x054396df) /* 0.329001306 */, 15 },
1154 /* 1059 */ { MAD_F(0x054549b4) /* 0.329415992 */, 15 },
1155 /* 1060 */ { MAD_F(0x0546fcab) /* 0.329830808 */, 15 },
1156 /* 1061 */ { MAD_F(0x0548afc6) /* 0.330245755 */, 15 },
1157 /* 1062 */ { MAD_F(0x054a6303) /* 0.330660832 */, 15 },
1158 /* 1063 */ { MAD_F(0x054c1663) /* 0.331076039 */, 15 },
1159 /* 1064 */ { MAD_F(0x054dc9e7) /* 0.331491377 */, 15 },
1160 /* 1065 */ { MAD_F(0x054f7d8d) /* 0.331906845 */, 15 },
1161 /* 1066 */ { MAD_F(0x05513156) /* 0.332322443 */, 15 },
1162 /* 1067 */ { MAD_F(0x0552e542) /* 0.332738170 */, 15 },
1163 /* 1068 */ { MAD_F(0x05549951) /* 0.333154028 */, 15 },
1164 /* 1069 */ { MAD_F(0x05564d83) /* 0.333570016 */, 15 },
1165 /* 1070 */ { MAD_F(0x055801d8) /* 0.333986133 */, 15 },
1166 /* 1071 */ { MAD_F(0x0559b64f) /* 0.334402380 */, 15 },
1167
1168 /* 1072 */ { MAD_F(0x055b6ae9) /* 0.334818756 */, 15 },
1169 /* 1073 */ { MAD_F(0x055d1fa6) /* 0.335235262 */, 15 },
1170 /* 1074 */ { MAD_F(0x055ed486) /* 0.335651898 */, 15 },
1171 /* 1075 */ { MAD_F(0x05608988) /* 0.336068662 */, 15 },
1172 /* 1076 */ { MAD_F(0x05623ead) /* 0.336485556 */, 15 },
1173 /* 1077 */ { MAD_F(0x0563f3f5) /* 0.336902579 */, 15 },
1174 /* 1078 */ { MAD_F(0x0565a960) /* 0.337319732 */, 15 },
1175 /* 1079 */ { MAD_F(0x05675eed) /* 0.337737013 */, 15 },
1176 /* 1080 */ { MAD_F(0x0569149c) /* 0.338154423 */, 15 },
1177 /* 1081 */ { MAD_F(0x056aca6f) /* 0.338571962 */, 15 },
1178 /* 1082 */ { MAD_F(0x056c8064) /* 0.338989630 */, 15 },
1179 /* 1083 */ { MAD_F(0x056e367b) /* 0.339407426 */, 15 },
1180 /* 1084 */ { MAD_F(0x056fecb5) /* 0.339825351 */, 15 },
1181 /* 1085 */ { MAD_F(0x0571a311) /* 0.340243405 */, 15 },
1182 /* 1086 */ { MAD_F(0x05735990) /* 0.340661587 */, 15 },
1183 /* 1087 */ { MAD_F(0x05751032) /* 0.341079898 */, 15 },
1184
1185 /* 1088 */ { MAD_F(0x0576c6f5) /* 0.341498336 */, 15 },
1186 /* 1089 */ { MAD_F(0x05787ddc) /* 0.341916903 */, 15 },
1187 /* 1090 */ { MAD_F(0x057a34e4) /* 0.342335598 */, 15 },
1188 /* 1091 */ { MAD_F(0x057bec0f) /* 0.342754421 */, 15 },
1189 /* 1092 */ { MAD_F(0x057da35d) /* 0.343173373 */, 15 },
1190 /* 1093 */ { MAD_F(0x057f5acc) /* 0.343592452 */, 15 },
1191 /* 1094 */ { MAD_F(0x0581125e) /* 0.344011659 */, 15 },
1192 /* 1095 */ { MAD_F(0x0582ca12) /* 0.344430993 */, 15 },
1193 /* 1096 */ { MAD_F(0x058481e9) /* 0.344850455 */, 15 },
1194 /* 1097 */ { MAD_F(0x058639e2) /* 0.345270045 */, 15 },
1195 /* 1098 */ { MAD_F(0x0587f1fd) /* 0.345689763 */, 15 },
1196 /* 1099 */ { MAD_F(0x0589aa3a) /* 0.346109608 */, 15 },
1197 /* 1100 */ { MAD_F(0x058b629a) /* 0.346529580 */, 15 },
1198 /* 1101 */ { MAD_F(0x058d1b1b) /* 0.346949679 */, 15 },
1199 /* 1102 */ { MAD_F(0x058ed3bf) /* 0.347369906 */, 15 },
1200 /* 1103 */ { MAD_F(0x05908c85) /* 0.347790260 */, 15 },
1201
1202 /* 1104 */ { MAD_F(0x0592456d) /* 0.348210741 */, 15 },
1203 /* 1105 */ { MAD_F(0x0593fe77) /* 0.348631348 */, 15 },
1204 /* 1106 */ { MAD_F(0x0595b7a3) /* 0.349052083 */, 15 },
1205 /* 1107 */ { MAD_F(0x059770f1) /* 0.349472945 */, 15 },
1206 /* 1108 */ { MAD_F(0x05992a61) /* 0.349893933 */, 15 },
1207 /* 1109 */ { MAD_F(0x059ae3f3) /* 0.350315048 */, 15 },
1208 /* 1110 */ { MAD_F(0x059c9da8) /* 0.350736290 */, 15 },
1209 /* 1111 */ { MAD_F(0x059e577e) /* 0.351157658 */, 15 },
1210 /* 1112 */ { MAD_F(0x05a01176) /* 0.351579152 */, 15 },
1211 /* 1113 */ { MAD_F(0x05a1cb90) /* 0.352000773 */, 15 },
1212 /* 1114 */ { MAD_F(0x05a385cc) /* 0.352422520 */, 15 },
1213 /* 1115 */ { MAD_F(0x05a5402a) /* 0.352844394 */, 15 },
1214 /* 1116 */ { MAD_F(0x05a6faa9) /* 0.353266393 */, 15 },
1215 /* 1117 */ { MAD_F(0x05a8b54b) /* 0.353688519 */, 15 },
1216 /* 1118 */ { MAD_F(0x05aa700e) /* 0.354110771 */, 15 },
1217 /* 1119 */ { MAD_F(0x05ac2af3) /* 0.354533148 */, 15 },
1218
1219 /* 1120 */ { MAD_F(0x05ade5fa) /* 0.354955651 */, 15 },
1220 /* 1121 */ { MAD_F(0x05afa123) /* 0.355378281 */, 15 },
1221 /* 1122 */ { MAD_F(0x05b15c6d) /* 0.355801035 */, 15 },
1222 /* 1123 */ { MAD_F(0x05b317d9) /* 0.356223916 */, 15 },
1223 /* 1124 */ { MAD_F(0x05b4d367) /* 0.356646922 */, 15 },
1224 /* 1125 */ { MAD_F(0x05b68f16) /* 0.357070053 */, 15 },
1225 /* 1126 */ { MAD_F(0x05b84ae7) /* 0.357493310 */, 15 },
1226 /* 1127 */ { MAD_F(0x05ba06da) /* 0.357916692 */, 15 },
1227 /* 1128 */ { MAD_F(0x05bbc2ef) /* 0.358340200 */, 15 },
1228 /* 1129 */ { MAD_F(0x05bd7f25) /* 0.358763832 */, 15 },
1229 /* 1130 */ { MAD_F(0x05bf3b7c) /* 0.359187590 */, 15 },
1230 /* 1131 */ { MAD_F(0x05c0f7f5) /* 0.359611472 */, 15 },
1231 /* 1132 */ { MAD_F(0x05c2b490) /* 0.360035480 */, 15 },
1232 /* 1133 */ { MAD_F(0x05c4714c) /* 0.360459613 */, 15 },
1233 /* 1134 */ { MAD_F(0x05c62e2a) /* 0.360883870 */, 15 },
1234 /* 1135 */ { MAD_F(0x05c7eb29) /* 0.361308252 */, 15 },
1235
1236 /* 1136 */ { MAD_F(0x05c9a84a) /* 0.361732758 */, 15 },
1237 /* 1137 */ { MAD_F(0x05cb658c) /* 0.362157390 */, 15 },
1238 /* 1138 */ { MAD_F(0x05cd22ef) /* 0.362582145 */, 15 },
1239 /* 1139 */ { MAD_F(0x05cee074) /* 0.363007026 */, 15 },
1240 /* 1140 */ { MAD_F(0x05d09e1b) /* 0.363432030 */, 15 },
1241 /* 1141 */ { MAD_F(0x05d25be2) /* 0.363857159 */, 15 },
1242 /* 1142 */ { MAD_F(0x05d419cb) /* 0.364282412 */, 15 },
1243 /* 1143 */ { MAD_F(0x05d5d7d5) /* 0.364707789 */, 15 },
1244 /* 1144 */ { MAD_F(0x05d79601) /* 0.365133291 */, 15 },
1245 /* 1145 */ { MAD_F(0x05d9544e) /* 0.365558916 */, 15 },
1246 /* 1146 */ { MAD_F(0x05db12bc) /* 0.365984665 */, 15 },
1247 /* 1147 */ { MAD_F(0x05dcd14c) /* 0.366410538 */, 15 },
1248 /* 1148 */ { MAD_F(0x05de8ffc) /* 0.366836535 */, 15 },
1249 /* 1149 */ { MAD_F(0x05e04ece) /* 0.367262655 */, 15 },
1250 /* 1150 */ { MAD_F(0x05e20dc1) /* 0.367688900 */, 15 },
1251 /* 1151 */ { MAD_F(0x05e3ccd5) /* 0.368115267 */, 15 },
1252
1253 /* 1152 */ { MAD_F(0x05e58c0b) /* 0.368541759 */, 15 },
1254 /* 1153 */ { MAD_F(0x05e74b61) /* 0.368968373 */, 15 },
1255 /* 1154 */ { MAD_F(0x05e90ad9) /* 0.369395111 */, 15 },
1256 /* 1155 */ { MAD_F(0x05eaca72) /* 0.369821973 */, 15 },
1257 /* 1156 */ { MAD_F(0x05ec8a2b) /* 0.370248957 */, 15 },
1258 /* 1157 */ { MAD_F(0x05ee4a06) /* 0.370676065 */, 15 },
1259 /* 1158 */ { MAD_F(0x05f00a02) /* 0.371103295 */, 15 },
1260 /* 1159 */ { MAD_F(0x05f1ca1f) /* 0.371530649 */, 15 },
1261 /* 1160 */ { MAD_F(0x05f38a5d) /* 0.371958126 */, 15 },
1262 /* 1161 */ { MAD_F(0x05f54abc) /* 0.372385725 */, 15 },
1263 /* 1162 */ { MAD_F(0x05f70b3c) /* 0.372813448 */, 15 },
1264 /* 1163 */ { MAD_F(0x05f8cbdc) /* 0.373241292 */, 15 },
1265 /* 1164 */ { MAD_F(0x05fa8c9e) /* 0.373669260 */, 15 },
1266 /* 1165 */ { MAD_F(0x05fc4d81) /* 0.374097350 */, 15 },
1267 /* 1166 */ { MAD_F(0x05fe0e84) /* 0.374525563 */, 15 },
1268 /* 1167 */ { MAD_F(0x05ffcfa8) /* 0.374953898 */, 15 },
1269
1270 /* 1168 */ { MAD_F(0x060190ee) /* 0.375382356 */, 15 },
1271 /* 1169 */ { MAD_F(0x06035254) /* 0.375810936 */, 15 },
1272 /* 1170 */ { MAD_F(0x060513da) /* 0.376239638 */, 15 },
1273 /* 1171 */ { MAD_F(0x0606d582) /* 0.376668462 */, 15 },
1274 /* 1172 */ { MAD_F(0x0608974a) /* 0.377097408 */, 15 },
1275 /* 1173 */ { MAD_F(0x060a5934) /* 0.377526476 */, 15 },
1276 /* 1174 */ { MAD_F(0x060c1b3d) /* 0.377955667 */, 15 },
1277 /* 1175 */ { MAD_F(0x060ddd68) /* 0.378384979 */, 15 },
1278 /* 1176 */ { MAD_F(0x060f9fb3) /* 0.378814413 */, 15 },
1279 /* 1177 */ { MAD_F(0x0611621f) /* 0.379243968 */, 15 },
1280 /* 1178 */ { MAD_F(0x061324ac) /* 0.379673646 */, 15 },
1281 /* 1179 */ { MAD_F(0x0614e759) /* 0.380103444 */, 15 },
1282 /* 1180 */ { MAD_F(0x0616aa27) /* 0.380533365 */, 15 },
1283 /* 1181 */ { MAD_F(0x06186d16) /* 0.380963407 */, 15 },
1284 /* 1182 */ { MAD_F(0x061a3025) /* 0.381393570 */, 15 },
1285 /* 1183 */ { MAD_F(0x061bf354) /* 0.381823855 */, 15 },
1286
1287 /* 1184 */ { MAD_F(0x061db6a5) /* 0.382254261 */, 15 },
1288 /* 1185 */ { MAD_F(0x061f7a15) /* 0.382684788 */, 15 },
1289 /* 1186 */ { MAD_F(0x06213da7) /* 0.383115436 */, 15 },
1290 /* 1187 */ { MAD_F(0x06230158) /* 0.383546205 */, 15 },
1291 /* 1188 */ { MAD_F(0x0624c52a) /* 0.383977096 */, 15 },
1292 /* 1189 */ { MAD_F(0x0626891d) /* 0.384408107 */, 15 },
1293 /* 1190 */ { MAD_F(0x06284d30) /* 0.384839239 */, 15 },
1294 /* 1191 */ { MAD_F(0x062a1164) /* 0.385270492 */, 15 },
1295 /* 1192 */ { MAD_F(0x062bd5b8) /* 0.385701865 */, 15 },
1296 /* 1193 */ { MAD_F(0x062d9a2c) /* 0.386133359 */, 15 },
1297 /* 1194 */ { MAD_F(0x062f5ec1) /* 0.386564974 */, 15 },
1298 /* 1195 */ { MAD_F(0x06312376) /* 0.386996709 */, 15 },
1299 /* 1196 */ { MAD_F(0x0632e84b) /* 0.387428565 */, 15 },
1300 /* 1197 */ { MAD_F(0x0634ad41) /* 0.387860541 */, 15 },
1301 /* 1198 */ { MAD_F(0x06367257) /* 0.388292637 */, 15 },
1302 /* 1199 */ { MAD_F(0x0638378d) /* 0.388724854 */, 15 },
1303
1304 /* 1200 */ { MAD_F(0x0639fce4) /* 0.389157191 */, 15 },
1305 /* 1201 */ { MAD_F(0x063bc25b) /* 0.389589648 */, 15 },
1306 /* 1202 */ { MAD_F(0x063d87f2) /* 0.390022225 */, 15 },
1307 /* 1203 */ { MAD_F(0x063f4da9) /* 0.390454922 */, 15 },
1308 /* 1204 */ { MAD_F(0x06411380) /* 0.390887739 */, 15 },
1309 /* 1205 */ { MAD_F(0x0642d978) /* 0.391320675 */, 15 },
1310 /* 1206 */ { MAD_F(0x06449f8f) /* 0.391753732 */, 15 },
1311 /* 1207 */ { MAD_F(0x064665c7) /* 0.392186908 */, 15 },
1312 /* 1208 */ { MAD_F(0x06482c1f) /* 0.392620204 */, 15 },
1313 /* 1209 */ { MAD_F(0x0649f297) /* 0.393053619 */, 15 },
1314 /* 1210 */ { MAD_F(0x064bb92f) /* 0.393487154 */, 15 },
1315 /* 1211 */ { MAD_F(0x064d7fe8) /* 0.393920808 */, 15 },
1316 /* 1212 */ { MAD_F(0x064f46c0) /* 0.394354582 */, 15 },
1317 /* 1213 */ { MAD_F(0x06510db8) /* 0.394788475 */, 15 },
1318 /* 1214 */ { MAD_F(0x0652d4d0) /* 0.395222488 */, 15 },
1319 /* 1215 */ { MAD_F(0x06549c09) /* 0.395656619 */, 15 },
1320
1321 /* 1216 */ { MAD_F(0x06566361) /* 0.396090870 */, 15 },
1322 /* 1217 */ { MAD_F(0x06582ad9) /* 0.396525239 */, 15 },
1323 /* 1218 */ { MAD_F(0x0659f271) /* 0.396959728 */, 15 },
1324 /* 1219 */ { MAD_F(0x065bba29) /* 0.397394336 */, 15 },
1325 /* 1220 */ { MAD_F(0x065d8201) /* 0.397829062 */, 15 },
1326 /* 1221 */ { MAD_F(0x065f49f9) /* 0.398263907 */, 15 },
1327 /* 1222 */ { MAD_F(0x06611211) /* 0.398698871 */, 15 },
1328 /* 1223 */ { MAD_F(0x0662da49) /* 0.399133954 */, 15 },
1329 /* 1224 */ { MAD_F(0x0664a2a0) /* 0.399569155 */, 15 },
1330 /* 1225 */ { MAD_F(0x06666b17) /* 0.400004475 */, 15 },
1331 /* 1226 */ { MAD_F(0x066833ae) /* 0.400439913 */, 15 },
1332 /* 1227 */ { MAD_F(0x0669fc65) /* 0.400875470 */, 15 },
1333 /* 1228 */ { MAD_F(0x066bc53c) /* 0.401311145 */, 15 },
1334 /* 1229 */ { MAD_F(0x066d8e32) /* 0.401746938 */, 15 },
1335 /* 1230 */ { MAD_F(0x066f5748) /* 0.402182850 */, 15 },
1336 /* 1231 */ { MAD_F(0x0671207e) /* 0.402618879 */, 15 },
1337
1338 /* 1232 */ { MAD_F(0x0672e9d4) /* 0.403055027 */, 15 },
1339 /* 1233 */ { MAD_F(0x0674b349) /* 0.403491293 */, 15 },
1340 /* 1234 */ { MAD_F(0x06767cde) /* 0.403927676 */, 15 },
1341 /* 1235 */ { MAD_F(0x06784692) /* 0.404364178 */, 15 },
1342 /* 1236 */ { MAD_F(0x067a1066) /* 0.404800797 */, 15 },
1343 /* 1237 */ { MAD_F(0x067bda5a) /* 0.405237535 */, 15 },
1344 /* 1238 */ { MAD_F(0x067da46d) /* 0.405674390 */, 15 },
1345 /* 1239 */ { MAD_F(0x067f6ea0) /* 0.406111362 */, 15 },
1346 /* 1240 */ { MAD_F(0x068138f3) /* 0.406548452 */, 15 },
1347 /* 1241 */ { MAD_F(0x06830365) /* 0.406985660 */, 15 },
1348 /* 1242 */ { MAD_F(0x0684cdf6) /* 0.407422985 */, 15 },
1349 /* 1243 */ { MAD_F(0x068698a8) /* 0.407860427 */, 15 },
1350 /* 1244 */ { MAD_F(0x06886378) /* 0.408297987 */, 15 },
1351 /* 1245 */ { MAD_F(0x068a2e68) /* 0.408735664 */, 15 },
1352 /* 1246 */ { MAD_F(0x068bf978) /* 0.409173458 */, 15 },
1353 /* 1247 */ { MAD_F(0x068dc4a7) /* 0.409611370 */, 15 },
1354
1355 /* 1248 */ { MAD_F(0x068f8ff5) /* 0.410049398 */, 15 },
1356 /* 1249 */ { MAD_F(0x06915b63) /* 0.410487544 */, 15 },
1357 /* 1250 */ { MAD_F(0x069326f0) /* 0.410925806 */, 15 },
1358 /* 1251 */ { MAD_F(0x0694f29c) /* 0.411364185 */, 15 },
1359 /* 1252 */ { MAD_F(0x0696be68) /* 0.411802681 */, 15 },
1360 /* 1253 */ { MAD_F(0x06988a54) /* 0.412241294 */, 15 },
1361 /* 1254 */ { MAD_F(0x069a565e) /* 0.412680024 */, 15 },
1362 /* 1255 */ { MAD_F(0x069c2288) /* 0.413118870 */, 15 },
1363 /* 1256 */ { MAD_F(0x069deed1) /* 0.413557833 */, 15 },
1364 /* 1257 */ { MAD_F(0x069fbb3a) /* 0.413996912 */, 15 },
1365 /* 1258 */ { MAD_F(0x06a187c1) /* 0.414436108 */, 15 },
1366 /* 1259 */ { MAD_F(0x06a35468) /* 0.414875420 */, 15 },
1367 /* 1260 */ { MAD_F(0x06a5212f) /* 0.415314849 */, 15 },
1368 /* 1261 */ { MAD_F(0x06a6ee14) /* 0.415754393 */, 15 },
1369 /* 1262 */ { MAD_F(0x06a8bb18) /* 0.416194054 */, 15 },
1370 /* 1263 */ { MAD_F(0x06aa883c) /* 0.416633831 */, 15 },
1371
1372 /* 1264 */ { MAD_F(0x06ac557f) /* 0.417073724 */, 15 },
1373 /* 1265 */ { MAD_F(0x06ae22e1) /* 0.417513734 */, 15 },
1374 /* 1266 */ { MAD_F(0x06aff062) /* 0.417953859 */, 15 },
1375 /* 1267 */ { MAD_F(0x06b1be03) /* 0.418394100 */, 15 },
1376 /* 1268 */ { MAD_F(0x06b38bc2) /* 0.418834457 */, 15 },
1377 /* 1269 */ { MAD_F(0x06b559a1) /* 0.419274929 */, 15 },
1378 /* 1270 */ { MAD_F(0x06b7279e) /* 0.419715518 */, 15 },
1379 /* 1271 */ { MAD_F(0x06b8f5bb) /* 0.420156222 */, 15 },
1380 /* 1272 */ { MAD_F(0x06bac3f6) /* 0.420597041 */, 15 },
1381 /* 1273 */ { MAD_F(0x06bc9251) /* 0.421037977 */, 15 },
1382 /* 1274 */ { MAD_F(0x06be60cb) /* 0.421479027 */, 15 },
1383 /* 1275 */ { MAD_F(0x06c02f63) /* 0.421920193 */, 15 },
1384 /* 1276 */ { MAD_F(0x06c1fe1b) /* 0.422361475 */, 15 },
1385 /* 1277 */ { MAD_F(0x06c3ccf1) /* 0.422802871 */, 15 },
1386 /* 1278 */ { MAD_F(0x06c59be7) /* 0.423244383 */, 15 },
1387 /* 1279 */ { MAD_F(0x06c76afb) /* 0.423686010 */, 15 },
1388
1389 /* 1280 */ { MAD_F(0x06c93a2e) /* 0.424127753 */, 15 },
1390 /* 1281 */ { MAD_F(0x06cb0981) /* 0.424569610 */, 15 },
1391 /* 1282 */ { MAD_F(0x06ccd8f2) /* 0.425011582 */, 15 },
1392 /* 1283 */ { MAD_F(0x06cea881) /* 0.425453669 */, 15 },
1393 /* 1284 */ { MAD_F(0x06d07830) /* 0.425895871 */, 15 },
1394 /* 1285 */ { MAD_F(0x06d247fe) /* 0.426338188 */, 15 },
1395 /* 1286 */ { MAD_F(0x06d417ea) /* 0.426780620 */, 15 },
1396 /* 1287 */ { MAD_F(0x06d5e7f5) /* 0.427223166 */, 15 },
1397 /* 1288 */ { MAD_F(0x06d7b81f) /* 0.427665827 */, 15 },
1398 /* 1289 */ { MAD_F(0x06d98868) /* 0.428108603 */, 15 },
1399 /* 1290 */ { MAD_F(0x06db58cf) /* 0.428551493 */, 15 },
1400 /* 1291 */ { MAD_F(0x06dd2955) /* 0.428994497 */, 15 },
1401 /* 1292 */ { MAD_F(0x06def9fa) /* 0.429437616 */, 15 },
1402 /* 1293 */ { MAD_F(0x06e0cabe) /* 0.429880849 */, 15 },
1403 /* 1294 */ { MAD_F(0x06e29ba0) /* 0.430324197 */, 15 },
1404 /* 1295 */ { MAD_F(0x06e46ca1) /* 0.430767659 */, 15 },
1405
1406 /* 1296 */ { MAD_F(0x06e63dc0) /* 0.431211234 */, 15 },
1407 /* 1297 */ { MAD_F(0x06e80efe) /* 0.431654924 */, 15 },
1408 /* 1298 */ { MAD_F(0x06e9e05b) /* 0.432098728 */, 15 },
1409 /* 1299 */ { MAD_F(0x06ebb1d6) /* 0.432542647 */, 15 },
1410 /* 1300 */ { MAD_F(0x06ed8370) /* 0.432986678 */, 15 },
1411 /* 1301 */ { MAD_F(0x06ef5529) /* 0.433430824 */, 15 },
1412 /* 1302 */ { MAD_F(0x06f12700) /* 0.433875084 */, 15 },
1413 /* 1303 */ { MAD_F(0x06f2f8f5) /* 0.434319457 */, 15 },
1414 /* 1304 */ { MAD_F(0x06f4cb09) /* 0.434763944 */, 15 },
1415 /* 1305 */ { MAD_F(0x06f69d3c) /* 0.435208545 */, 15 },
1416 /* 1306 */ { MAD_F(0x06f86f8d) /* 0.435653259 */, 15 },
1417 /* 1307 */ { MAD_F(0x06fa41fd) /* 0.436098087 */, 15 },
1418 /* 1308 */ { MAD_F(0x06fc148b) /* 0.436543029 */, 15 },
1419 /* 1309 */ { MAD_F(0x06fde737) /* 0.436988083 */, 15 },
1420 /* 1310 */ { MAD_F(0x06ffba02) /* 0.437433251 */, 15 },
1421 /* 1311 */ { MAD_F(0x07018ceb) /* 0.437878533 */, 15 },
1422
1423 /* 1312 */ { MAD_F(0x07035ff3) /* 0.438323927 */, 15 },
1424 /* 1313 */ { MAD_F(0x07053319) /* 0.438769435 */, 15 },
1425 /* 1314 */ { MAD_F(0x0707065d) /* 0.439215056 */, 15 },
1426 /* 1315 */ { MAD_F(0x0708d9c0) /* 0.439660790 */, 15 },
1427 /* 1316 */ { MAD_F(0x070aad41) /* 0.440106636 */, 15 },
1428 /* 1317 */ { MAD_F(0x070c80e1) /* 0.440552596 */, 15 },
1429 /* 1318 */ { MAD_F(0x070e549f) /* 0.440998669 */, 15 },
1430 /* 1319 */ { MAD_F(0x0710287b) /* 0.441444855 */, 15 },
1431 /* 1320 */ { MAD_F(0x0711fc75) /* 0.441891153 */, 15 },
1432 /* 1321 */ { MAD_F(0x0713d08d) /* 0.442337564 */, 15 },
1433 /* 1322 */ { MAD_F(0x0715a4c4) /* 0.442784088 */, 15 },
1434 /* 1323 */ { MAD_F(0x07177919) /* 0.443230724 */, 15 },
1435 /* 1324 */ { MAD_F(0x07194d8c) /* 0.443677473 */, 15 },
1436 /* 1325 */ { MAD_F(0x071b221e) /* 0.444124334 */, 15 },
1437 /* 1326 */ { MAD_F(0x071cf6ce) /* 0.444571308 */, 15 },
1438 /* 1327 */ { MAD_F(0x071ecb9b) /* 0.445018394 */, 15 },
1439
1440 /* 1328 */ { MAD_F(0x0720a087) /* 0.445465593 */, 15 },
1441 /* 1329 */ { MAD_F(0x07227591) /* 0.445912903 */, 15 },
1442 /* 1330 */ { MAD_F(0x07244ab9) /* 0.446360326 */, 15 },
1443 /* 1331 */ { MAD_F(0x07262000) /* 0.446807861 */, 15 },
1444 /* 1332 */ { MAD_F(0x0727f564) /* 0.447255509 */, 15 },
1445 /* 1333 */ { MAD_F(0x0729cae7) /* 0.447703268 */, 15 },
1446 /* 1334 */ { MAD_F(0x072ba087) /* 0.448151139 */, 15 },
1447 /* 1335 */ { MAD_F(0x072d7646) /* 0.448599122 */, 15 },
1448 /* 1336 */ { MAD_F(0x072f4c22) /* 0.449047217 */, 15 },
1449 /* 1337 */ { MAD_F(0x0731221d) /* 0.449495424 */, 15 },
1450 /* 1338 */ { MAD_F(0x0732f835) /* 0.449943742 */, 15 },
1451 /* 1339 */ { MAD_F(0x0734ce6c) /* 0.450392173 */, 15 },
1452 /* 1340 */ { MAD_F(0x0736a4c1) /* 0.450840715 */, 15 },
1453 /* 1341 */ { MAD_F(0x07387b33) /* 0.451289368 */, 15 },
1454 /* 1342 */ { MAD_F(0x073a51c4) /* 0.451738133 */, 15 },
1455 /* 1343 */ { MAD_F(0x073c2872) /* 0.452187010 */, 15 },
1456
1457 /* 1344 */ { MAD_F(0x073dff3e) /* 0.452635998 */, 15 },
1458 /* 1345 */ { MAD_F(0x073fd628) /* 0.453085097 */, 15 },
1459 /* 1346 */ { MAD_F(0x0741ad30) /* 0.453534308 */, 15 },
1460 /* 1347 */ { MAD_F(0x07438456) /* 0.453983630 */, 15 },
1461 /* 1348 */ { MAD_F(0x07455b9a) /* 0.454433063 */, 15 },
1462 /* 1349 */ { MAD_F(0x074732fc) /* 0.454882607 */, 15 },
1463 /* 1350 */ { MAD_F(0x07490a7b) /* 0.455332262 */, 15 },
1464 /* 1351 */ { MAD_F(0x074ae218) /* 0.455782029 */, 15 },
1465 /* 1352 */ { MAD_F(0x074cb9d3) /* 0.456231906 */, 15 },
1466 /* 1353 */ { MAD_F(0x074e91ac) /* 0.456681894 */, 15 },
1467 /* 1354 */ { MAD_F(0x075069a3) /* 0.457131993 */, 15 },
1468 /* 1355 */ { MAD_F(0x075241b7) /* 0.457582203 */, 15 },
1469 /* 1356 */ { MAD_F(0x075419e9) /* 0.458032524 */, 15 },
1470 /* 1357 */ { MAD_F(0x0755f239) /* 0.458482956 */, 15 },
1471 /* 1358 */ { MAD_F(0x0757caa7) /* 0.458933498 */, 15 },
1472 /* 1359 */ { MAD_F(0x0759a332) /* 0.459384151 */, 15 },
1473
1474 /* 1360 */ { MAD_F(0x075b7bdb) /* 0.459834914 */, 15 },
1475 /* 1361 */ { MAD_F(0x075d54a1) /* 0.460285788 */, 15 },
1476 /* 1362 */ { MAD_F(0x075f2d85) /* 0.460736772 */, 15 },
1477 /* 1363 */ { MAD_F(0x07610687) /* 0.461187867 */, 15 },
1478 /* 1364 */ { MAD_F(0x0762dfa6) /* 0.461639071 */, 15 },
1479 /* 1365 */ { MAD_F(0x0764b8e3) /* 0.462090387 */, 15 },
1480 /* 1366 */ { MAD_F(0x0766923e) /* 0.462541812 */, 15 },
1481 /* 1367 */ { MAD_F(0x07686bb6) /* 0.462993348 */, 15 },
1482 /* 1368 */ { MAD_F(0x076a454c) /* 0.463444993 */, 15 },
1483 /* 1369 */ { MAD_F(0x076c1eff) /* 0.463896749 */, 15 },
1484 /* 1370 */ { MAD_F(0x076df8d0) /* 0.464348615 */, 15 },
1485 /* 1371 */ { MAD_F(0x076fd2be) /* 0.464800591 */, 15 },
1486 /* 1372 */ { MAD_F(0x0771acca) /* 0.465252676 */, 15 },
1487 /* 1373 */ { MAD_F(0x077386f3) /* 0.465704872 */, 15 },
1488 /* 1374 */ { MAD_F(0x0775613a) /* 0.466157177 */, 15 },
1489 /* 1375 */ { MAD_F(0x07773b9e) /* 0.466609592 */, 15 },
1490
1491 /* 1376 */ { MAD_F(0x07791620) /* 0.467062117 */, 15 },
1492 /* 1377 */ { MAD_F(0x077af0bf) /* 0.467514751 */, 15 },
1493 /* 1378 */ { MAD_F(0x077ccb7c) /* 0.467967495 */, 15 },
1494 /* 1379 */ { MAD_F(0x077ea656) /* 0.468420349 */, 15 },
1495 /* 1380 */ { MAD_F(0x0780814d) /* 0.468873312 */, 15 },
1496 /* 1381 */ { MAD_F(0x07825c62) /* 0.469326384 */, 15 },
1497 /* 1382 */ { MAD_F(0x07843794) /* 0.469779566 */, 15 },
1498 /* 1383 */ { MAD_F(0x078612e3) /* 0.470232857 */, 15 },
1499 /* 1384 */ { MAD_F(0x0787ee50) /* 0.470686258 */, 15 },
1500 /* 1385 */ { MAD_F(0x0789c9da) /* 0.471139767 */, 15 },
1501 /* 1386 */ { MAD_F(0x078ba581) /* 0.471593386 */, 15 },
1502 /* 1387 */ { MAD_F(0x078d8146) /* 0.472047114 */, 15 },
1503 /* 1388 */ { MAD_F(0x078f5d28) /* 0.472500951 */, 15 },
1504 /* 1389 */ { MAD_F(0x07913927) /* 0.472954896 */, 15 },
1505 /* 1390 */ { MAD_F(0x07931543) /* 0.473408951 */, 15 },
1506 /* 1391 */ { MAD_F(0x0794f17d) /* 0.473863115 */, 15 },
1507
1508 /* 1392 */ { MAD_F(0x0796cdd4) /* 0.474317388 */, 15 },
1509 /* 1393 */ { MAD_F(0x0798aa48) /* 0.474771769 */, 15 },
1510 /* 1394 */ { MAD_F(0x079a86d9) /* 0.475226259 */, 15 },
1511 /* 1395 */ { MAD_F(0x079c6388) /* 0.475680858 */, 15 },
1512 /* 1396 */ { MAD_F(0x079e4053) /* 0.476135565 */, 15 },
1513 /* 1397 */ { MAD_F(0x07a01d3c) /* 0.476590381 */, 15 },
1514 /* 1398 */ { MAD_F(0x07a1fa42) /* 0.477045306 */, 15 },
1515 /* 1399 */ { MAD_F(0x07a3d765) /* 0.477500339 */, 15 },
1516 /* 1400 */ { MAD_F(0x07a5b4a5) /* 0.477955481 */, 15 },
1517 /* 1401 */ { MAD_F(0x07a79202) /* 0.478410731 */, 15 },
1518 /* 1402 */ { MAD_F(0x07a96f7d) /* 0.478866089 */, 15 },
1519 /* 1403 */ { MAD_F(0x07ab4d14) /* 0.479321555 */, 15 },
1520 /* 1404 */ { MAD_F(0x07ad2ac8) /* 0.479777130 */, 15 },
1521 /* 1405 */ { MAD_F(0x07af089a) /* 0.480232813 */, 15 },
1522 /* 1406 */ { MAD_F(0x07b0e688) /* 0.480688604 */, 15 },
1523 /* 1407 */ { MAD_F(0x07b2c494) /* 0.481144503 */, 15 },
1524
1525 /* 1408 */ { MAD_F(0x07b4a2bc) /* 0.481600510 */, 15 },
1526 /* 1409 */ { MAD_F(0x07b68102) /* 0.482056625 */, 15 },
1527 /* 1410 */ { MAD_F(0x07b85f64) /* 0.482512848 */, 15 },
1528 /* 1411 */ { MAD_F(0x07ba3de4) /* 0.482969179 */, 15 },
1529 /* 1412 */ { MAD_F(0x07bc1c80) /* 0.483425618 */, 15 },
1530 /* 1413 */ { MAD_F(0x07bdfb39) /* 0.483882164 */, 15 },
1531 /* 1414 */ { MAD_F(0x07bfda0f) /* 0.484338818 */, 15 },
1532 /* 1415 */ { MAD_F(0x07c1b902) /* 0.484795580 */, 15 },
1533 /* 1416 */ { MAD_F(0x07c39812) /* 0.485252449 */, 15 },
1534 /* 1417 */ { MAD_F(0x07c5773f) /* 0.485709426 */, 15 },
1535 /* 1418 */ { MAD_F(0x07c75689) /* 0.486166511 */, 15 },
1536 /* 1419 */ { MAD_F(0x07c935ef) /* 0.486623703 */, 15 },
1537 /* 1420 */ { MAD_F(0x07cb1573) /* 0.487081002 */, 15 },
1538 /* 1421 */ { MAD_F(0x07ccf513) /* 0.487538409 */, 15 },
1539 /* 1422 */ { MAD_F(0x07ced4d0) /* 0.487995923 */, 15 },
1540 /* 1423 */ { MAD_F(0x07d0b4aa) /* 0.488453544 */, 15 },
1541
1542 /* 1424 */ { MAD_F(0x07d294a0) /* 0.488911273 */, 15 },
1543 /* 1425 */ { MAD_F(0x07d474b3) /* 0.489369108 */, 15 },
1544 /* 1426 */ { MAD_F(0x07d654e4) /* 0.489827051 */, 15 },
1545 /* 1427 */ { MAD_F(0x07d83530) /* 0.490285101 */, 15 },
1546 /* 1428 */ { MAD_F(0x07da159a) /* 0.490743258 */, 15 },
1547 /* 1429 */ { MAD_F(0x07dbf620) /* 0.491201522 */, 15 },
1548 /* 1430 */ { MAD_F(0x07ddd6c3) /* 0.491659892 */, 15 },
1549 /* 1431 */ { MAD_F(0x07dfb783) /* 0.492118370 */, 15 },
1550 /* 1432 */ { MAD_F(0x07e1985f) /* 0.492576954 */, 15 },
1551 /* 1433 */ { MAD_F(0x07e37958) /* 0.493035645 */, 15 },
1552 /* 1434 */ { MAD_F(0x07e55a6e) /* 0.493494443 */, 15 },
1553 /* 1435 */ { MAD_F(0x07e73ba0) /* 0.493953348 */, 15 },
1554 /* 1436 */ { MAD_F(0x07e91cef) /* 0.494412359 */, 15 },
1555 /* 1437 */ { MAD_F(0x07eafe5a) /* 0.494871476 */, 15 },
1556 /* 1438 */ { MAD_F(0x07ecdfe2) /* 0.495330701 */, 15 },
1557 /* 1439 */ { MAD_F(0x07eec187) /* 0.495790031 */, 15 },
1558
1559 /* 1440 */ { MAD_F(0x07f0a348) /* 0.496249468 */, 15 },
1560 /* 1441 */ { MAD_F(0x07f28526) /* 0.496709012 */, 15 },
1561 /* 1442 */ { MAD_F(0x07f46720) /* 0.497168662 */, 15 },
1562 /* 1443 */ { MAD_F(0x07f64937) /* 0.497628418 */, 15 },
1563 /* 1444 */ { MAD_F(0x07f82b6a) /* 0.498088280 */, 15 },
1564 /* 1445 */ { MAD_F(0x07fa0dba) /* 0.498548248 */, 15 },
1565 /* 1446 */ { MAD_F(0x07fbf026) /* 0.499008323 */, 15 },
1566 /* 1447 */ { MAD_F(0x07fdd2af) /* 0.499468503 */, 15 },
1567 /* 1448 */ { MAD_F(0x07ffb554) /* 0.499928790 */, 15 },
1568 /* 1449 */ { MAD_F(0x0400cc0b) /* 0.250194591 */, 16 },
1569 /* 1450 */ { MAD_F(0x0401bd7a) /* 0.250424840 */, 16 },
1570 /* 1451 */ { MAD_F(0x0402aef7) /* 0.250655143 */, 16 },
1571 /* 1452 */ { MAD_F(0x0403a083) /* 0.250885498 */, 16 },
1572 /* 1453 */ { MAD_F(0x0404921c) /* 0.251115906 */, 16 },
1573 /* 1454 */ { MAD_F(0x040583c4) /* 0.251346367 */, 16 },
1574 /* 1455 */ { MAD_F(0x0406757a) /* 0.251576880 */, 16 },
1575
1576 /* 1456 */ { MAD_F(0x0407673f) /* 0.251807447 */, 16 },
1577 /* 1457 */ { MAD_F(0x04085911) /* 0.252038066 */, 16 },
1578 /* 1458 */ { MAD_F(0x04094af1) /* 0.252268738 */, 16 },
1579 /* 1459 */ { MAD_F(0x040a3ce0) /* 0.252499463 */, 16 },
1580 /* 1460 */ { MAD_F(0x040b2edd) /* 0.252730240 */, 16 },
1581 /* 1461 */ { MAD_F(0x040c20e8) /* 0.252961071 */, 16 },
1582 /* 1462 */ { MAD_F(0x040d1301) /* 0.253191953 */, 16 },
1583 /* 1463 */ { MAD_F(0x040e0529) /* 0.253422889 */, 16 },
1584 /* 1464 */ { MAD_F(0x040ef75e) /* 0.253653877 */, 16 },
1585 /* 1465 */ { MAD_F(0x040fe9a1) /* 0.253884918 */, 16 },
1586 /* 1466 */ { MAD_F(0x0410dbf3) /* 0.254116011 */, 16 },
1587 /* 1467 */ { MAD_F(0x0411ce53) /* 0.254347157 */, 16 },
1588 /* 1468 */ { MAD_F(0x0412c0c1) /* 0.254578356 */, 16 },
1589 /* 1469 */ { MAD_F(0x0413b33d) /* 0.254809606 */, 16 },
1590 /* 1470 */ { MAD_F(0x0414a5c7) /* 0.255040910 */, 16 },
1591 /* 1471 */ { MAD_F(0x0415985f) /* 0.255272266 */, 16 },
1592
1593 /* 1472 */ { MAD_F(0x04168b05) /* 0.255503674 */, 16 },
1594 /* 1473 */ { MAD_F(0x04177db9) /* 0.255735135 */, 16 },
1595 /* 1474 */ { MAD_F(0x0418707c) /* 0.255966648 */, 16 },
1596 /* 1475 */ { MAD_F(0x0419634c) /* 0.256198213 */, 16 },
1597 /* 1476 */ { MAD_F(0x041a562a) /* 0.256429831 */, 16 },
1598 /* 1477 */ { MAD_F(0x041b4917) /* 0.256661501 */, 16 },
1599 /* 1478 */ { MAD_F(0x041c3c11) /* 0.256893223 */, 16 },
1600 /* 1479 */ { MAD_F(0x041d2f1a) /* 0.257124998 */, 16 },
1601 /* 1480 */ { MAD_F(0x041e2230) /* 0.257356825 */, 16 },
1602 /* 1481 */ { MAD_F(0x041f1555) /* 0.257588704 */, 16 },
1603 /* 1482 */ { MAD_F(0x04200888) /* 0.257820635 */, 16 },
1604 /* 1483 */ { MAD_F(0x0420fbc8) /* 0.258052619 */, 16 },
1605 /* 1484 */ { MAD_F(0x0421ef17) /* 0.258284654 */, 16 },
1606 /* 1485 */ { MAD_F(0x0422e273) /* 0.258516742 */, 16 },
1607 /* 1486 */ { MAD_F(0x0423d5de) /* 0.258748882 */, 16 },
1608 /* 1487 */ { MAD_F(0x0424c956) /* 0.258981074 */, 16 },
1609
1610 /* 1488 */ { MAD_F(0x0425bcdd) /* 0.259213318 */, 16 },
1611 /* 1489 */ { MAD_F(0x0426b071) /* 0.259445614 */, 16 },
1612 /* 1490 */ { MAD_F(0x0427a414) /* 0.259677962 */, 16 },
1613 /* 1491 */ { MAD_F(0x042897c4) /* 0.259910362 */, 16 },
1614 /* 1492 */ { MAD_F(0x04298b83) /* 0.260142814 */, 16 },
1615 /* 1493 */ { MAD_F(0x042a7f4f) /* 0.260375318 */, 16 },
1616 /* 1494 */ { MAD_F(0x042b7329) /* 0.260607874 */, 16 },
1617 /* 1495 */ { MAD_F(0x042c6711) /* 0.260840481 */, 16 },
1618 /* 1496 */ { MAD_F(0x042d5b07) /* 0.261073141 */, 16 },
1619 /* 1497 */ { MAD_F(0x042e4f0b) /* 0.261305852 */, 16 },
1620 /* 1498 */ { MAD_F(0x042f431d) /* 0.261538616 */, 16 },
1621 /* 1499 */ { MAD_F(0x0430373d) /* 0.261771431 */, 16 },
1622 /* 1500 */ { MAD_F(0x04312b6b) /* 0.262004297 */, 16 },
1623 /* 1501 */ { MAD_F(0x04321fa6) /* 0.262237216 */, 16 },
1624 /* 1502 */ { MAD_F(0x043313f0) /* 0.262470186 */, 16 },
1625 /* 1503 */ { MAD_F(0x04340847) /* 0.262703208 */, 16 },
1626
1627 /* 1504 */ { MAD_F(0x0434fcad) /* 0.262936282 */, 16 },
1628 /* 1505 */ { MAD_F(0x0435f120) /* 0.263169407 */, 16 },
1629 /* 1506 */ { MAD_F(0x0436e5a1) /* 0.263402584 */, 16 },
1630 /* 1507 */ { MAD_F(0x0437da2f) /* 0.263635813 */, 16 },
1631 /* 1508 */ { MAD_F(0x0438cecc) /* 0.263869093 */, 16 },
1632 /* 1509 */ { MAD_F(0x0439c377) /* 0.264102425 */, 16 },
1633 /* 1510 */ { MAD_F(0x043ab82f) /* 0.264335808 */, 16 },
1634 /* 1511 */ { MAD_F(0x043bacf5) /* 0.264569243 */, 16 },
1635 /* 1512 */ { MAD_F(0x043ca1c9) /* 0.264802730 */, 16 },
1636 /* 1513 */ { MAD_F(0x043d96ab) /* 0.265036267 */, 16 },
1637 /* 1514 */ { MAD_F(0x043e8b9b) /* 0.265269857 */, 16 },
1638 /* 1515 */ { MAD_F(0x043f8098) /* 0.265503498 */, 16 },
1639 /* 1516 */ { MAD_F(0x044075a3) /* 0.265737190 */, 16 },
1640 /* 1517 */ { MAD_F(0x04416abc) /* 0.265970933 */, 16 },
1641 /* 1518 */ { MAD_F(0x04425fe3) /* 0.266204728 */, 16 },
1642 /* 1519 */ { MAD_F(0x04435518) /* 0.266438574 */, 16 },
1643
1644 /* 1520 */ { MAD_F(0x04444a5a) /* 0.266672472 */, 16 },
1645 /* 1521 */ { MAD_F(0x04453fab) /* 0.266906421 */, 16 },
1646 /* 1522 */ { MAD_F(0x04463508) /* 0.267140421 */, 16 },
1647 /* 1523 */ { MAD_F(0x04472a74) /* 0.267374472 */, 16 },
1648 /* 1524 */ { MAD_F(0x04481fee) /* 0.267608575 */, 16 },
1649 /* 1525 */ { MAD_F(0x04491575) /* 0.267842729 */, 16 },
1650 /* 1526 */ { MAD_F(0x044a0b0a) /* 0.268076934 */, 16 },
1651 /* 1527 */ { MAD_F(0x044b00ac) /* 0.268311190 */, 16 },
1652 /* 1528 */ { MAD_F(0x044bf65d) /* 0.268545497 */, 16 },
1653 /* 1529 */ { MAD_F(0x044cec1b) /* 0.268779856 */, 16 },
1654 /* 1530 */ { MAD_F(0x044de1e7) /* 0.269014265 */, 16 },
1655 /* 1531 */ { MAD_F(0x044ed7c0) /* 0.269248726 */, 16 },
1656 /* 1532 */ { MAD_F(0x044fcda8) /* 0.269483238 */, 16 },
1657 /* 1533 */ { MAD_F(0x0450c39c) /* 0.269717800 */, 16 },
1658 /* 1534 */ { MAD_F(0x0451b99f) /* 0.269952414 */, 16 },
1659 /* 1535 */ { MAD_F(0x0452afaf) /* 0.270187079 */, 16 },
1660
1661 /* 1536 */ { MAD_F(0x0453a5cd) /* 0.270421794 */, 16 },
1662 /* 1537 */ { MAD_F(0x04549bf9) /* 0.270656561 */, 16 },
1663 /* 1538 */ { MAD_F(0x04559232) /* 0.270891379 */, 16 },
1664 /* 1539 */ { MAD_F(0x04568879) /* 0.271126247 */, 16 },
1665 /* 1540 */ { MAD_F(0x04577ece) /* 0.271361166 */, 16 },
1666 /* 1541 */ { MAD_F(0x04587530) /* 0.271596136 */, 16 },
1667 /* 1542 */ { MAD_F(0x04596ba0) /* 0.271831157 */, 16 },
1668 /* 1543 */ { MAD_F(0x045a621e) /* 0.272066229 */, 16 },
1669 /* 1544 */ { MAD_F(0x045b58a9) /* 0.272301352 */, 16 },
1670 /* 1545 */ { MAD_F(0x045c4f42) /* 0.272536525 */, 16 },
1671 /* 1546 */ { MAD_F(0x045d45e9) /* 0.272771749 */, 16 },
1672 /* 1547 */ { MAD_F(0x045e3c9d) /* 0.273007024 */, 16 },
1673 /* 1548 */ { MAD_F(0x045f335e) /* 0.273242350 */, 16 },
1674 /* 1549 */ { MAD_F(0x04602a2e) /* 0.273477726 */, 16 },
1675 /* 1550 */ { MAD_F(0x0461210b) /* 0.273713153 */, 16 },
1676 /* 1551 */ { MAD_F(0x046217f5) /* 0.273948630 */, 16 },
1677
1678 /* 1552 */ { MAD_F(0x04630eed) /* 0.274184158 */, 16 },
1679 /* 1553 */ { MAD_F(0x046405f3) /* 0.274419737 */, 16 },
1680 /* 1554 */ { MAD_F(0x0464fd06) /* 0.274655366 */, 16 },
1681 /* 1555 */ { MAD_F(0x0465f427) /* 0.274891046 */, 16 },
1682 /* 1556 */ { MAD_F(0x0466eb55) /* 0.275126776 */, 16 },
1683 /* 1557 */ { MAD_F(0x0467e291) /* 0.275362557 */, 16 },
1684 /* 1558 */ { MAD_F(0x0468d9db) /* 0.275598389 */, 16 },
1685 /* 1559 */ { MAD_F(0x0469d132) /* 0.275834270 */, 16 },
1686 /* 1560 */ { MAD_F(0x046ac896) /* 0.276070203 */, 16 },
1687 /* 1561 */ { MAD_F(0x046bc009) /* 0.276306185 */, 16 },
1688 /* 1562 */ { MAD_F(0x046cb788) /* 0.276542218 */, 16 },
1689 /* 1563 */ { MAD_F(0x046daf15) /* 0.276778302 */, 16 },
1690 /* 1564 */ { MAD_F(0x046ea6b0) /* 0.277014435 */, 16 },
1691 /* 1565 */ { MAD_F(0x046f9e58) /* 0.277250619 */, 16 },
1692 /* 1566 */ { MAD_F(0x0470960e) /* 0.277486854 */, 16 },
1693 /* 1567 */ { MAD_F(0x04718dd1) /* 0.277723139 */, 16 },
1694
1695 /* 1568 */ { MAD_F(0x047285a2) /* 0.277959474 */, 16 },
1696 /* 1569 */ { MAD_F(0x04737d80) /* 0.278195859 */, 16 },
1697 /* 1570 */ { MAD_F(0x0474756c) /* 0.278432294 */, 16 },
1698 /* 1571 */ { MAD_F(0x04756d65) /* 0.278668780 */, 16 },
1699 /* 1572 */ { MAD_F(0x0476656b) /* 0.278905316 */, 16 },
1700 /* 1573 */ { MAD_F(0x04775d7f) /* 0.279141902 */, 16 },
1701 /* 1574 */ { MAD_F(0x047855a1) /* 0.279378538 */, 16 },
1702 /* 1575 */ { MAD_F(0x04794dd0) /* 0.279615224 */, 16 },
1703 /* 1576 */ { MAD_F(0x047a460c) /* 0.279851960 */, 16 },
1704 /* 1577 */ { MAD_F(0x047b3e56) /* 0.280088747 */, 16 },
1705 /* 1578 */ { MAD_F(0x047c36ae) /* 0.280325583 */, 16 },
1706 /* 1579 */ { MAD_F(0x047d2f12) /* 0.280562470 */, 16 },
1707 /* 1580 */ { MAD_F(0x047e2784) /* 0.280799406 */, 16 },
1708 /* 1581 */ { MAD_F(0x047f2004) /* 0.281036393 */, 16 },
1709 /* 1582 */ { MAD_F(0x04801891) /* 0.281273429 */, 16 },
1710 /* 1583 */ { MAD_F(0x0481112b) /* 0.281510516 */, 16 },
1711
1712 /* 1584 */ { MAD_F(0x048209d3) /* 0.281747652 */, 16 },
1713 /* 1585 */ { MAD_F(0x04830288) /* 0.281984838 */, 16 },
1714 /* 1586 */ { MAD_F(0x0483fb4b) /* 0.282222075 */, 16 },
1715 /* 1587 */ { MAD_F(0x0484f41b) /* 0.282459361 */, 16 },
1716 /* 1588 */ { MAD_F(0x0485ecf8) /* 0.282696697 */, 16 },
1717 /* 1589 */ { MAD_F(0x0486e5e3) /* 0.282934082 */, 16 },
1718 /* 1590 */ { MAD_F(0x0487dedb) /* 0.283171518 */, 16 },
1719 /* 1591 */ { MAD_F(0x0488d7e1) /* 0.283409003 */, 16 },
1720 /* 1592 */ { MAD_F(0x0489d0f4) /* 0.283646538 */, 16 },
1721 /* 1593 */ { MAD_F(0x048aca14) /* 0.283884123 */, 16 },
1722 /* 1594 */ { MAD_F(0x048bc341) /* 0.284121757 */, 16 },
1723 /* 1595 */ { MAD_F(0x048cbc7c) /* 0.284359441 */, 16 },
1724 /* 1596 */ { MAD_F(0x048db5c4) /* 0.284597175 */, 16 },
1725 /* 1597 */ { MAD_F(0x048eaf1a) /* 0.284834959 */, 16 },
1726 /* 1598 */ { MAD_F(0x048fa87d) /* 0.285072792 */, 16 },
1727 /* 1599 */ { MAD_F(0x0490a1ed) /* 0.285310675 */, 16 },
1728
1729 /* 1600 */ { MAD_F(0x04919b6a) /* 0.285548607 */, 16 },
1730 /* 1601 */ { MAD_F(0x049294f5) /* 0.285786589 */, 16 },
1731 /* 1602 */ { MAD_F(0x04938e8d) /* 0.286024621 */, 16 },
1732 /* 1603 */ { MAD_F(0x04948833) /* 0.286262702 */, 16 },
1733 /* 1604 */ { MAD_F(0x049581e5) /* 0.286500832 */, 16 },
1734 /* 1605 */ { MAD_F(0x04967ba5) /* 0.286739012 */, 16 },
1735 /* 1606 */ { MAD_F(0x04977573) /* 0.286977242 */, 16 },
1736 /* 1607 */ { MAD_F(0x04986f4d) /* 0.287215521 */, 16 },
1737 /* 1608 */ { MAD_F(0x04996935) /* 0.287453849 */, 16 },
1738 /* 1609 */ { MAD_F(0x049a632a) /* 0.287692227 */, 16 },
1739 /* 1610 */ { MAD_F(0x049b5d2c) /* 0.287930654 */, 16 },
1740 /* 1611 */ { MAD_F(0x049c573c) /* 0.288169131 */, 16 },
1741 /* 1612 */ { MAD_F(0x049d5159) /* 0.288407657 */, 16 },
1742 /* 1613 */ { MAD_F(0x049e4b83) /* 0.288646232 */, 16 },
1743 /* 1614 */ { MAD_F(0x049f45ba) /* 0.288884857 */, 16 },
1744 /* 1615 */ { MAD_F(0x04a03ffe) /* 0.289123530 */, 16 },
1745
1746 /* 1616 */ { MAD_F(0x04a13a50) /* 0.289362253 */, 16 },
1747 /* 1617 */ { MAD_F(0x04a234af) /* 0.289601026 */, 16 },
1748 /* 1618 */ { MAD_F(0x04a32f1b) /* 0.289839847 */, 16 },
1749 /* 1619 */ { MAD_F(0x04a42995) /* 0.290078718 */, 16 },
1750 /* 1620 */ { MAD_F(0x04a5241b) /* 0.290317638 */, 16 },
1751 /* 1621 */ { MAD_F(0x04a61eaf) /* 0.290556607 */, 16 },
1752 /* 1622 */ { MAD_F(0x04a71950) /* 0.290795626 */, 16 },
1753 /* 1623 */ { MAD_F(0x04a813fe) /* 0.291034693 */, 16 },
1754 /* 1624 */ { MAD_F(0x04a90eba) /* 0.291273810 */, 16 },
1755 /* 1625 */ { MAD_F(0x04aa0982) /* 0.291512975 */, 16 },
1756 /* 1626 */ { MAD_F(0x04ab0458) /* 0.291752190 */, 16 },
1757 /* 1627 */ { MAD_F(0x04abff3b) /* 0.291991453 */, 16 },
1758 /* 1628 */ { MAD_F(0x04acfa2b) /* 0.292230766 */, 16 },
1759 /* 1629 */ { MAD_F(0x04adf528) /* 0.292470128 */, 16 },
1760 /* 1630 */ { MAD_F(0x04aef032) /* 0.292709539 */, 16 },
1761 /* 1631 */ { MAD_F(0x04afeb4a) /* 0.292948998 */, 16 },
1762
1763 /* 1632 */ { MAD_F(0x04b0e66e) /* 0.293188507 */, 16 },
1764 /* 1633 */ { MAD_F(0x04b1e1a0) /* 0.293428065 */, 16 },
1765 /* 1634 */ { MAD_F(0x04b2dcdf) /* 0.293667671 */, 16 },
1766 /* 1635 */ { MAD_F(0x04b3d82b) /* 0.293907326 */, 16 },
1767 /* 1636 */ { MAD_F(0x04b4d384) /* 0.294147031 */, 16 },
1768 /* 1637 */ { MAD_F(0x04b5ceea) /* 0.294386784 */, 16 },
1769 /* 1638 */ { MAD_F(0x04b6ca5e) /* 0.294626585 */, 16 },
1770 /* 1639 */ { MAD_F(0x04b7c5de) /* 0.294866436 */, 16 },
1771 /* 1640 */ { MAD_F(0x04b8c16c) /* 0.295106336 */, 16 },
1772 /* 1641 */ { MAD_F(0x04b9bd06) /* 0.295346284 */, 16 },
1773 /* 1642 */ { MAD_F(0x04bab8ae) /* 0.295586281 */, 16 },
1774 /* 1643 */ { MAD_F(0x04bbb463) /* 0.295826327 */, 16 },
1775 /* 1644 */ { MAD_F(0x04bcb024) /* 0.296066421 */, 16 },
1776 /* 1645 */ { MAD_F(0x04bdabf3) /* 0.296306564 */, 16 },
1777 /* 1646 */ { MAD_F(0x04bea7cf) /* 0.296546756 */, 16 },
1778 /* 1647 */ { MAD_F(0x04bfa3b8) /* 0.296786996 */, 16 },
1779
1780 /* 1648 */ { MAD_F(0x04c09faf) /* 0.297027285 */, 16 },
1781 /* 1649 */ { MAD_F(0x04c19bb2) /* 0.297267623 */, 16 },
1782 /* 1650 */ { MAD_F(0x04c297c2) /* 0.297508009 */, 16 },
1783 /* 1651 */ { MAD_F(0x04c393df) /* 0.297748444 */, 16 },
1784 /* 1652 */ { MAD_F(0x04c49009) /* 0.297988927 */, 16 },
1785 /* 1653 */ { MAD_F(0x04c58c41) /* 0.298229459 */, 16 },
1786 /* 1654 */ { MAD_F(0x04c68885) /* 0.298470039 */, 16 },
1787 /* 1655 */ { MAD_F(0x04c784d6) /* 0.298710668 */, 16 },
1788 /* 1656 */ { MAD_F(0x04c88135) /* 0.298951346 */, 16 },
1789 /* 1657 */ { MAD_F(0x04c97da0) /* 0.299192071 */, 16 },
1790 /* 1658 */ { MAD_F(0x04ca7a18) /* 0.299432846 */, 16 },
1791 /* 1659 */ { MAD_F(0x04cb769e) /* 0.299673668 */, 16 },
1792 /* 1660 */ { MAD_F(0x04cc7330) /* 0.299914539 */, 16 },
1793 /* 1661 */ { MAD_F(0x04cd6fcf) /* 0.300155459 */, 16 },
1794 /* 1662 */ { MAD_F(0x04ce6c7b) /* 0.300396426 */, 16 },
1795 /* 1663 */ { MAD_F(0x04cf6935) /* 0.300637443 */, 16 },
1796
1797 /* 1664 */ { MAD_F(0x04d065fb) /* 0.300878507 */, 16 },
1798 /* 1665 */ { MAD_F(0x04d162ce) /* 0.301119620 */, 16 },
1799 /* 1666 */ { MAD_F(0x04d25fae) /* 0.301360781 */, 16 },
1800 /* 1667 */ { MAD_F(0x04d35c9b) /* 0.301601990 */, 16 },
1801 /* 1668 */ { MAD_F(0x04d45995) /* 0.301843247 */, 16 },
1802 /* 1669 */ { MAD_F(0x04d5569c) /* 0.302084553 */, 16 },
1803 /* 1670 */ { MAD_F(0x04d653b0) /* 0.302325907 */, 16 },
1804 /* 1671 */ { MAD_F(0x04d750d1) /* 0.302567309 */, 16 },
1805 /* 1672 */ { MAD_F(0x04d84dff) /* 0.302808759 */, 16 },
1806 /* 1673 */ { MAD_F(0x04d94b3a) /* 0.303050257 */, 16 },
1807 /* 1674 */ { MAD_F(0x04da4881) /* 0.303291804 */, 16 },
1808 /* 1675 */ { MAD_F(0x04db45d6) /* 0.303533399 */, 16 },
1809 /* 1676 */ { MAD_F(0x04dc4337) /* 0.303775041 */, 16 },
1810 /* 1677 */ { MAD_F(0x04dd40a6) /* 0.304016732 */, 16 },
1811 /* 1678 */ { MAD_F(0x04de3e21) /* 0.304258471 */, 16 },
1812 /* 1679 */ { MAD_F(0x04df3ba9) /* 0.304500257 */, 16 },
1813
1814 /* 1680 */ { MAD_F(0x04e0393e) /* 0.304742092 */, 16 },
1815 /* 1681 */ { MAD_F(0x04e136e0) /* 0.304983975 */, 16 },
1816 /* 1682 */ { MAD_F(0x04e2348f) /* 0.305225906 */, 16 },
1817 /* 1683 */ { MAD_F(0x04e3324b) /* 0.305467885 */, 16 },
1818 /* 1684 */ { MAD_F(0x04e43013) /* 0.305709911 */, 16 },
1819 /* 1685 */ { MAD_F(0x04e52de9) /* 0.305951986 */, 16 },
1820 /* 1686 */ { MAD_F(0x04e62bcb) /* 0.306194108 */, 16 },
1821 /* 1687 */ { MAD_F(0x04e729ba) /* 0.306436279 */, 16 },
1822 /* 1688 */ { MAD_F(0x04e827b6) /* 0.306678497 */, 16 },
1823 /* 1689 */ { MAD_F(0x04e925bf) /* 0.306920763 */, 16 },
1824 /* 1690 */ { MAD_F(0x04ea23d4) /* 0.307163077 */, 16 },
1825 /* 1691 */ { MAD_F(0x04eb21f7) /* 0.307405438 */, 16 },
1826 /* 1692 */ { MAD_F(0x04ec2026) /* 0.307647848 */, 16 },
1827 /* 1693 */ { MAD_F(0x04ed1e62) /* 0.307890305 */, 16 },
1828 /* 1694 */ { MAD_F(0x04ee1cab) /* 0.308132810 */, 16 },
1829 /* 1695 */ { MAD_F(0x04ef1b01) /* 0.308375362 */, 16 },
1830
1831 /* 1696 */ { MAD_F(0x04f01963) /* 0.308617963 */, 16 },
1832 /* 1697 */ { MAD_F(0x04f117d3) /* 0.308860611 */, 16 },
1833 /* 1698 */ { MAD_F(0x04f2164f) /* 0.309103306 */, 16 },
1834 /* 1699 */ { MAD_F(0x04f314d8) /* 0.309346050 */, 16 },
1835 /* 1700 */ { MAD_F(0x04f4136d) /* 0.309588841 */, 16 },
1836 /* 1701 */ { MAD_F(0x04f51210) /* 0.309831679 */, 16 },
1837 /* 1702 */ { MAD_F(0x04f610bf) /* 0.310074565 */, 16 },
1838 /* 1703 */ { MAD_F(0x04f70f7b) /* 0.310317499 */, 16 },
1839 /* 1704 */ { MAD_F(0x04f80e44) /* 0.310560480 */, 16 },
1840 /* 1705 */ { MAD_F(0x04f90d19) /* 0.310803509 */, 16 },
1841 /* 1706 */ { MAD_F(0x04fa0bfc) /* 0.311046586 */, 16 },
1842 /* 1707 */ { MAD_F(0x04fb0aeb) /* 0.311289710 */, 16 },
1843 /* 1708 */ { MAD_F(0x04fc09e7) /* 0.311532881 */, 16 },
1844 /* 1709 */ { MAD_F(0x04fd08ef) /* 0.311776100 */, 16 },
1845 /* 1710 */ { MAD_F(0x04fe0805) /* 0.312019366 */, 16 },
1846 /* 1711 */ { MAD_F(0x04ff0727) /* 0.312262680 */, 16 },
1847
1848 /* 1712 */ { MAD_F(0x05000655) /* 0.312506041 */, 16 },
1849 /* 1713 */ { MAD_F(0x05010591) /* 0.312749449 */, 16 },
1850 /* 1714 */ { MAD_F(0x050204d9) /* 0.312992905 */, 16 },
1851 /* 1715 */ { MAD_F(0x0503042e) /* 0.313236408 */, 16 },
1852 /* 1716 */ { MAD_F(0x0504038f) /* 0.313479959 */, 16 },
1853 /* 1717 */ { MAD_F(0x050502fe) /* 0.313723556 */, 16 },
1854 /* 1718 */ { MAD_F(0x05060279) /* 0.313967202 */, 16 },
1855 /* 1719 */ { MAD_F(0x05070200) /* 0.314210894 */, 16 },
1856 /* 1720 */ { MAD_F(0x05080195) /* 0.314454634 */, 16 },
1857 /* 1721 */ { MAD_F(0x05090136) /* 0.314698420 */, 16 },
1858 /* 1722 */ { MAD_F(0x050a00e3) /* 0.314942255 */, 16 },
1859 /* 1723 */ { MAD_F(0x050b009e) /* 0.315186136 */, 16 },
1860 /* 1724 */ { MAD_F(0x050c0065) /* 0.315430064 */, 16 },
1861 /* 1725 */ { MAD_F(0x050d0039) /* 0.315674040 */, 16 },
1862 /* 1726 */ { MAD_F(0x050e0019) /* 0.315918063 */, 16 },
1863 /* 1727 */ { MAD_F(0x050f0006) /* 0.316162133 */, 16 },
1864
1865 /* 1728 */ { MAD_F(0x05100000) /* 0.316406250 */, 16 },
1866 /* 1729 */ { MAD_F(0x05110006) /* 0.316650414 */, 16 },
1867 /* 1730 */ { MAD_F(0x05120019) /* 0.316894625 */, 16 },
1868 /* 1731 */ { MAD_F(0x05130039) /* 0.317138884 */, 16 },
1869 /* 1732 */ { MAD_F(0x05140065) /* 0.317383189 */, 16 },
1870 /* 1733 */ { MAD_F(0x0515009e) /* 0.317627541 */, 16 },
1871 /* 1734 */ { MAD_F(0x051600e3) /* 0.317871941 */, 16 },
1872 /* 1735 */ { MAD_F(0x05170135) /* 0.318116387 */, 16 },
1873 /* 1736 */ { MAD_F(0x05180194) /* 0.318360880 */, 16 },
1874 /* 1737 */ { MAD_F(0x051901ff) /* 0.318605421 */, 16 },
1875 /* 1738 */ { MAD_F(0x051a0277) /* 0.318850008 */, 16 },
1876 /* 1739 */ { MAD_F(0x051b02fc) /* 0.319094642 */, 16 },
1877 /* 1740 */ { MAD_F(0x051c038d) /* 0.319339323 */, 16 },
1878 /* 1741 */ { MAD_F(0x051d042a) /* 0.319584051 */, 16 },
1879 /* 1742 */ { MAD_F(0x051e04d4) /* 0.319828826 */, 16 },
1880 /* 1743 */ { MAD_F(0x051f058b) /* 0.320073647 */, 16 },
1881
1882 /* 1744 */ { MAD_F(0x0520064f) /* 0.320318516 */, 16 },
1883 /* 1745 */ { MAD_F(0x0521071f) /* 0.320563431 */, 16 },
1884 /* 1746 */ { MAD_F(0x052207fb) /* 0.320808393 */, 16 },
1885 /* 1747 */ { MAD_F(0x052308e4) /* 0.321053402 */, 16 },
1886 /* 1748 */ { MAD_F(0x052409da) /* 0.321298457 */, 16 },
1887 /* 1749 */ { MAD_F(0x05250adc) /* 0.321543560 */, 16 },
1888 /* 1750 */ { MAD_F(0x05260bea) /* 0.321788709 */, 16 },
1889 /* 1751 */ { MAD_F(0x05270d06) /* 0.322033904 */, 16 },
1890 /* 1752 */ { MAD_F(0x05280e2d) /* 0.322279147 */, 16 },
1891 /* 1753 */ { MAD_F(0x05290f62) /* 0.322524436 */, 16 },
1892 /* 1754 */ { MAD_F(0x052a10a3) /* 0.322769771 */, 16 },
1893 /* 1755 */ { MAD_F(0x052b11f0) /* 0.323015154 */, 16 },
1894 /* 1756 */ { MAD_F(0x052c134a) /* 0.323260583 */, 16 },
1895 /* 1757 */ { MAD_F(0x052d14b0) /* 0.323506058 */, 16 },
1896 /* 1758 */ { MAD_F(0x052e1623) /* 0.323751580 */, 16 },
1897 /* 1759 */ { MAD_F(0x052f17a2) /* 0.323997149 */, 16 },
1898
1899 /* 1760 */ { MAD_F(0x0530192e) /* 0.324242764 */, 16 },
1900 /* 1761 */ { MAD_F(0x05311ac6) /* 0.324488426 */, 16 },
1901 /* 1762 */ { MAD_F(0x05321c6b) /* 0.324734134 */, 16 },
1902 /* 1763 */ { MAD_F(0x05331e1c) /* 0.324979889 */, 16 },
1903 /* 1764 */ { MAD_F(0x05341fda) /* 0.325225690 */, 16 },
1904 /* 1765 */ { MAD_F(0x053521a4) /* 0.325471538 */, 16 },
1905 /* 1766 */ { MAD_F(0x0536237b) /* 0.325717432 */, 16 },
1906 /* 1767 */ { MAD_F(0x0537255e) /* 0.325963372 */, 16 },
1907 /* 1768 */ { MAD_F(0x0538274e) /* 0.326209359 */, 16 },
1908 /* 1769 */ { MAD_F(0x0539294a) /* 0.326455392 */, 16 },
1909 /* 1770 */ { MAD_F(0x053a2b52) /* 0.326701472 */, 16 },
1910 /* 1771 */ { MAD_F(0x053b2d67) /* 0.326947598 */, 16 },
1911 /* 1772 */ { MAD_F(0x053c2f89) /* 0.327193770 */, 16 },
1912 /* 1773 */ { MAD_F(0x053d31b6) /* 0.327439989 */, 16 },
1913 /* 1774 */ { MAD_F(0x053e33f1) /* 0.327686254 */, 16 },
1914 /* 1775 */ { MAD_F(0x053f3637) /* 0.327932565 */, 16 },
1915
1916 /* 1776 */ { MAD_F(0x0540388a) /* 0.328178922 */, 16 },
1917 /* 1777 */ { MAD_F(0x05413aea) /* 0.328425326 */, 16 },
1918 /* 1778 */ { MAD_F(0x05423d56) /* 0.328671776 */, 16 },
1919 /* 1779 */ { MAD_F(0x05433fce) /* 0.328918272 */, 16 },
1920 /* 1780 */ { MAD_F(0x05444253) /* 0.329164814 */, 16 },
1921 /* 1781 */ { MAD_F(0x054544e4) /* 0.329411403 */, 16 },
1922 /* 1782 */ { MAD_F(0x05464781) /* 0.329658038 */, 16 },
1923 /* 1783 */ { MAD_F(0x05474a2b) /* 0.329904718 */, 16 },
1924 /* 1784 */ { MAD_F(0x05484ce2) /* 0.330151445 */, 16 },
1925 /* 1785 */ { MAD_F(0x05494fa4) /* 0.330398218 */, 16 },
1926 /* 1786 */ { MAD_F(0x054a5273) /* 0.330645037 */, 16 },
1927 /* 1787 */ { MAD_F(0x054b554e) /* 0.330891903 */, 16 },
1928 /* 1788 */ { MAD_F(0x054c5836) /* 0.331138814 */, 16 },
1929 /* 1789 */ { MAD_F(0x054d5b2a) /* 0.331385771 */, 16 },
1930 /* 1790 */ { MAD_F(0x054e5e2b) /* 0.331632774 */, 16 },
1931 /* 1791 */ { MAD_F(0x054f6138) /* 0.331879824 */, 16 },
1932
1933 /* 1792 */ { MAD_F(0x05506451) /* 0.332126919 */, 16 },
1934 /* 1793 */ { MAD_F(0x05516776) /* 0.332374060 */, 16 },
1935 /* 1794 */ { MAD_F(0x05526aa8) /* 0.332621247 */, 16 },
1936 /* 1795 */ { MAD_F(0x05536de6) /* 0.332868480 */, 16 },
1937 /* 1796 */ { MAD_F(0x05547131) /* 0.333115759 */, 16 },
1938 /* 1797 */ { MAD_F(0x05557487) /* 0.333363084 */, 16 },
1939 /* 1798 */ { MAD_F(0x055677ea) /* 0.333610455 */, 16 },
1940 /* 1799 */ { MAD_F(0x05577b5a) /* 0.333857872 */, 16 },
1941 /* 1800 */ { MAD_F(0x05587ed5) /* 0.334105334 */, 16 },
1942 /* 1801 */ { MAD_F(0x0559825e) /* 0.334352843 */, 16 },
1943 /* 1802 */ { MAD_F(0x055a85f2) /* 0.334600397 */, 16 },
1944 /* 1803 */ { MAD_F(0x055b8992) /* 0.334847997 */, 16 },
1945 /* 1804 */ { MAD_F(0x055c8d3f) /* 0.335095642 */, 16 },
1946 /* 1805 */ { MAD_F(0x055d90f9) /* 0.335343334 */, 16 },
1947 /* 1806 */ { MAD_F(0x055e94be) /* 0.335591071 */, 16 },
1948 /* 1807 */ { MAD_F(0x055f9890) /* 0.335838854 */, 16 },
1949
1950 /* 1808 */ { MAD_F(0x05609c6e) /* 0.336086683 */, 16 },
1951 /* 1809 */ { MAD_F(0x0561a058) /* 0.336334557 */, 16 },
1952 /* 1810 */ { MAD_F(0x0562a44f) /* 0.336582477 */, 16 },
1953 /* 1811 */ { MAD_F(0x0563a851) /* 0.336830443 */, 16 },
1954 /* 1812 */ { MAD_F(0x0564ac60) /* 0.337078454 */, 16 },
1955 /* 1813 */ { MAD_F(0x0565b07c) /* 0.337326511 */, 16 },
1956 /* 1814 */ { MAD_F(0x0566b4a3) /* 0.337574614 */, 16 },
1957 /* 1815 */ { MAD_F(0x0567b8d7) /* 0.337822762 */, 16 },
1958 /* 1816 */ { MAD_F(0x0568bd17) /* 0.338070956 */, 16 },
1959 /* 1817 */ { MAD_F(0x0569c163) /* 0.338319195 */, 16 },
1960 /* 1818 */ { MAD_F(0x056ac5bc) /* 0.338567480 */, 16 },
1961 /* 1819 */ { MAD_F(0x056bca20) /* 0.338815811 */, 16 },
1962 /* 1820 */ { MAD_F(0x056cce91) /* 0.339064186 */, 16 },
1963 /* 1821 */ { MAD_F(0x056dd30e) /* 0.339312608 */, 16 },
1964 /* 1822 */ { MAD_F(0x056ed798) /* 0.339561075 */, 16 },
1965 /* 1823 */ { MAD_F(0x056fdc2d) /* 0.339809587 */, 16 },
1966
1967 /* 1824 */ { MAD_F(0x0570e0cf) /* 0.340058145 */, 16 },
1968 /* 1825 */ { MAD_F(0x0571e57d) /* 0.340306748 */, 16 },
1969 /* 1826 */ { MAD_F(0x0572ea37) /* 0.340555397 */, 16 },
1970 /* 1827 */ { MAD_F(0x0573eefd) /* 0.340804091 */, 16 },
1971 /* 1828 */ { MAD_F(0x0574f3d0) /* 0.341052830 */, 16 },
1972 /* 1829 */ { MAD_F(0x0575f8ae) /* 0.341301615 */, 16 },
1973 /* 1830 */ { MAD_F(0x0576fd99) /* 0.341550445 */, 16 },
1974 /* 1831 */ { MAD_F(0x05780290) /* 0.341799321 */, 16 },
1975 /* 1832 */ { MAD_F(0x05790793) /* 0.342048241 */, 16 },
1976 /* 1833 */ { MAD_F(0x057a0ca3) /* 0.342297207 */, 16 },
1977 /* 1834 */ { MAD_F(0x057b11be) /* 0.342546219 */, 16 },
1978 /* 1835 */ { MAD_F(0x057c16e6) /* 0.342795275 */, 16 },
1979 /* 1836 */ { MAD_F(0x057d1c1a) /* 0.343044377 */, 16 },
1980 /* 1837 */ { MAD_F(0x057e2159) /* 0.343293524 */, 16 },
1981 /* 1838 */ { MAD_F(0x057f26a6) /* 0.343542717 */, 16 },
1982 /* 1839 */ { MAD_F(0x05802bfe) /* 0.343791954 */, 16 },
1983
1984 /* 1840 */ { MAD_F(0x05813162) /* 0.344041237 */, 16 },
1985 /* 1841 */ { MAD_F(0x058236d2) /* 0.344290564 */, 16 },
1986 /* 1842 */ { MAD_F(0x05833c4f) /* 0.344539937 */, 16 },
1987 /* 1843 */ { MAD_F(0x058441d8) /* 0.344789356 */, 16 },
1988 /* 1844 */ { MAD_F(0x0585476c) /* 0.345038819 */, 16 },
1989 /* 1845 */ { MAD_F(0x05864d0d) /* 0.345288327 */, 16 },
1990 /* 1846 */ { MAD_F(0x058752ba) /* 0.345537880 */, 16 },
1991 /* 1847 */ { MAD_F(0x05885873) /* 0.345787479 */, 16 },
1992 /* 1848 */ { MAD_F(0x05895e39) /* 0.346037122 */, 16 },
1993 /* 1849 */ { MAD_F(0x058a640a) /* 0.346286811 */, 16 },
1994 /* 1850 */ { MAD_F(0x058b69e7) /* 0.346536545 */, 16 },
1995 /* 1851 */ { MAD_F(0x058c6fd1) /* 0.346786323 */, 16 },
1996 /* 1852 */ { MAD_F(0x058d75c6) /* 0.347036147 */, 16 },
1997 /* 1853 */ { MAD_F(0x058e7bc8) /* 0.347286015 */, 16 },
1998 /* 1854 */ { MAD_F(0x058f81d5) /* 0.347535929 */, 16 },
1999 /* 1855 */ { MAD_F(0x059087ef) /* 0.347785887 */, 16 },
2000
2001 /* 1856 */ { MAD_F(0x05918e15) /* 0.348035890 */, 16 },
2002 /* 1857 */ { MAD_F(0x05929447) /* 0.348285939 */, 16 },
2003 /* 1858 */ { MAD_F(0x05939a84) /* 0.348536032 */, 16 },
2004 /* 1859 */ { MAD_F(0x0594a0ce) /* 0.348786170 */, 16 },
2005 /* 1860 */ { MAD_F(0x0595a724) /* 0.349036353 */, 16 },
2006 /* 1861 */ { MAD_F(0x0596ad86) /* 0.349286580 */, 16 },
2007 /* 1862 */ { MAD_F(0x0597b3f4) /* 0.349536853 */, 16 },
2008 /* 1863 */ { MAD_F(0x0598ba6e) /* 0.349787170 */, 16 },
2009 /* 1864 */ { MAD_F(0x0599c0f4) /* 0.350037532 */, 16 },
2010 /* 1865 */ { MAD_F(0x059ac786) /* 0.350287939 */, 16 },
2011 /* 1866 */ { MAD_F(0x059bce25) /* 0.350538391 */, 16 },
2012 /* 1867 */ { MAD_F(0x059cd4cf) /* 0.350788887 */, 16 },
2013 /* 1868 */ { MAD_F(0x059ddb85) /* 0.351039428 */, 16 },
2014 /* 1869 */ { MAD_F(0x059ee247) /* 0.351290014 */, 16 },
2015 /* 1870 */ { MAD_F(0x059fe915) /* 0.351540645 */, 16 },
2016 /* 1871 */ { MAD_F(0x05a0efef) /* 0.351791320 */, 16 },
2017
2018 /* 1872 */ { MAD_F(0x05a1f6d5) /* 0.352042040 */, 16 },
2019 /* 1873 */ { MAD_F(0x05a2fdc7) /* 0.352292804 */, 16 },
2020 /* 1874 */ { MAD_F(0x05a404c5) /* 0.352543613 */, 16 },
2021 /* 1875 */ { MAD_F(0x05a50bcf) /* 0.352794467 */, 16 },
2022 /* 1876 */ { MAD_F(0x05a612e5) /* 0.353045365 */, 16 },
2023 /* 1877 */ { MAD_F(0x05a71a07) /* 0.353296308 */, 16 },
2024 /* 1878 */ { MAD_F(0x05a82135) /* 0.353547296 */, 16 },
2025 /* 1879 */ { MAD_F(0x05a9286f) /* 0.353798328 */, 16 },
2026 /* 1880 */ { MAD_F(0x05aa2fb5) /* 0.354049405 */, 16 },
2027 /* 1881 */ { MAD_F(0x05ab3707) /* 0.354300526 */, 16 },
2028 /* 1882 */ { MAD_F(0x05ac3e65) /* 0.354551691 */, 16 },
2029 /* 1883 */ { MAD_F(0x05ad45ce) /* 0.354802901 */, 16 },
2030 /* 1884 */ { MAD_F(0x05ae4d44) /* 0.355054156 */, 16 },
2031 /* 1885 */ { MAD_F(0x05af54c6) /* 0.355305455 */, 16 },
2032 /* 1886 */ { MAD_F(0x05b05c53) /* 0.355556799 */, 16 },
2033 /* 1887 */ { MAD_F(0x05b163ed) /* 0.355808187 */, 16 },
2034
2035 /* 1888 */ { MAD_F(0x05b26b92) /* 0.356059619 */, 16 },
2036 /* 1889 */ { MAD_F(0x05b37343) /* 0.356311096 */, 16 },
2037 /* 1890 */ { MAD_F(0x05b47b00) /* 0.356562617 */, 16 },
2038 /* 1891 */ { MAD_F(0x05b582c9) /* 0.356814182 */, 16 },
2039 /* 1892 */ { MAD_F(0x05b68a9e) /* 0.357065792 */, 16 },
2040 /* 1893 */ { MAD_F(0x05b7927f) /* 0.357317446 */, 16 },
2041 /* 1894 */ { MAD_F(0x05b89a6c) /* 0.357569145 */, 16 },
2042 /* 1895 */ { MAD_F(0x05b9a265) /* 0.357820887 */, 16 },
2043 /* 1896 */ { MAD_F(0x05baaa69) /* 0.358072674 */, 16 },
2044 /* 1897 */ { MAD_F(0x05bbb27a) /* 0.358324506 */, 16 },
2045 /* 1898 */ { MAD_F(0x05bcba96) /* 0.358576381 */, 16 },
2046 /* 1899 */ { MAD_F(0x05bdc2be) /* 0.358828301 */, 16 },
2047 /* 1900 */ { MAD_F(0x05becaf2) /* 0.359080265 */, 16 },
2048 /* 1901 */ { MAD_F(0x05bfd332) /* 0.359332273 */, 16 },
2049 /* 1902 */ { MAD_F(0x05c0db7e) /* 0.359584326 */, 16 },
2050 /* 1903 */ { MAD_F(0x05c1e3d6) /* 0.359836423 */, 16 },
2051
2052 /* 1904 */ { MAD_F(0x05c2ec39) /* 0.360088563 */, 16 },
2053 /* 1905 */ { MAD_F(0x05c3f4a9) /* 0.360340748 */, 16 },
2054 /* 1906 */ { MAD_F(0x05c4fd24) /* 0.360592977 */, 16 },
2055 /* 1907 */ { MAD_F(0x05c605ab) /* 0.360845251 */, 16 },
2056 /* 1908 */ { MAD_F(0x05c70e3e) /* 0.361097568 */, 16 },
2057 /* 1909 */ { MAD_F(0x05c816dd) /* 0.361349929 */, 16 },
2058 /* 1910 */ { MAD_F(0x05c91f87) /* 0.361602335 */, 16 },
2059 /* 1911 */ { MAD_F(0x05ca283e) /* 0.361854784 */, 16 },
2060 /* 1912 */ { MAD_F(0x05cb3100) /* 0.362107278 */, 16 },
2061 /* 1913 */ { MAD_F(0x05cc39ce) /* 0.362359815 */, 16 },
2062 /* 1914 */ { MAD_F(0x05cd42a8) /* 0.362612397 */, 16 },
2063 /* 1915 */ { MAD_F(0x05ce4b8d) /* 0.362865022 */, 16 },
2064 /* 1916 */ { MAD_F(0x05cf547f) /* 0.363117692 */, 16 },
2065 /* 1917 */ { MAD_F(0x05d05d7c) /* 0.363370405 */, 16 },
2066 /* 1918 */ { MAD_F(0x05d16685) /* 0.363623163 */, 16 },
2067 /* 1919 */ { MAD_F(0x05d26f9a) /* 0.363875964 */, 16 },
2068
2069 /* 1920 */ { MAD_F(0x05d378bb) /* 0.364128809 */, 16 },
2070 /* 1921 */ { MAD_F(0x05d481e7) /* 0.364381698 */, 16 },
2071 /* 1922 */ { MAD_F(0x05d58b1f) /* 0.364634632 */, 16 },
2072 /* 1923 */ { MAD_F(0x05d69463) /* 0.364887608 */, 16 },
2073 /* 1924 */ { MAD_F(0x05d79db3) /* 0.365140629 */, 16 },
2074 /* 1925 */ { MAD_F(0x05d8a70f) /* 0.365393694 */, 16 },
2075 /* 1926 */ { MAD_F(0x05d9b076) /* 0.365646802 */, 16 },
2076 /* 1927 */ { MAD_F(0x05dab9e9) /* 0.365899955 */, 16 },
2077 /* 1928 */ { MAD_F(0x05dbc368) /* 0.366153151 */, 16 },
2078 /* 1929 */ { MAD_F(0x05dcccf2) /* 0.366406390 */, 16 },
2079 /* 1930 */ { MAD_F(0x05ddd689) /* 0.366659674 */, 16 },
2080 /* 1931 */ { MAD_F(0x05dee02b) /* 0.366913001 */, 16 },
2081 /* 1932 */ { MAD_F(0x05dfe9d8) /* 0.367166372 */, 16 },
2082 /* 1933 */ { MAD_F(0x05e0f392) /* 0.367419787 */, 16 },
2083 /* 1934 */ { MAD_F(0x05e1fd57) /* 0.367673246 */, 16 },
2084 /* 1935 */ { MAD_F(0x05e30728) /* 0.367926748 */, 16 },
2085
2086 /* 1936 */ { MAD_F(0x05e41105) /* 0.368180294 */, 16 },
2087 /* 1937 */ { MAD_F(0x05e51aed) /* 0.368433883 */, 16 },
2088 /* 1938 */ { MAD_F(0x05e624e1) /* 0.368687517 */, 16 },
2089 /* 1939 */ { MAD_F(0x05e72ee1) /* 0.368941193 */, 16 },
2090 /* 1940 */ { MAD_F(0x05e838ed) /* 0.369194914 */, 16 },
2091 /* 1941 */ { MAD_F(0x05e94304) /* 0.369448678 */, 16 },
2092 /* 1942 */ { MAD_F(0x05ea4d27) /* 0.369702485 */, 16 },
2093 /* 1943 */ { MAD_F(0x05eb5756) /* 0.369956336 */, 16 },
2094 /* 1944 */ { MAD_F(0x05ec6190) /* 0.370210231 */, 16 },
2095 /* 1945 */ { MAD_F(0x05ed6bd6) /* 0.370464169 */, 16 },
2096 /* 1946 */ { MAD_F(0x05ee7628) /* 0.370718151 */, 16 },
2097 /* 1947 */ { MAD_F(0x05ef8085) /* 0.370972177 */, 16 },
2098 /* 1948 */ { MAD_F(0x05f08aee) /* 0.371226245 */, 16 },
2099 /* 1949 */ { MAD_F(0x05f19563) /* 0.371480358 */, 16 },
2100 /* 1950 */ { MAD_F(0x05f29fe3) /* 0.371734513 */, 16 },
2101 /* 1951 */ { MAD_F(0x05f3aa6f) /* 0.371988712 */, 16 },
2102
2103 /* 1952 */ { MAD_F(0x05f4b507) /* 0.372242955 */, 16 },
2104 /* 1953 */ { MAD_F(0x05f5bfab) /* 0.372497241 */, 16 },
2105 /* 1954 */ { MAD_F(0x05f6ca5a) /* 0.372751570 */, 16 },
2106 /* 1955 */ { MAD_F(0x05f7d514) /* 0.373005943 */, 16 },
2107 /* 1956 */ { MAD_F(0x05f8dfdb) /* 0.373260359 */, 16 },
2108 /* 1957 */ { MAD_F(0x05f9eaad) /* 0.373514819 */, 16 },
2109 /* 1958 */ { MAD_F(0x05faf58a) /* 0.373769322 */, 16 },
2110 /* 1959 */ { MAD_F(0x05fc0073) /* 0.374023868 */, 16 },
2111 /* 1960 */ { MAD_F(0x05fd0b68) /* 0.374278458 */, 16 },
2112 /* 1961 */ { MAD_F(0x05fe1669) /* 0.374533091 */, 16 },
2113 /* 1962 */ { MAD_F(0x05ff2175) /* 0.374787767 */, 16 },
2114 /* 1963 */ { MAD_F(0x06002c8d) /* 0.375042486 */, 16 },
2115 /* 1964 */ { MAD_F(0x060137b0) /* 0.375297249 */, 16 },
2116 /* 1965 */ { MAD_F(0x060242df) /* 0.375552055 */, 16 },
2117 /* 1966 */ { MAD_F(0x06034e19) /* 0.375806904 */, 16 },
2118 /* 1967 */ { MAD_F(0x0604595f) /* 0.376061796 */, 16 },
2119
2120 /* 1968 */ { MAD_F(0x060564b1) /* 0.376316732 */, 16 },
2121 /* 1969 */ { MAD_F(0x0606700f) /* 0.376571710 */, 16 },
2122 /* 1970 */ { MAD_F(0x06077b77) /* 0.376826732 */, 16 },
2123 /* 1971 */ { MAD_F(0x060886ec) /* 0.377081797 */, 16 },
2124 /* 1972 */ { MAD_F(0x0609926c) /* 0.377336905 */, 16 },
2125 /* 1973 */ { MAD_F(0x060a9df8) /* 0.377592057 */, 16 },
2126 /* 1974 */ { MAD_F(0x060ba98f) /* 0.377847251 */, 16 },
2127 /* 1975 */ { MAD_F(0x060cb532) /* 0.378102489 */, 16 },
2128 /* 1976 */ { MAD_F(0x060dc0e0) /* 0.378357769 */, 16 },
2129 /* 1977 */ { MAD_F(0x060ecc9a) /* 0.378613093 */, 16 },
2130 /* 1978 */ { MAD_F(0x060fd860) /* 0.378868460 */, 16 },
2131 /* 1979 */ { MAD_F(0x0610e431) /* 0.379123870 */, 16 },
2132 /* 1980 */ { MAD_F(0x0611f00d) /* 0.379379322 */, 16 },
2133 /* 1981 */ { MAD_F(0x0612fbf5) /* 0.379634818 */, 16 },
2134 /* 1982 */ { MAD_F(0x061407e9) /* 0.379890357 */, 16 },
2135 /* 1983 */ { MAD_F(0x061513e8) /* 0.380145939 */, 16 },
2136
2137 /* 1984 */ { MAD_F(0x06161ff3) /* 0.380401563 */, 16 },
2138 /* 1985 */ { MAD_F(0x06172c09) /* 0.380657231 */, 16 },
2139 /* 1986 */ { MAD_F(0x0618382b) /* 0.380912942 */, 16 },
2140 /* 1987 */ { MAD_F(0x06194458) /* 0.381168695 */, 16 },
2141 /* 1988 */ { MAD_F(0x061a5091) /* 0.381424492 */, 16 },
2142 /* 1989 */ { MAD_F(0x061b5cd5) /* 0.381680331 */, 16 },
2143 /* 1990 */ { MAD_F(0x061c6925) /* 0.381936213 */, 16 },
2144 /* 1991 */ { MAD_F(0x061d7581) /* 0.382192138 */, 16 },
2145 /* 1992 */ { MAD_F(0x061e81e8) /* 0.382448106 */, 16 },
2146 /* 1993 */ { MAD_F(0x061f8e5a) /* 0.382704117 */, 16 },
2147 /* 1994 */ { MAD_F(0x06209ad8) /* 0.382960171 */, 16 },
2148 /* 1995 */ { MAD_F(0x0621a761) /* 0.383216267 */, 16 },
2149 /* 1996 */ { MAD_F(0x0622b3f6) /* 0.383472406 */, 16 },
2150 /* 1997 */ { MAD_F(0x0623c096) /* 0.383728588 */, 16 },
2151 /* 1998 */ { MAD_F(0x0624cd42) /* 0.383984813 */, 16 },
2152 /* 1999 */ { MAD_F(0x0625d9f9) /* 0.384241080 */, 16 },
2153
2154 /* 2000 */ { MAD_F(0x0626e6bc) /* 0.384497391 */, 16 },
2155 /* 2001 */ { MAD_F(0x0627f38a) /* 0.384753744 */, 16 },
2156 /* 2002 */ { MAD_F(0x06290064) /* 0.385010139 */, 16 },
2157 /* 2003 */ { MAD_F(0x062a0d49) /* 0.385266578 */, 16 },
2158 /* 2004 */ { MAD_F(0x062b1a3a) /* 0.385523059 */, 16 },
2159 /* 2005 */ { MAD_F(0x062c2736) /* 0.385779582 */, 16 },
2160 /* 2006 */ { MAD_F(0x062d343d) /* 0.386036149 */, 16 },
2161 /* 2007 */ { MAD_F(0x062e4150) /* 0.386292758 */, 16 },
2162 /* 2008 */ { MAD_F(0x062f4e6f) /* 0.386549409 */, 16 },
2163 /* 2009 */ { MAD_F(0x06305b99) /* 0.386806104 */, 16 },
2164 /* 2010 */ { MAD_F(0x063168ce) /* 0.387062840 */, 16 },
2165 /* 2011 */ { MAD_F(0x0632760f) /* 0.387319620 */, 16 },
2166 /* 2012 */ { MAD_F(0x0633835b) /* 0.387576442 */, 16 },
2167 /* 2013 */ { MAD_F(0x063490b2) /* 0.387833306 */, 16 },
2168 /* 2014 */ { MAD_F(0x06359e15) /* 0.388090213 */, 16 },
2169 /* 2015 */ { MAD_F(0x0636ab83) /* 0.388347163 */, 16 },
2170
2171 /* 2016 */ { MAD_F(0x0637b8fd) /* 0.388604155 */, 16 },
2172 /* 2017 */ { MAD_F(0x0638c682) /* 0.388861190 */, 16 },
2173 /* 2018 */ { MAD_F(0x0639d413) /* 0.389118267 */, 16 },
2174 /* 2019 */ { MAD_F(0x063ae1af) /* 0.389375386 */, 16 },
2175 /* 2020 */ { MAD_F(0x063bef56) /* 0.389632548 */, 16 },
2176 /* 2021 */ { MAD_F(0x063cfd09) /* 0.389889752 */, 16 },
2177 /* 2022 */ { MAD_F(0x063e0ac7) /* 0.390146999 */, 16 },
2178 /* 2023 */ { MAD_F(0x063f1891) /* 0.390404289 */, 16 },
2179 /* 2024 */ { MAD_F(0x06402666) /* 0.390661620 */, 16 },
2180 /* 2025 */ { MAD_F(0x06413446) /* 0.390918994 */, 16 },
2181 /* 2026 */ { MAD_F(0x06424232) /* 0.391176411 */, 16 },
2182 /* 2027 */ { MAD_F(0x06435029) /* 0.391433869 */, 16 },
2183 /* 2028 */ { MAD_F(0x06445e2b) /* 0.391691371 */, 16 },
2184 /* 2029 */ { MAD_F(0x06456c39) /* 0.391948914 */, 16 },
2185 /* 2030 */ { MAD_F(0x06467a52) /* 0.392206500 */, 16 },
2186 /* 2031 */ { MAD_F(0x06478877) /* 0.392464128 */, 16 },
2187
2188 /* 2032 */ { MAD_F(0x064896a7) /* 0.392721798 */, 16 },
2189 /* 2033 */ { MAD_F(0x0649a4e2) /* 0.392979511 */, 16 },
2190 /* 2034 */ { MAD_F(0x064ab328) /* 0.393237266 */, 16 },
2191 /* 2035 */ { MAD_F(0x064bc17a) /* 0.393495063 */, 16 },
2192 /* 2036 */ { MAD_F(0x064ccfd8) /* 0.393752902 */, 16 },
2193 /* 2037 */ { MAD_F(0x064dde40) /* 0.394010784 */, 16 },
2194 /* 2038 */ { MAD_F(0x064eecb4) /* 0.394268707 */, 16 },
2195 /* 2039 */ { MAD_F(0x064ffb33) /* 0.394526673 */, 16 },
2196 /* 2040 */ { MAD_F(0x065109be) /* 0.394784681 */, 16 },
2197 /* 2041 */ { MAD_F(0x06521854) /* 0.395042732 */, 16 },
2198 /* 2042 */ { MAD_F(0x065326f5) /* 0.395300824 */, 16 },
2199 /* 2043 */ { MAD_F(0x065435a1) /* 0.395558959 */, 16 },
2200 /* 2044 */ { MAD_F(0x06554459) /* 0.395817135 */, 16 },
2201 /* 2045 */ { MAD_F(0x0656531c) /* 0.396075354 */, 16 },
2202 /* 2046 */ { MAD_F(0x065761ea) /* 0.396333615 */, 16 },
2203 /* 2047 */ { MAD_F(0x065870c4) /* 0.396591918 */, 16 },
2204
2205 /* 2048 */ { MAD_F(0x06597fa9) /* 0.396850263 */, 16 },
2206 /* 2049 */ { MAD_F(0x065a8e99) /* 0.397108650 */, 16 },
2207 /* 2050 */ { MAD_F(0x065b9d95) /* 0.397367079 */, 16 },
2208 /* 2051 */ { MAD_F(0x065cac9c) /* 0.397625550 */, 16 },
2209 /* 2052 */ { MAD_F(0x065dbbae) /* 0.397884063 */, 16 },
2210 /* 2053 */ { MAD_F(0x065ecacb) /* 0.398142619 */, 16 },
2211 /* 2054 */ { MAD_F(0x065fd9f4) /* 0.398401216 */, 16 },
2212 /* 2055 */ { MAD_F(0x0660e928) /* 0.398659855 */, 16 },
2213 /* 2056 */ { MAD_F(0x0661f867) /* 0.398918536 */, 16 },
2214 /* 2057 */ { MAD_F(0x066307b1) /* 0.399177259 */, 16 },
2215 /* 2058 */ { MAD_F(0x06641707) /* 0.399436024 */, 16 },
2216 /* 2059 */ { MAD_F(0x06652668) /* 0.399694831 */, 16 },
2217 /* 2060 */ { MAD_F(0x066635d4) /* 0.399953679 */, 16 },
2218 /* 2061 */ { MAD_F(0x0667454c) /* 0.400212570 */, 16 },
2219 /* 2062 */ { MAD_F(0x066854ce) /* 0.400471503 */, 16 },
2220 /* 2063 */ { MAD_F(0x0669645c) /* 0.400730477 */, 16 },
2221
2222 /* 2064 */ { MAD_F(0x066a73f5) /* 0.400989493 */, 16 },
2223 /* 2065 */ { MAD_F(0x066b839a) /* 0.401248551 */, 16 },
2224 /* 2066 */ { MAD_F(0x066c9349) /* 0.401507651 */, 16 },
2225 /* 2067 */ { MAD_F(0x066da304) /* 0.401766793 */, 16 },
2226 /* 2068 */ { MAD_F(0x066eb2ca) /* 0.402025976 */, 16 },
2227 /* 2069 */ { MAD_F(0x066fc29b) /* 0.402285202 */, 16 },
2228 /* 2070 */ { MAD_F(0x0670d278) /* 0.402544469 */, 16 },
2229 /* 2071 */ { MAD_F(0x0671e25f) /* 0.402803777 */, 16 },
2230 /* 2072 */ { MAD_F(0x0672f252) /* 0.403063128 */, 16 },
2231 /* 2073 */ { MAD_F(0x06740250) /* 0.403322520 */, 16 },
2232 /* 2074 */ { MAD_F(0x0675125a) /* 0.403581954 */, 16 },
2233 /* 2075 */ { MAD_F(0x0676226e) /* 0.403841430 */, 16 },
2234 /* 2076 */ { MAD_F(0x0677328e) /* 0.404100947 */, 16 },
2235 /* 2077 */ { MAD_F(0x067842b9) /* 0.404360506 */, 16 },
2236 /* 2078 */ { MAD_F(0x067952ef) /* 0.404620107 */, 16 },
2237 /* 2079 */ { MAD_F(0x067a6330) /* 0.404879749 */, 16 },
2238
2239 /* 2080 */ { MAD_F(0x067b737c) /* 0.405139433 */, 16 },
2240 /* 2081 */ { MAD_F(0x067c83d4) /* 0.405399159 */, 16 },
2241 /* 2082 */ { MAD_F(0x067d9436) /* 0.405658926 */, 16 },
2242 /* 2083 */ { MAD_F(0x067ea4a4) /* 0.405918735 */, 16 },
2243 /* 2084 */ { MAD_F(0x067fb51d) /* 0.406178585 */, 16 },
2244 /* 2085 */ { MAD_F(0x0680c5a2) /* 0.406438477 */, 16 },
2245 /* 2086 */ { MAD_F(0x0681d631) /* 0.406698410 */, 16 },
2246 /* 2087 */ { MAD_F(0x0682e6cb) /* 0.406958385 */, 16 },
2247 /* 2088 */ { MAD_F(0x0683f771) /* 0.407218402 */, 16 },
2248 /* 2089 */ { MAD_F(0x06850822) /* 0.407478460 */, 16 },
2249 /* 2090 */ { MAD_F(0x068618de) /* 0.407738559 */, 16 },
2250 /* 2091 */ { MAD_F(0x068729a5) /* 0.407998700 */, 16 },
2251 /* 2092 */ { MAD_F(0x06883a77) /* 0.408258883 */, 16 },
2252 /* 2093 */ { MAD_F(0x06894b55) /* 0.408519107 */, 16 },
2253 /* 2094 */ { MAD_F(0x068a5c3d) /* 0.408779372 */, 16 },
2254 /* 2095 */ { MAD_F(0x068b6d31) /* 0.409039679 */, 16 },
2255
2256 /* 2096 */ { MAD_F(0x068c7e2f) /* 0.409300027 */, 16 },
2257 /* 2097 */ { MAD_F(0x068d8f39) /* 0.409560417 */, 16 },
2258 /* 2098 */ { MAD_F(0x068ea04e) /* 0.409820848 */, 16 },
2259 /* 2099 */ { MAD_F(0x068fb16e) /* 0.410081321 */, 16 },
2260 /* 2100 */ { MAD_F(0x0690c299) /* 0.410341834 */, 16 },
2261 /* 2101 */ { MAD_F(0x0691d3cf) /* 0.410602390 */, 16 },
2262 /* 2102 */ { MAD_F(0x0692e511) /* 0.410862986 */, 16 },
2263 /* 2103 */ { MAD_F(0x0693f65d) /* 0.411123624 */, 16 },
2264 /* 2104 */ { MAD_F(0x069507b5) /* 0.411384303 */, 16 },
2265 /* 2105 */ { MAD_F(0x06961917) /* 0.411645024 */, 16 },
2266 /* 2106 */ { MAD_F(0x06972a85) /* 0.411905785 */, 16 },
2267 /* 2107 */ { MAD_F(0x06983bfe) /* 0.412166588 */, 16 },
2268 /* 2108 */ { MAD_F(0x06994d82) /* 0.412427433 */, 16 },
2269 /* 2109 */ { MAD_F(0x069a5f11) /* 0.412688318 */, 16 },
2270 /* 2110 */ { MAD_F(0x069b70ab) /* 0.412949245 */, 16 },
2271 /* 2111 */ { MAD_F(0x069c8250) /* 0.413210213 */, 16 },
2272
2273 /* 2112 */ { MAD_F(0x069d9400) /* 0.413471222 */, 16 },
2274 /* 2113 */ { MAD_F(0x069ea5bb) /* 0.413732273 */, 16 },
2275 /* 2114 */ { MAD_F(0x069fb781) /* 0.413993364 */, 16 },
2276 /* 2115 */ { MAD_F(0x06a0c953) /* 0.414254497 */, 16 },
2277 /* 2116 */ { MAD_F(0x06a1db2f) /* 0.414515671 */, 16 },
2278 /* 2117 */ { MAD_F(0x06a2ed16) /* 0.414776886 */, 16 },
2279 /* 2118 */ { MAD_F(0x06a3ff09) /* 0.415038142 */, 16 },
2280 /* 2119 */ { MAD_F(0x06a51106) /* 0.415299440 */, 16 },
2281 /* 2120 */ { MAD_F(0x06a6230f) /* 0.415560778 */, 16 },
2282 /* 2121 */ { MAD_F(0x06a73522) /* 0.415822157 */, 16 },
2283 /* 2122 */ { MAD_F(0x06a84741) /* 0.416083578 */, 16 },
2284 /* 2123 */ { MAD_F(0x06a9596a) /* 0.416345040 */, 16 },
2285 /* 2124 */ { MAD_F(0x06aa6b9f) /* 0.416606542 */, 16 },
2286 /* 2125 */ { MAD_F(0x06ab7ddf) /* 0.416868086 */, 16 },
2287 /* 2126 */ { MAD_F(0x06ac9029) /* 0.417129671 */, 16 },
2288 /* 2127 */ { MAD_F(0x06ada27f) /* 0.417391297 */, 16 },
2289
2290 /* 2128 */ { MAD_F(0x06aeb4e0) /* 0.417652964 */, 16 },
2291 /* 2129 */ { MAD_F(0x06afc74b) /* 0.417914672 */, 16 },
2292 /* 2130 */ { MAD_F(0x06b0d9c2) /* 0.418176420 */, 16 },
2293 /* 2131 */ { MAD_F(0x06b1ec43) /* 0.418438210 */, 16 },
2294 /* 2132 */ { MAD_F(0x06b2fed0) /* 0.418700041 */, 16 },
2295 /* 2133 */ { MAD_F(0x06b41168) /* 0.418961912 */, 16 },
2296 /* 2134 */ { MAD_F(0x06b5240a) /* 0.419223825 */, 16 },
2297 /* 2135 */ { MAD_F(0x06b636b8) /* 0.419485778 */, 16 },
2298 /* 2136 */ { MAD_F(0x06b74971) /* 0.419747773 */, 16 },
2299 /* 2137 */ { MAD_F(0x06b85c34) /* 0.420009808 */, 16 },
2300 /* 2138 */ { MAD_F(0x06b96f03) /* 0.420271884 */, 16 },
2301 /* 2139 */ { MAD_F(0x06ba81dc) /* 0.420534001 */, 16 },
2302 /* 2140 */ { MAD_F(0x06bb94c1) /* 0.420796159 */, 16 },
2303 /* 2141 */ { MAD_F(0x06bca7b0) /* 0.421058358 */, 16 },
2304 /* 2142 */ { MAD_F(0x06bdbaaa) /* 0.421320597 */, 16 },
2305 /* 2143 */ { MAD_F(0x06becdb0) /* 0.421582878 */, 16 },
2306
2307 /* 2144 */ { MAD_F(0x06bfe0c0) /* 0.421845199 */, 16 },
2308 /* 2145 */ { MAD_F(0x06c0f3db) /* 0.422107561 */, 16 },
2309 /* 2146 */ { MAD_F(0x06c20702) /* 0.422369964 */, 16 },
2310 /* 2147 */ { MAD_F(0x06c31a33) /* 0.422632407 */, 16 },
2311 /* 2148 */ { MAD_F(0x06c42d6f) /* 0.422894891 */, 16 },
2312 /* 2149 */ { MAD_F(0x06c540b6) /* 0.423157416 */, 16 },
2313 /* 2150 */ { MAD_F(0x06c65408) /* 0.423419982 */, 16 },
2314 /* 2151 */ { MAD_F(0x06c76765) /* 0.423682588 */, 16 },
2315 /* 2152 */ { MAD_F(0x06c87acc) /* 0.423945235 */, 16 },
2316 /* 2153 */ { MAD_F(0x06c98e3f) /* 0.424207923 */, 16 },
2317 /* 2154 */ { MAD_F(0x06caa1bd) /* 0.424470652 */, 16 },
2318 /* 2155 */ { MAD_F(0x06cbb545) /* 0.424733421 */, 16 },
2319 /* 2156 */ { MAD_F(0x06ccc8d9) /* 0.424996230 */, 16 },
2320 /* 2157 */ { MAD_F(0x06cddc77) /* 0.425259081 */, 16 },
2321 /* 2158 */ { MAD_F(0x06cef020) /* 0.425521972 */, 16 },
2322 /* 2159 */ { MAD_F(0x06d003d4) /* 0.425784903 */, 16 },
2323
2324 /* 2160 */ { MAD_F(0x06d11794) /* 0.426047876 */, 16 },
2325 /* 2161 */ { MAD_F(0x06d22b5e) /* 0.426310889 */, 16 },
2326 /* 2162 */ { MAD_F(0x06d33f32) /* 0.426573942 */, 16 },
2327 /* 2163 */ { MAD_F(0x06d45312) /* 0.426837036 */, 16 },
2328 /* 2164 */ { MAD_F(0x06d566fd) /* 0.427100170 */, 16 },
2329 /* 2165 */ { MAD_F(0x06d67af2) /* 0.427363345 */, 16 },
2330 /* 2166 */ { MAD_F(0x06d78ef3) /* 0.427626561 */, 16 },
2331 /* 2167 */ { MAD_F(0x06d8a2fe) /* 0.427889817 */, 16 },
2332 /* 2168 */ { MAD_F(0x06d9b714) /* 0.428153114 */, 16 },
2333 /* 2169 */ { MAD_F(0x06dacb35) /* 0.428416451 */, 16 },
2334 /* 2170 */ { MAD_F(0x06dbdf61) /* 0.428679828 */, 16 },
2335 /* 2171 */ { MAD_F(0x06dcf398) /* 0.428943246 */, 16 },
2336 /* 2172 */ { MAD_F(0x06de07d9) /* 0.429206704 */, 16 },
2337 /* 2173 */ { MAD_F(0x06df1c26) /* 0.429470203 */, 16 },
2338 /* 2174 */ { MAD_F(0x06e0307d) /* 0.429733743 */, 16 },
2339 /* 2175 */ { MAD_F(0x06e144df) /* 0.429997322 */, 16 },
2340
2341 /* 2176 */ { MAD_F(0x06e2594c) /* 0.430260942 */, 16 },
2342 /* 2177 */ { MAD_F(0x06e36dc4) /* 0.430524603 */, 16 },
2343 /* 2178 */ { MAD_F(0x06e48246) /* 0.430788304 */, 16 },
2344 /* 2179 */ { MAD_F(0x06e596d4) /* 0.431052045 */, 16 },
2345 /* 2180 */ { MAD_F(0x06e6ab6c) /* 0.431315826 */, 16 },
2346 /* 2181 */ { MAD_F(0x06e7c00f) /* 0.431579648 */, 16 },
2347 /* 2182 */ { MAD_F(0x06e8d4bd) /* 0.431843511 */, 16 },
2348 /* 2183 */ { MAD_F(0x06e9e976) /* 0.432107413 */, 16 },
2349 /* 2184 */ { MAD_F(0x06eafe3a) /* 0.432371356 */, 16 },
2350 /* 2185 */ { MAD_F(0x06ec1308) /* 0.432635339 */, 16 },
2351 /* 2186 */ { MAD_F(0x06ed27e2) /* 0.432899362 */, 16 },
2352 /* 2187 */ { MAD_F(0x06ee3cc6) /* 0.433163426 */, 16 },
2353 /* 2188 */ { MAD_F(0x06ef51b4) /* 0.433427530 */, 16 },
2354 /* 2189 */ { MAD_F(0x06f066ae) /* 0.433691674 */, 16 },
2355 /* 2190 */ { MAD_F(0x06f17bb3) /* 0.433955859 */, 16 },
2356 /* 2191 */ { MAD_F(0x06f290c2) /* 0.434220083 */, 16 },
2357
2358 /* 2192 */ { MAD_F(0x06f3a5dc) /* 0.434484348 */, 16 },
2359 /* 2193 */ { MAD_F(0x06f4bb01) /* 0.434748653 */, 16 },
2360 /* 2194 */ { MAD_F(0x06f5d030) /* 0.435012998 */, 16 },
2361 /* 2195 */ { MAD_F(0x06f6e56b) /* 0.435277383 */, 16 },
2362 /* 2196 */ { MAD_F(0x06f7fab0) /* 0.435541809 */, 16 },
2363 /* 2197 */ { MAD_F(0x06f91000) /* 0.435806274 */, 16 },
2364 /* 2198 */ { MAD_F(0x06fa255a) /* 0.436070780 */, 16 },
2365 /* 2199 */ { MAD_F(0x06fb3ac0) /* 0.436335326 */, 16 },
2366 /* 2200 */ { MAD_F(0x06fc5030) /* 0.436599912 */, 16 },
2367 /* 2201 */ { MAD_F(0x06fd65ab) /* 0.436864538 */, 16 },
2368 /* 2202 */ { MAD_F(0x06fe7b31) /* 0.437129204 */, 16 },
2369 /* 2203 */ { MAD_F(0x06ff90c2) /* 0.437393910 */, 16 },
2370 /* 2204 */ { MAD_F(0x0700a65d) /* 0.437658657 */, 16 },
2371 /* 2205 */ { MAD_F(0x0701bc03) /* 0.437923443 */, 16 },
2372 /* 2206 */ { MAD_F(0x0702d1b4) /* 0.438188269 */, 16 },
2373 /* 2207 */ { MAD_F(0x0703e76f) /* 0.438453136 */, 16 },
2374
2375 /* 2208 */ { MAD_F(0x0704fd35) /* 0.438718042 */, 16 },
2376 /* 2209 */ { MAD_F(0x07061306) /* 0.438982988 */, 16 },
2377 /* 2210 */ { MAD_F(0x070728e2) /* 0.439247975 */, 16 },
2378 /* 2211 */ { MAD_F(0x07083ec9) /* 0.439513001 */, 16 },
2379 /* 2212 */ { MAD_F(0x070954ba) /* 0.439778067 */, 16 },
2380 /* 2213 */ { MAD_F(0x070a6ab6) /* 0.440043173 */, 16 },
2381 /* 2214 */ { MAD_F(0x070b80bc) /* 0.440308320 */, 16 },
2382 /* 2215 */ { MAD_F(0x070c96ce) /* 0.440573506 */, 16 },
2383 /* 2216 */ { MAD_F(0x070dacea) /* 0.440838732 */, 16 },
2384 /* 2217 */ { MAD_F(0x070ec310) /* 0.441103997 */, 16 },
2385 /* 2218 */ { MAD_F(0x070fd942) /* 0.441369303 */, 16 },
2386 /* 2219 */ { MAD_F(0x0710ef7e) /* 0.441634649 */, 16 },
2387 /* 2220 */ { MAD_F(0x071205c5) /* 0.441900034 */, 16 },
2388 /* 2221 */ { MAD_F(0x07131c17) /* 0.442165460 */, 16 },
2389 /* 2222 */ { MAD_F(0x07143273) /* 0.442430925 */, 16 },
2390 /* 2223 */ { MAD_F(0x071548da) /* 0.442696430 */, 16 },
2391
2392 /* 2224 */ { MAD_F(0x07165f4b) /* 0.442961975 */, 16 },
2393 /* 2225 */ { MAD_F(0x071775c8) /* 0.443227559 */, 16 },
2394 /* 2226 */ { MAD_F(0x07188c4f) /* 0.443493184 */, 16 },
2395 /* 2227 */ { MAD_F(0x0719a2e0) /* 0.443758848 */, 16 },
2396 /* 2228 */ { MAD_F(0x071ab97d) /* 0.444024552 */, 16 },
2397 /* 2229 */ { MAD_F(0x071bd024) /* 0.444290296 */, 16 },
2398 /* 2230 */ { MAD_F(0x071ce6d6) /* 0.444556079 */, 16 },
2399 /* 2231 */ { MAD_F(0x071dfd92) /* 0.444821902 */, 16 },
2400 /* 2232 */ { MAD_F(0x071f1459) /* 0.445087765 */, 16 },
2401 /* 2233 */ { MAD_F(0x07202b2b) /* 0.445353668 */, 16 },
2402 /* 2234 */ { MAD_F(0x07214207) /* 0.445619610 */, 16 },
2403 /* 2235 */ { MAD_F(0x072258ee) /* 0.445885592 */, 16 },
2404 /* 2236 */ { MAD_F(0x07236fe0) /* 0.446151614 */, 16 },
2405 /* 2237 */ { MAD_F(0x072486dc) /* 0.446417675 */, 16 },
2406 /* 2238 */ { MAD_F(0x07259de3) /* 0.446683776 */, 16 },
2407 /* 2239 */ { MAD_F(0x0726b4f4) /* 0.446949917 */, 16 },
2408
2409 /* 2240 */ { MAD_F(0x0727cc11) /* 0.447216097 */, 16 },
2410 /* 2241 */ { MAD_F(0x0728e338) /* 0.447482317 */, 16 },
2411 /* 2242 */ { MAD_F(0x0729fa69) /* 0.447748576 */, 16 },
2412 /* 2243 */ { MAD_F(0x072b11a5) /* 0.448014875 */, 16 },
2413 /* 2244 */ { MAD_F(0x072c28ec) /* 0.448281214 */, 16 },
2414 /* 2245 */ { MAD_F(0x072d403d) /* 0.448547592 */, 16 },
2415 /* 2246 */ { MAD_F(0x072e5799) /* 0.448814010 */, 16 },
2416 /* 2247 */ { MAD_F(0x072f6f00) /* 0.449080467 */, 16 },
2417 /* 2248 */ { MAD_F(0x07308671) /* 0.449346964 */, 16 },
2418 /* 2249 */ { MAD_F(0x07319ded) /* 0.449613501 */, 16 },
2419 /* 2250 */ { MAD_F(0x0732b573) /* 0.449880076 */, 16 },
2420 /* 2251 */ { MAD_F(0x0733cd04) /* 0.450146692 */, 16 },
2421 /* 2252 */ { MAD_F(0x0734e4a0) /* 0.450413347 */, 16 },
2422 /* 2253 */ { MAD_F(0x0735fc46) /* 0.450680041 */, 16 },
2423 /* 2254 */ { MAD_F(0x073713f7) /* 0.450946775 */, 16 },
2424 /* 2255 */ { MAD_F(0x07382bb2) /* 0.451213548 */, 16 },
2425
2426 /* 2256 */ { MAD_F(0x07394378) /* 0.451480360 */, 16 },
2427 /* 2257 */ { MAD_F(0x073a5b49) /* 0.451747213 */, 16 },
2428 /* 2258 */ { MAD_F(0x073b7324) /* 0.452014104 */, 16 },
2429 /* 2259 */ { MAD_F(0x073c8b0a) /* 0.452281035 */, 16 },
2430 /* 2260 */ { MAD_F(0x073da2fa) /* 0.452548005 */, 16 },
2431 /* 2261 */ { MAD_F(0x073ebaf5) /* 0.452815015 */, 16 },
2432 /* 2262 */ { MAD_F(0x073fd2fa) /* 0.453082064 */, 16 },
2433 /* 2263 */ { MAD_F(0x0740eb0a) /* 0.453349152 */, 16 },
2434 /* 2264 */ { MAD_F(0x07420325) /* 0.453616280 */, 16 },
2435 /* 2265 */ { MAD_F(0x07431b4a) /* 0.453883447 */, 16 },
2436 /* 2266 */ { MAD_F(0x0744337a) /* 0.454150653 */, 16 },
2437 /* 2267 */ { MAD_F(0x07454bb4) /* 0.454417899 */, 16 },
2438 /* 2268 */ { MAD_F(0x074663f8) /* 0.454685184 */, 16 },
2439 /* 2269 */ { MAD_F(0x07477c48) /* 0.454952508 */, 16 },
2440 /* 2270 */ { MAD_F(0x074894a2) /* 0.455219872 */, 16 },
2441 /* 2271 */ { MAD_F(0x0749ad06) /* 0.455487275 */, 16 },
2442
2443 /* 2272 */ { MAD_F(0x074ac575) /* 0.455754717 */, 16 },
2444 /* 2273 */ { MAD_F(0x074bddee) /* 0.456022198 */, 16 },
2445 /* 2274 */ { MAD_F(0x074cf672) /* 0.456289719 */, 16 },
2446 /* 2275 */ { MAD_F(0x074e0f01) /* 0.456557278 */, 16 },
2447 /* 2276 */ { MAD_F(0x074f279a) /* 0.456824877 */, 16 },
2448 /* 2277 */ { MAD_F(0x0750403e) /* 0.457092516 */, 16 },
2449 /* 2278 */ { MAD_F(0x075158ec) /* 0.457360193 */, 16 },
2450 /* 2279 */ { MAD_F(0x075271a4) /* 0.457627909 */, 16 },
2451 /* 2280 */ { MAD_F(0x07538a67) /* 0.457895665 */, 16 },
2452 /* 2281 */ { MAD_F(0x0754a335) /* 0.458163460 */, 16 },
2453 /* 2282 */ { MAD_F(0x0755bc0d) /* 0.458431294 */, 16 },
2454 /* 2283 */ { MAD_F(0x0756d4f0) /* 0.458699167 */, 16 },
2455 /* 2284 */ { MAD_F(0x0757eddd) /* 0.458967079 */, 16 },
2456 /* 2285 */ { MAD_F(0x075906d5) /* 0.459235030 */, 16 },
2457 /* 2286 */ { MAD_F(0x075a1fd7) /* 0.459503021 */, 16 },
2458 /* 2287 */ { MAD_F(0x075b38e3) /* 0.459771050 */, 16 },
2459
2460 /* 2288 */ { MAD_F(0x075c51fa) /* 0.460039119 */, 16 },
2461 /* 2289 */ { MAD_F(0x075d6b1c) /* 0.460307226 */, 16 },
2462 /* 2290 */ { MAD_F(0x075e8448) /* 0.460575373 */, 16 },
2463 /* 2291 */ { MAD_F(0x075f9d7f) /* 0.460843559 */, 16 },
2464 /* 2292 */ { MAD_F(0x0760b6c0) /* 0.461111783 */, 16 },
2465 /* 2293 */ { MAD_F(0x0761d00b) /* 0.461380047 */, 16 },
2466 /* 2294 */ { MAD_F(0x0762e961) /* 0.461648350 */, 16 },
2467 /* 2295 */ { MAD_F(0x076402c1) /* 0.461916691 */, 16 },
2468 /* 2296 */ { MAD_F(0x07651c2c) /* 0.462185072 */, 16 },
2469 /* 2297 */ { MAD_F(0x076635a2) /* 0.462453492 */, 16 },
2470 /* 2298 */ { MAD_F(0x07674f22) /* 0.462721950 */, 16 },
2471 /* 2299 */ { MAD_F(0x076868ac) /* 0.462990448 */, 16 },
2472 /* 2300 */ { MAD_F(0x07698240) /* 0.463258984 */, 16 },
2473 /* 2301 */ { MAD_F(0x076a9be0) /* 0.463527560 */, 16 },
2474 /* 2302 */ { MAD_F(0x076bb589) /* 0.463796174 */, 16 },
2475 /* 2303 */ { MAD_F(0x076ccf3d) /* 0.464064827 */, 16 },
2476
2477 /* 2304 */ { MAD_F(0x076de8fc) /* 0.464333519 */, 16 },
2478 /* 2305 */ { MAD_F(0x076f02c5) /* 0.464602250 */, 16 },
2479 /* 2306 */ { MAD_F(0x07701c98) /* 0.464871020 */, 16 },
2480 /* 2307 */ { MAD_F(0x07713676) /* 0.465139829 */, 16 },
2481 /* 2308 */ { MAD_F(0x0772505e) /* 0.465408676 */, 16 },
2482 /* 2309 */ { MAD_F(0x07736a51) /* 0.465677563 */, 16 },
2483 /* 2310 */ { MAD_F(0x0774844e) /* 0.465946488 */, 16 },
2484 /* 2311 */ { MAD_F(0x07759e55) /* 0.466215452 */, 16 },
2485 /* 2312 */ { MAD_F(0x0776b867) /* 0.466484455 */, 16 },
2486 /* 2313 */ { MAD_F(0x0777d283) /* 0.466753496 */, 16 },
2487 /* 2314 */ { MAD_F(0x0778ecaa) /* 0.467022577 */, 16 },
2488 /* 2315 */ { MAD_F(0x077a06db) /* 0.467291696 */, 16 },
2489 /* 2316 */ { MAD_F(0x077b2117) /* 0.467560854 */, 16 },
2490 /* 2317 */ { MAD_F(0x077c3b5d) /* 0.467830050 */, 16 },
2491 /* 2318 */ { MAD_F(0x077d55ad) /* 0.468099285 */, 16 },
2492 /* 2319 */ { MAD_F(0x077e7008) /* 0.468368560 */, 16 },
2493
2494 /* 2320 */ { MAD_F(0x077f8a6d) /* 0.468637872 */, 16 },
2495 /* 2321 */ { MAD_F(0x0780a4dc) /* 0.468907224 */, 16 },
2496 /* 2322 */ { MAD_F(0x0781bf56) /* 0.469176614 */, 16 },
2497 /* 2323 */ { MAD_F(0x0782d9da) /* 0.469446043 */, 16 },
2498 /* 2324 */ { MAD_F(0x0783f469) /* 0.469715510 */, 16 },
2499 /* 2325 */ { MAD_F(0x07850f02) /* 0.469985016 */, 16 },
2500 /* 2326 */ { MAD_F(0x078629a5) /* 0.470254561 */, 16 },
2501 /* 2327 */ { MAD_F(0x07874453) /* 0.470524145 */, 16 },
2502 /* 2328 */ { MAD_F(0x07885f0b) /* 0.470793767 */, 16 },
2503 /* 2329 */ { MAD_F(0x078979ce) /* 0.471063427 */, 16 },
2504 /* 2330 */ { MAD_F(0x078a949a) /* 0.471333126 */, 16 },
2505 /* 2331 */ { MAD_F(0x078baf72) /* 0.471602864 */, 16 },
2506 /* 2332 */ { MAD_F(0x078cca53) /* 0.471872641 */, 16 },
2507 /* 2333 */ { MAD_F(0x078de53f) /* 0.472142456 */, 16 },
2508 /* 2334 */ { MAD_F(0x078f0035) /* 0.472412309 */, 16 },
2509 /* 2335 */ { MAD_F(0x07901b36) /* 0.472682201 */, 16 },
2510
2511 /* 2336 */ { MAD_F(0x07913641) /* 0.472952132 */, 16 },
2512 /* 2337 */ { MAD_F(0x07925156) /* 0.473222101 */, 16 },
2513 /* 2338 */ { MAD_F(0x07936c76) /* 0.473492108 */, 16 },
2514 /* 2339 */ { MAD_F(0x079487a0) /* 0.473762155 */, 16 },
2515 /* 2340 */ { MAD_F(0x0795a2d4) /* 0.474032239 */, 16 },
2516 /* 2341 */ { MAD_F(0x0796be13) /* 0.474302362 */, 16 },
2517 /* 2342 */ { MAD_F(0x0797d95c) /* 0.474572524 */, 16 },
2518 /* 2343 */ { MAD_F(0x0798f4af) /* 0.474842724 */, 16 },
2519 /* 2344 */ { MAD_F(0x079a100c) /* 0.475112962 */, 16 },
2520 /* 2345 */ { MAD_F(0x079b2b74) /* 0.475383239 */, 16 },
2521 /* 2346 */ { MAD_F(0x079c46e7) /* 0.475653554 */, 16 },
2522 /* 2347 */ { MAD_F(0x079d6263) /* 0.475923908 */, 16 },
2523 /* 2348 */ { MAD_F(0x079e7dea) /* 0.476194300 */, 16 },
2524 /* 2349 */ { MAD_F(0x079f997b) /* 0.476464731 */, 16 },
2525 /* 2350 */ { MAD_F(0x07a0b516) /* 0.476735200 */, 16 },
2526 /* 2351 */ { MAD_F(0x07a1d0bc) /* 0.477005707 */, 16 },
2527
2528 /* 2352 */ { MAD_F(0x07a2ec6c) /* 0.477276252 */, 16 },
2529 /* 2353 */ { MAD_F(0x07a40827) /* 0.477546836 */, 16 },
2530 /* 2354 */ { MAD_F(0x07a523eb) /* 0.477817459 */, 16 },
2531 /* 2355 */ { MAD_F(0x07a63fba) /* 0.478088119 */, 16 },
2532 /* 2356 */ { MAD_F(0x07a75b93) /* 0.478358818 */, 16 },
2533 /* 2357 */ { MAD_F(0x07a87777) /* 0.478629555 */, 16 },
2534 /* 2358 */ { MAD_F(0x07a99364) /* 0.478900331 */, 16 },
2535 /* 2359 */ { MAD_F(0x07aaaf5c) /* 0.479171145 */, 16 },
2536 /* 2360 */ { MAD_F(0x07abcb5f) /* 0.479441997 */, 16 },
2537 /* 2361 */ { MAD_F(0x07ace76b) /* 0.479712887 */, 16 },
2538 /* 2362 */ { MAD_F(0x07ae0382) /* 0.479983816 */, 16 },
2539 /* 2363 */ { MAD_F(0x07af1fa3) /* 0.480254782 */, 16 },
2540 /* 2364 */ { MAD_F(0x07b03bcf) /* 0.480525787 */, 16 },
2541 /* 2365 */ { MAD_F(0x07b15804) /* 0.480796831 */, 16 },
2542 /* 2366 */ { MAD_F(0x07b27444) /* 0.481067912 */, 16 },
2543 /* 2367 */ { MAD_F(0x07b3908e) /* 0.481339032 */, 16 },
2544
2545 /* 2368 */ { MAD_F(0x07b4ace3) /* 0.481610189 */, 16 },
2546 /* 2369 */ { MAD_F(0x07b5c941) /* 0.481881385 */, 16 },
2547 /* 2370 */ { MAD_F(0x07b6e5aa) /* 0.482152620 */, 16 },
2548 /* 2371 */ { MAD_F(0x07b8021d) /* 0.482423892 */, 16 },
2549 /* 2372 */ { MAD_F(0x07b91e9b) /* 0.482695202 */, 16 },
2550 /* 2373 */ { MAD_F(0x07ba3b22) /* 0.482966551 */, 16 },
2551 /* 2374 */ { MAD_F(0x07bb57b4) /* 0.483237938 */, 16 },
2552 /* 2375 */ { MAD_F(0x07bc7450) /* 0.483509362 */, 16 },
2553 /* 2376 */ { MAD_F(0x07bd90f6) /* 0.483780825 */, 16 },
2554 /* 2377 */ { MAD_F(0x07beada7) /* 0.484052326 */, 16 },
2555 /* 2378 */ { MAD_F(0x07bfca61) /* 0.484323865 */, 16 },
2556 /* 2379 */ { MAD_F(0x07c0e726) /* 0.484595443 */, 16 },
2557 /* 2380 */ { MAD_F(0x07c203f5) /* 0.484867058 */, 16 },
2558 /* 2381 */ { MAD_F(0x07c320cf) /* 0.485138711 */, 16 },
2559 /* 2382 */ { MAD_F(0x07c43db2) /* 0.485410402 */, 16 },
2560 /* 2383 */ { MAD_F(0x07c55aa0) /* 0.485682131 */, 16 },
2561
2562 /* 2384 */ { MAD_F(0x07c67798) /* 0.485953899 */, 16 },
2563 /* 2385 */ { MAD_F(0x07c7949a) /* 0.486225704 */, 16 },
2564 /* 2386 */ { MAD_F(0x07c8b1a7) /* 0.486497547 */, 16 },
2565 /* 2387 */ { MAD_F(0x07c9cebd) /* 0.486769429 */, 16 },
2566 /* 2388 */ { MAD_F(0x07caebde) /* 0.487041348 */, 16 },
2567 /* 2389 */ { MAD_F(0x07cc0909) /* 0.487313305 */, 16 },
2568 /* 2390 */ { MAD_F(0x07cd263e) /* 0.487585300 */, 16 },
2569 /* 2391 */ { MAD_F(0x07ce437d) /* 0.487857333 */, 16 },
2570 /* 2392 */ { MAD_F(0x07cf60c7) /* 0.488129404 */, 16 },
2571 /* 2393 */ { MAD_F(0x07d07e1b) /* 0.488401513 */, 16 },
2572 /* 2394 */ { MAD_F(0x07d19b79) /* 0.488673660 */, 16 },
2573 /* 2395 */ { MAD_F(0x07d2b8e1) /* 0.488945845 */, 16 },
2574 /* 2396 */ { MAD_F(0x07d3d653) /* 0.489218067 */, 16 },
2575 /* 2397 */ { MAD_F(0x07d4f3cf) /* 0.489490328 */, 16 },
2576 /* 2398 */ { MAD_F(0x07d61156) /* 0.489762626 */, 16 },
2577 /* 2399 */ { MAD_F(0x07d72ee6) /* 0.490034962 */, 16 },
2578
2579 /* 2400 */ { MAD_F(0x07d84c81) /* 0.490307336 */, 16 },
2580 /* 2401 */ { MAD_F(0x07d96a26) /* 0.490579748 */, 16 },
2581 /* 2402 */ { MAD_F(0x07da87d5) /* 0.490852198 */, 16 },
2582 /* 2403 */ { MAD_F(0x07dba58f) /* 0.491124686 */, 16 },
2583 /* 2404 */ { MAD_F(0x07dcc352) /* 0.491397211 */, 16 },
2584 /* 2405 */ { MAD_F(0x07dde120) /* 0.491669774 */, 16 },
2585 /* 2406 */ { MAD_F(0x07defef7) /* 0.491942375 */, 16 },
2586 /* 2407 */ { MAD_F(0x07e01cd9) /* 0.492215014 */, 16 },
2587 /* 2408 */ { MAD_F(0x07e13ac5) /* 0.492487690 */, 16 },
2588 /* 2409 */ { MAD_F(0x07e258bc) /* 0.492760404 */, 16 },
2589 /* 2410 */ { MAD_F(0x07e376bc) /* 0.493033156 */, 16 },
2590 /* 2411 */ { MAD_F(0x07e494c6) /* 0.493305946 */, 16 },
2591 /* 2412 */ { MAD_F(0x07e5b2db) /* 0.493578773 */, 16 },
2592 /* 2413 */ { MAD_F(0x07e6d0f9) /* 0.493851638 */, 16 },
2593 /* 2414 */ { MAD_F(0x07e7ef22) /* 0.494124541 */, 16 },
2594 /* 2415 */ { MAD_F(0x07e90d55) /* 0.494397481 */, 16 },
2595
2596 /* 2416 */ { MAD_F(0x07ea2b92) /* 0.494670459 */, 16 },
2597 /* 2417 */ { MAD_F(0x07eb49d9) /* 0.494943475 */, 16 },
2598 /* 2418 */ { MAD_F(0x07ec682a) /* 0.495216529 */, 16 },
2599 /* 2419 */ { MAD_F(0x07ed8686) /* 0.495489620 */, 16 },
2600 /* 2420 */ { MAD_F(0x07eea4eb) /* 0.495762748 */, 16 },
2601 /* 2421 */ { MAD_F(0x07efc35b) /* 0.496035915 */, 16 },
2602 /* 2422 */ { MAD_F(0x07f0e1d4) /* 0.496309119 */, 16 },
2603 /* 2423 */ { MAD_F(0x07f20058) /* 0.496582360 */, 16 },
2604 /* 2424 */ { MAD_F(0x07f31ee6) /* 0.496855639 */, 16 },
2605 /* 2425 */ { MAD_F(0x07f43d7e) /* 0.497128956 */, 16 },
2606 /* 2426 */ { MAD_F(0x07f55c20) /* 0.497402310 */, 16 },
2607 /* 2427 */ { MAD_F(0x07f67acc) /* 0.497675702 */, 16 },
2608 /* 2428 */ { MAD_F(0x07f79982) /* 0.497949132 */, 16 },
2609 /* 2429 */ { MAD_F(0x07f8b842) /* 0.498222598 */, 16 },
2610 /* 2430 */ { MAD_F(0x07f9d70c) /* 0.498496103 */, 16 },
2611 /* 2431 */ { MAD_F(0x07faf5e1) /* 0.498769645 */, 16 },
2612
2613 /* 2432 */ { MAD_F(0x07fc14bf) /* 0.499043224 */, 16 },
2614 /* 2433 */ { MAD_F(0x07fd33a8) /* 0.499316841 */, 16 },
2615 /* 2434 */ { MAD_F(0x07fe529a) /* 0.499590496 */, 16 },
2616 /* 2435 */ { MAD_F(0x07ff7197) /* 0.499864188 */, 16 },
2617 /* 2436 */ { MAD_F(0x0400484f) /* 0.250068959 */, 17 },
2618 /* 2437 */ { MAD_F(0x0400d7d7) /* 0.250205842 */, 17 },
2619 /* 2438 */ { MAD_F(0x04016764) /* 0.250342744 */, 17 },
2620 /* 2439 */ { MAD_F(0x0401f6f7) /* 0.250479665 */, 17 },
2621 /* 2440 */ { MAD_F(0x0402868e) /* 0.250616605 */, 17 },
2622 /* 2441 */ { MAD_F(0x0403162b) /* 0.250753563 */, 17 },
2623 /* 2442 */ { MAD_F(0x0403a5cc) /* 0.250890540 */, 17 },
2624 /* 2443 */ { MAD_F(0x04043573) /* 0.251027536 */, 17 },
2625 /* 2444 */ { MAD_F(0x0404c51e) /* 0.251164550 */, 17 },
2626 /* 2445 */ { MAD_F(0x040554cf) /* 0.251301583 */, 17 },
2627 /* 2446 */ { MAD_F(0x0405e484) /* 0.251438635 */, 17 },
2628 /* 2447 */ { MAD_F(0x0406743f) /* 0.251575706 */, 17 },
2629
2630 /* 2448 */ { MAD_F(0x040703ff) /* 0.251712795 */, 17 },
2631 /* 2449 */ { MAD_F(0x040793c3) /* 0.251849903 */, 17 },
2632 /* 2450 */ { MAD_F(0x0408238d) /* 0.251987029 */, 17 },
2633 /* 2451 */ { MAD_F(0x0408b35b) /* 0.252124174 */, 17 },
2634 /* 2452 */ { MAD_F(0x0409432f) /* 0.252261338 */, 17 },
2635 /* 2453 */ { MAD_F(0x0409d308) /* 0.252398520 */, 17 },
2636 /* 2454 */ { MAD_F(0x040a62e5) /* 0.252535721 */, 17 },
2637 /* 2455 */ { MAD_F(0x040af2c8) /* 0.252672941 */, 17 },
2638 /* 2456 */ { MAD_F(0x040b82b0) /* 0.252810180 */, 17 },
2639 /* 2457 */ { MAD_F(0x040c129c) /* 0.252947436 */, 17 },
2640 /* 2458 */ { MAD_F(0x040ca28e) /* 0.253084712 */, 17 },
2641 /* 2459 */ { MAD_F(0x040d3284) /* 0.253222006 */, 17 },
2642 /* 2460 */ { MAD_F(0x040dc280) /* 0.253359319 */, 17 },
2643 /* 2461 */ { MAD_F(0x040e5281) /* 0.253496651 */, 17 },
2644 /* 2462 */ { MAD_F(0x040ee286) /* 0.253634001 */, 17 },
2645 /* 2463 */ { MAD_F(0x040f7291) /* 0.253771369 */, 17 },
2646
2647 /* 2464 */ { MAD_F(0x041002a1) /* 0.253908756 */, 17 },
2648 /* 2465 */ { MAD_F(0x041092b5) /* 0.254046162 */, 17 },
2649 /* 2466 */ { MAD_F(0x041122cf) /* 0.254183587 */, 17 },
2650 /* 2467 */ { MAD_F(0x0411b2ed) /* 0.254321030 */, 17 },
2651 /* 2468 */ { MAD_F(0x04124311) /* 0.254458491 */, 17 },
2652 /* 2469 */ { MAD_F(0x0412d339) /* 0.254595971 */, 17 },
2653 /* 2470 */ { MAD_F(0x04136367) /* 0.254733470 */, 17 },
2654 /* 2471 */ { MAD_F(0x0413f399) /* 0.254870987 */, 17 },
2655 /* 2472 */ { MAD_F(0x041483d1) /* 0.255008523 */, 17 },
2656 /* 2473 */ { MAD_F(0x0415140d) /* 0.255146077 */, 17 },
2657 /* 2474 */ { MAD_F(0x0415a44f) /* 0.255283650 */, 17 },
2658 /* 2475 */ { MAD_F(0x04163495) /* 0.255421241 */, 17 },
2659 /* 2476 */ { MAD_F(0x0416c4e1) /* 0.255558851 */, 17 },
2660 /* 2477 */ { MAD_F(0x04175531) /* 0.255696480 */, 17 },
2661 /* 2478 */ { MAD_F(0x0417e586) /* 0.255834127 */, 17 },
2662 /* 2479 */ { MAD_F(0x041875e1) /* 0.255971792 */, 17 },
2663
2664 /* 2480 */ { MAD_F(0x04190640) /* 0.256109476 */, 17 },
2665 /* 2481 */ { MAD_F(0x041996a4) /* 0.256247179 */, 17 },
2666 /* 2482 */ { MAD_F(0x041a270d) /* 0.256384900 */, 17 },
2667 /* 2483 */ { MAD_F(0x041ab77b) /* 0.256522639 */, 17 },
2668 /* 2484 */ { MAD_F(0x041b47ef) /* 0.256660397 */, 17 },
2669 /* 2485 */ { MAD_F(0x041bd867) /* 0.256798174 */, 17 },
2670 /* 2486 */ { MAD_F(0x041c68e4) /* 0.256935969 */, 17 },
2671 /* 2487 */ { MAD_F(0x041cf966) /* 0.257073782 */, 17 },
2672 /* 2488 */ { MAD_F(0x041d89ed) /* 0.257211614 */, 17 },
2673 /* 2489 */ { MAD_F(0x041e1a79) /* 0.257349465 */, 17 },
2674 /* 2490 */ { MAD_F(0x041eab0a) /* 0.257487334 */, 17 },
2675 /* 2491 */ { MAD_F(0x041f3b9f) /* 0.257625221 */, 17 },
2676 /* 2492 */ { MAD_F(0x041fcc3a) /* 0.257763127 */, 17 },
2677 /* 2493 */ { MAD_F(0x04205cda) /* 0.257901051 */, 17 },
2678 /* 2494 */ { MAD_F(0x0420ed7f) /* 0.258038994 */, 17 },
2679 /* 2495 */ { MAD_F(0x04217e28) /* 0.258176955 */, 17 },
2680
2681 /* 2496 */ { MAD_F(0x04220ed7) /* 0.258314934 */, 17 },
2682 /* 2497 */ { MAD_F(0x04229f8a) /* 0.258452932 */, 17 },
2683 /* 2498 */ { MAD_F(0x04233043) /* 0.258590948 */, 17 },
2684 /* 2499 */ { MAD_F(0x0423c100) /* 0.258728983 */, 17 },
2685 /* 2500 */ { MAD_F(0x042451c3) /* 0.258867036 */, 17 },
2686 /* 2501 */ { MAD_F(0x0424e28a) /* 0.259005108 */, 17 },
2687 /* 2502 */ { MAD_F(0x04257356) /* 0.259143198 */, 17 },
2688 /* 2503 */ { MAD_F(0x04260428) /* 0.259281307 */, 17 },
2689 /* 2504 */ { MAD_F(0x042694fe) /* 0.259419433 */, 17 },
2690 /* 2505 */ { MAD_F(0x042725d9) /* 0.259557579 */, 17 },
2691 /* 2506 */ { MAD_F(0x0427b6b9) /* 0.259695742 */, 17 },
2692 /* 2507 */ { MAD_F(0x0428479e) /* 0.259833924 */, 17 },
2693 /* 2508 */ { MAD_F(0x0428d888) /* 0.259972124 */, 17 },
2694 /* 2509 */ { MAD_F(0x04296976) /* 0.260110343 */, 17 },
2695 /* 2510 */ { MAD_F(0x0429fa6a) /* 0.260248580 */, 17 },
2696 /* 2511 */ { MAD_F(0x042a8b63) /* 0.260386836 */, 17 },
2697
2698 /* 2512 */ { MAD_F(0x042b1c60) /* 0.260525110 */, 17 },
2699 /* 2513 */ { MAD_F(0x042bad63) /* 0.260663402 */, 17 },
2700 /* 2514 */ { MAD_F(0x042c3e6a) /* 0.260801712 */, 17 },
2701 /* 2515 */ { MAD_F(0x042ccf77) /* 0.260940041 */, 17 },
2702 /* 2516 */ { MAD_F(0x042d6088) /* 0.261078388 */, 17 },
2703 /* 2517 */ { MAD_F(0x042df19e) /* 0.261216754 */, 17 },
2704 /* 2518 */ { MAD_F(0x042e82b9) /* 0.261355137 */, 17 },
2705 /* 2519 */ { MAD_F(0x042f13d9) /* 0.261493540 */, 17 },
2706 /* 2520 */ { MAD_F(0x042fa4fe) /* 0.261631960 */, 17 },
2707 /* 2521 */ { MAD_F(0x04303628) /* 0.261770399 */, 17 },
2708 /* 2522 */ { MAD_F(0x0430c757) /* 0.261908856 */, 17 },
2709 /* 2523 */ { MAD_F(0x0431588b) /* 0.262047331 */, 17 },
2710 /* 2524 */ { MAD_F(0x0431e9c3) /* 0.262185825 */, 17 },
2711 /* 2525 */ { MAD_F(0x04327b01) /* 0.262324337 */, 17 },
2712 /* 2526 */ { MAD_F(0x04330c43) /* 0.262462867 */, 17 },
2713 /* 2527 */ { MAD_F(0x04339d8a) /* 0.262601416 */, 17 },
2714
2715 /* 2528 */ { MAD_F(0x04342ed7) /* 0.262739982 */, 17 },
2716 /* 2529 */ { MAD_F(0x0434c028) /* 0.262878568 */, 17 },
2717 /* 2530 */ { MAD_F(0x0435517e) /* 0.263017171 */, 17 },
2718 /* 2531 */ { MAD_F(0x0435e2d9) /* 0.263155792 */, 17 },
2719 /* 2532 */ { MAD_F(0x04367439) /* 0.263294432 */, 17 },
2720 /* 2533 */ { MAD_F(0x0437059e) /* 0.263433090 */, 17 },
2721 /* 2534 */ { MAD_F(0x04379707) /* 0.263571767 */, 17 },
2722 /* 2535 */ { MAD_F(0x04382876) /* 0.263710461 */, 17 },
2723 /* 2536 */ { MAD_F(0x0438b9e9) /* 0.263849174 */, 17 },
2724 /* 2537 */ { MAD_F(0x04394b61) /* 0.263987905 */, 17 },
2725 /* 2538 */ { MAD_F(0x0439dcdf) /* 0.264126655 */, 17 },
2726 /* 2539 */ { MAD_F(0x043a6e61) /* 0.264265422 */, 17 },
2727 /* 2540 */ { MAD_F(0x043affe8) /* 0.264404208 */, 17 },
2728 /* 2541 */ { MAD_F(0x043b9174) /* 0.264543012 */, 17 },
2729 /* 2542 */ { MAD_F(0x043c2305) /* 0.264681834 */, 17 },
2730 /* 2543 */ { MAD_F(0x043cb49a) /* 0.264820674 */, 17 },
2731
2732 /* 2544 */ { MAD_F(0x043d4635) /* 0.264959533 */, 17 },
2733 /* 2545 */ { MAD_F(0x043dd7d4) /* 0.265098410 */, 17 },
2734 /* 2546 */ { MAD_F(0x043e6979) /* 0.265237305 */, 17 },
2735 /* 2547 */ { MAD_F(0x043efb22) /* 0.265376218 */, 17 },
2736 /* 2548 */ { MAD_F(0x043f8cd0) /* 0.265515149 */, 17 },
2737 /* 2549 */ { MAD_F(0x04401e83) /* 0.265654099 */, 17 },
2738 /* 2550 */ { MAD_F(0x0440b03b) /* 0.265793066 */, 17 },
2739 /* 2551 */ { MAD_F(0x044141f7) /* 0.265932052 */, 17 },
2740 /* 2552 */ { MAD_F(0x0441d3b9) /* 0.266071056 */, 17 },
2741 /* 2553 */ { MAD_F(0x04426580) /* 0.266210078 */, 17 },
2742 /* 2554 */ { MAD_F(0x0442f74b) /* 0.266349119 */, 17 },
2743 /* 2555 */ { MAD_F(0x0443891b) /* 0.266488177 */, 17 },
2744 /* 2556 */ { MAD_F(0x04441af0) /* 0.266627254 */, 17 },
2745 /* 2557 */ { MAD_F(0x0444acca) /* 0.266766349 */, 17 },
2746 /* 2558 */ { MAD_F(0x04453ea9) /* 0.266905462 */, 17 },
2747 /* 2559 */ { MAD_F(0x0445d08d) /* 0.267044593 */, 17 },
2748
2749 /* 2560 */ { MAD_F(0x04466275) /* 0.267183742 */, 17 },
2750 /* 2561 */ { MAD_F(0x0446f463) /* 0.267322909 */, 17 },
2751 /* 2562 */ { MAD_F(0x04478655) /* 0.267462094 */, 17 },
2752 /* 2563 */ { MAD_F(0x0448184c) /* 0.267601298 */, 17 },
2753 /* 2564 */ { MAD_F(0x0448aa48) /* 0.267740519 */, 17 },
2754 /* 2565 */ { MAD_F(0x04493c49) /* 0.267879759 */, 17 },
2755 /* 2566 */ { MAD_F(0x0449ce4f) /* 0.268019017 */, 17 },
2756 /* 2567 */ { MAD_F(0x044a6059) /* 0.268158293 */, 17 },
2757 /* 2568 */ { MAD_F(0x044af269) /* 0.268297587 */, 17 },
2758 /* 2569 */ { MAD_F(0x044b847d) /* 0.268436899 */, 17 },
2759 /* 2570 */ { MAD_F(0x044c1696) /* 0.268576229 */, 17 },
2760 /* 2571 */ { MAD_F(0x044ca8b4) /* 0.268715577 */, 17 },
2761 /* 2572 */ { MAD_F(0x044d3ad7) /* 0.268854943 */, 17 },
2762 /* 2573 */ { MAD_F(0x044dccff) /* 0.268994328 */, 17 },
2763 /* 2574 */ { MAD_F(0x044e5f2b) /* 0.269133730 */, 17 },
2764 /* 2575 */ { MAD_F(0x044ef15d) /* 0.269273150 */, 17 },
2765
2766 /* 2576 */ { MAD_F(0x044f8393) /* 0.269412589 */, 17 },
2767 /* 2577 */ { MAD_F(0x045015ce) /* 0.269552045 */, 17 },
2768 /* 2578 */ { MAD_F(0x0450a80e) /* 0.269691520 */, 17 },
2769 /* 2579 */ { MAD_F(0x04513a53) /* 0.269831013 */, 17 },
2770 /* 2580 */ { MAD_F(0x0451cc9c) /* 0.269970523 */, 17 },
2771 /* 2581 */ { MAD_F(0x04525eeb) /* 0.270110052 */, 17 },
2772 /* 2582 */ { MAD_F(0x0452f13e) /* 0.270249599 */, 17 },
2773 /* 2583 */ { MAD_F(0x04538396) /* 0.270389163 */, 17 },
2774 /* 2584 */ { MAD_F(0x045415f3) /* 0.270528746 */, 17 },
2775 /* 2585 */ { MAD_F(0x0454a855) /* 0.270668347 */, 17 },
2776 /* 2586 */ { MAD_F(0x04553abb) /* 0.270807965 */, 17 },
2777 /* 2587 */ { MAD_F(0x0455cd27) /* 0.270947602 */, 17 },
2778 /* 2588 */ { MAD_F(0x04565f97) /* 0.271087257 */, 17 },
2779 /* 2589 */ { MAD_F(0x0456f20c) /* 0.271226930 */, 17 },
2780 /* 2590 */ { MAD_F(0x04578486) /* 0.271366620 */, 17 },
2781 /* 2591 */ { MAD_F(0x04581705) /* 0.271506329 */, 17 },
2782
2783 /* 2592 */ { MAD_F(0x0458a989) /* 0.271646056 */, 17 },
2784 /* 2593 */ { MAD_F(0x04593c11) /* 0.271785800 */, 17 },
2785 /* 2594 */ { MAD_F(0x0459ce9e) /* 0.271925563 */, 17 },
2786 /* 2595 */ { MAD_F(0x045a6130) /* 0.272065343 */, 17 },
2787 /* 2596 */ { MAD_F(0x045af3c7) /* 0.272205142 */, 17 },
2788 /* 2597 */ { MAD_F(0x045b8663) /* 0.272344958 */, 17 },
2789 /* 2598 */ { MAD_F(0x045c1903) /* 0.272484793 */, 17 },
2790 /* 2599 */ { MAD_F(0x045caba9) /* 0.272624645 */, 17 },
2791 /* 2600 */ { MAD_F(0x045d3e53) /* 0.272764515 */, 17 },
2792 /* 2601 */ { MAD_F(0x045dd102) /* 0.272904403 */, 17 },
2793 /* 2602 */ { MAD_F(0x045e63b6) /* 0.273044310 */, 17 },
2794 /* 2603 */ { MAD_F(0x045ef66e) /* 0.273184234 */, 17 },
2795 /* 2604 */ { MAD_F(0x045f892b) /* 0.273324176 */, 17 },
2796 /* 2605 */ { MAD_F(0x04601bee) /* 0.273464136 */, 17 },
2797 /* 2606 */ { MAD_F(0x0460aeb5) /* 0.273604113 */, 17 },
2798 /* 2607 */ { MAD_F(0x04614180) /* 0.273744109 */, 17 },
2799
2800 /* 2608 */ { MAD_F(0x0461d451) /* 0.273884123 */, 17 },
2801 /* 2609 */ { MAD_F(0x04626727) /* 0.274024154 */, 17 },
2802 /* 2610 */ { MAD_F(0x0462fa01) /* 0.274164204 */, 17 },
2803 /* 2611 */ { MAD_F(0x04638ce0) /* 0.274304271 */, 17 },
2804 /* 2612 */ { MAD_F(0x04641fc4) /* 0.274444356 */, 17 },
2805 /* 2613 */ { MAD_F(0x0464b2ac) /* 0.274584459 */, 17 },
2806 /* 2614 */ { MAD_F(0x0465459a) /* 0.274724580 */, 17 },
2807 /* 2615 */ { MAD_F(0x0465d88c) /* 0.274864719 */, 17 },
2808 /* 2616 */ { MAD_F(0x04666b83) /* 0.275004875 */, 17 },
2809 /* 2617 */ { MAD_F(0x0466fe7f) /* 0.275145050 */, 17 },
2810 /* 2618 */ { MAD_F(0x0467917f) /* 0.275285242 */, 17 },
2811 /* 2619 */ { MAD_F(0x04682485) /* 0.275425452 */, 17 },
2812 /* 2620 */ { MAD_F(0x0468b78f) /* 0.275565681 */, 17 },
2813 /* 2621 */ { MAD_F(0x04694a9e) /* 0.275705926 */, 17 },
2814 /* 2622 */ { MAD_F(0x0469ddb2) /* 0.275846190 */, 17 },
2815 /* 2623 */ { MAD_F(0x046a70ca) /* 0.275986472 */, 17 },
2816
2817 /* 2624 */ { MAD_F(0x046b03e7) /* 0.276126771 */, 17 },
2818 /* 2625 */ { MAD_F(0x046b970a) /* 0.276267088 */, 17 },
2819 /* 2626 */ { MAD_F(0x046c2a31) /* 0.276407423 */, 17 },
2820 /* 2627 */ { MAD_F(0x046cbd5c) /* 0.276547776 */, 17 },
2821 /* 2628 */ { MAD_F(0x046d508d) /* 0.276688147 */, 17 },
2822 /* 2629 */ { MAD_F(0x046de3c2) /* 0.276828535 */, 17 },
2823 /* 2630 */ { MAD_F(0x046e76fc) /* 0.276968942 */, 17 },
2824 /* 2631 */ { MAD_F(0x046f0a3b) /* 0.277109366 */, 17 },
2825 /* 2632 */ { MAD_F(0x046f9d7e) /* 0.277249808 */, 17 },
2826 /* 2633 */ { MAD_F(0x047030c7) /* 0.277390267 */, 17 },
2827 /* 2634 */ { MAD_F(0x0470c414) /* 0.277530745 */, 17 },
2828 /* 2635 */ { MAD_F(0x04715766) /* 0.277671240 */, 17 },
2829 /* 2636 */ { MAD_F(0x0471eabc) /* 0.277811753 */, 17 },
2830 /* 2637 */ { MAD_F(0x04727e18) /* 0.277952284 */, 17 },
2831 /* 2638 */ { MAD_F(0x04731178) /* 0.278092832 */, 17 },
2832 /* 2639 */ { MAD_F(0x0473a4dd) /* 0.278233399 */, 17 },
2833
2834 /* 2640 */ { MAD_F(0x04743847) /* 0.278373983 */, 17 },
2835 /* 2641 */ { MAD_F(0x0474cbb5) /* 0.278514584 */, 17 },
2836 /* 2642 */ { MAD_F(0x04755f29) /* 0.278655204 */, 17 },
2837 /* 2643 */ { MAD_F(0x0475f2a1) /* 0.278795841 */, 17 },
2838 /* 2644 */ { MAD_F(0x0476861d) /* 0.278936496 */, 17 },
2839 /* 2645 */ { MAD_F(0x0477199f) /* 0.279077169 */, 17 },
2840 /* 2646 */ { MAD_F(0x0477ad25) /* 0.279217860 */, 17 },
2841 /* 2647 */ { MAD_F(0x047840b0) /* 0.279358568 */, 17 },
2842 /* 2648 */ { MAD_F(0x0478d440) /* 0.279499294 */, 17 },
2843 /* 2649 */ { MAD_F(0x047967d5) /* 0.279640037 */, 17 },
2844 /* 2650 */ { MAD_F(0x0479fb6e) /* 0.279780799 */, 17 },
2845 /* 2651 */ { MAD_F(0x047a8f0c) /* 0.279921578 */, 17 },
2846 /* 2652 */ { MAD_F(0x047b22af) /* 0.280062375 */, 17 },
2847 /* 2653 */ { MAD_F(0x047bb657) /* 0.280203189 */, 17 },
2848 /* 2654 */ { MAD_F(0x047c4a03) /* 0.280344021 */, 17 },
2849 /* 2655 */ { MAD_F(0x047cddb4) /* 0.280484871 */, 17 },
2850
2851 /* 2656 */ { MAD_F(0x047d716a) /* 0.280625739 */, 17 },
2852 /* 2657 */ { MAD_F(0x047e0524) /* 0.280766624 */, 17 },
2853 /* 2658 */ { MAD_F(0x047e98e4) /* 0.280907527 */, 17 },
2854 /* 2659 */ { MAD_F(0x047f2ca8) /* 0.281048447 */, 17 },
2855 /* 2660 */ { MAD_F(0x047fc071) /* 0.281189385 */, 17 },
2856 /* 2661 */ { MAD_F(0x0480543e) /* 0.281330341 */, 17 },
2857 /* 2662 */ { MAD_F(0x0480e811) /* 0.281471315 */, 17 },
2858 /* 2663 */ { MAD_F(0x04817be8) /* 0.281612306 */, 17 },
2859 /* 2664 */ { MAD_F(0x04820fc3) /* 0.281753315 */, 17 },
2860 /* 2665 */ { MAD_F(0x0482a3a4) /* 0.281894341 */, 17 },
2861 /* 2666 */ { MAD_F(0x04833789) /* 0.282035386 */, 17 },
2862 /* 2667 */ { MAD_F(0x0483cb73) /* 0.282176447 */, 17 },
2863 /* 2668 */ { MAD_F(0x04845f62) /* 0.282317527 */, 17 },
2864 /* 2669 */ { MAD_F(0x0484f355) /* 0.282458624 */, 17 },
2865 /* 2670 */ { MAD_F(0x0485874d) /* 0.282599738 */, 17 },
2866 /* 2671 */ { MAD_F(0x04861b4a) /* 0.282740871 */, 17 },
2867
2868 /* 2672 */ { MAD_F(0x0486af4c) /* 0.282882021 */, 17 },
2869 /* 2673 */ { MAD_F(0x04874352) /* 0.283023188 */, 17 },
2870 /* 2674 */ { MAD_F(0x0487d75d) /* 0.283164373 */, 17 },
2871 /* 2675 */ { MAD_F(0x04886b6d) /* 0.283305576 */, 17 },
2872 /* 2676 */ { MAD_F(0x0488ff82) /* 0.283446796 */, 17 },
2873 /* 2677 */ { MAD_F(0x0489939b) /* 0.283588034 */, 17 },
2874 /* 2678 */ { MAD_F(0x048a27b9) /* 0.283729290 */, 17 },
2875 /* 2679 */ { MAD_F(0x048abbdc) /* 0.283870563 */, 17 },
2876 /* 2680 */ { MAD_F(0x048b5003) /* 0.284011853 */, 17 },
2877 /* 2681 */ { MAD_F(0x048be42f) /* 0.284153161 */, 17 },
2878 /* 2682 */ { MAD_F(0x048c7860) /* 0.284294487 */, 17 },
2879 /* 2683 */ { MAD_F(0x048d0c96) /* 0.284435831 */, 17 },
2880 /* 2684 */ { MAD_F(0x048da0d0) /* 0.284577192 */, 17 },
2881 /* 2685 */ { MAD_F(0x048e350f) /* 0.284718570 */, 17 },
2882 /* 2686 */ { MAD_F(0x048ec953) /* 0.284859966 */, 17 },
2883 /* 2687 */ { MAD_F(0x048f5d9b) /* 0.285001380 */, 17 },
2884
2885 /* 2688 */ { MAD_F(0x048ff1e8) /* 0.285142811 */, 17 },
2886 /* 2689 */ { MAD_F(0x0490863a) /* 0.285284259 */, 17 },
2887 /* 2690 */ { MAD_F(0x04911a91) /* 0.285425726 */, 17 },
2888 /* 2691 */ { MAD_F(0x0491aeec) /* 0.285567209 */, 17 },
2889 /* 2692 */ { MAD_F(0x0492434c) /* 0.285708711 */, 17 },
2890 /* 2693 */ { MAD_F(0x0492d7b0) /* 0.285850229 */, 17 },
2891 /* 2694 */ { MAD_F(0x04936c1a) /* 0.285991766 */, 17 },
2892 /* 2695 */ { MAD_F(0x04940088) /* 0.286133319 */, 17 },
2893 /* 2696 */ { MAD_F(0x049494fb) /* 0.286274891 */, 17 },
2894 /* 2697 */ { MAD_F(0x04952972) /* 0.286416480 */, 17 },
2895 /* 2698 */ { MAD_F(0x0495bdee) /* 0.286558086 */, 17 },
2896 /* 2699 */ { MAD_F(0x0496526f) /* 0.286699710 */, 17 },
2897 /* 2700 */ { MAD_F(0x0496e6f5) /* 0.286841351 */, 17 },
2898 /* 2701 */ { MAD_F(0x04977b7f) /* 0.286983010 */, 17 },
2899 /* 2702 */ { MAD_F(0x0498100e) /* 0.287124686 */, 17 },
2900 /* 2703 */ { MAD_F(0x0498a4a1) /* 0.287266380 */, 17 },
2901
2902 /* 2704 */ { MAD_F(0x0499393a) /* 0.287408091 */, 17 },
2903 /* 2705 */ { MAD_F(0x0499cdd7) /* 0.287549820 */, 17 },
2904 /* 2706 */ { MAD_F(0x049a6278) /* 0.287691566 */, 17 },
2905 /* 2707 */ { MAD_F(0x049af71f) /* 0.287833330 */, 17 },
2906 /* 2708 */ { MAD_F(0x049b8bca) /* 0.287975111 */, 17 },
2907 /* 2709 */ { MAD_F(0x049c207a) /* 0.288116909 */, 17 },
2908 /* 2710 */ { MAD_F(0x049cb52e) /* 0.288258725 */, 17 },
2909 /* 2711 */ { MAD_F(0x049d49e7) /* 0.288400559 */, 17 },
2910 /* 2712 */ { MAD_F(0x049ddea5) /* 0.288542409 */, 17 },
2911 /* 2713 */ { MAD_F(0x049e7367) /* 0.288684278 */, 17 },
2912 /* 2714 */ { MAD_F(0x049f082f) /* 0.288826163 */, 17 },
2913 /* 2715 */ { MAD_F(0x049f9cfa) /* 0.288968067 */, 17 },
2914 /* 2716 */ { MAD_F(0x04a031cb) /* 0.289109987 */, 17 },
2915 /* 2717 */ { MAD_F(0x04a0c6a0) /* 0.289251925 */, 17 },
2916 /* 2718 */ { MAD_F(0x04a15b7a) /* 0.289393881 */, 17 },
2917 /* 2719 */ { MAD_F(0x04a1f059) /* 0.289535854 */, 17 },
2918
2919 /* 2720 */ { MAD_F(0x04a2853c) /* 0.289677844 */, 17 },
2920 /* 2721 */ { MAD_F(0x04a31a24) /* 0.289819851 */, 17 },
2921 /* 2722 */ { MAD_F(0x04a3af10) /* 0.289961876 */, 17 },
2922 /* 2723 */ { MAD_F(0x04a44401) /* 0.290103919 */, 17 },
2923 /* 2724 */ { MAD_F(0x04a4d8f7) /* 0.290245979 */, 17 },
2924 /* 2725 */ { MAD_F(0x04a56df2) /* 0.290388056 */, 17 },
2925 /* 2726 */ { MAD_F(0x04a602f1) /* 0.290530150 */, 17 },
2926 /* 2727 */ { MAD_F(0x04a697f5) /* 0.290672262 */, 17 },
2927 /* 2728 */ { MAD_F(0x04a72cfe) /* 0.290814392 */, 17 },
2928 /* 2729 */ { MAD_F(0x04a7c20b) /* 0.290956538 */, 17 },
2929 /* 2730 */ { MAD_F(0x04a8571d) /* 0.291098703 */, 17 },
2930 /* 2731 */ { MAD_F(0x04a8ec33) /* 0.291240884 */, 17 },
2931 /* 2732 */ { MAD_F(0x04a9814e) /* 0.291383083 */, 17 },
2932 /* 2733 */ { MAD_F(0x04aa166e) /* 0.291525299 */, 17 },
2933 /* 2734 */ { MAD_F(0x04aaab93) /* 0.291667532 */, 17 },
2934 /* 2735 */ { MAD_F(0x04ab40bc) /* 0.291809783 */, 17 },
2935
2936 /* 2736 */ { MAD_F(0x04abd5ea) /* 0.291952051 */, 17 },
2937 /* 2737 */ { MAD_F(0x04ac6b1c) /* 0.292094337 */, 17 },
2938 /* 2738 */ { MAD_F(0x04ad0053) /* 0.292236640 */, 17 },
2939 /* 2739 */ { MAD_F(0x04ad958f) /* 0.292378960 */, 17 },
2940 /* 2740 */ { MAD_F(0x04ae2ad0) /* 0.292521297 */, 17 },
2941 /* 2741 */ { MAD_F(0x04aec015) /* 0.292663652 */, 17 },
2942 /* 2742 */ { MAD_F(0x04af555e) /* 0.292806024 */, 17 },
2943 /* 2743 */ { MAD_F(0x04afeaad) /* 0.292948414 */, 17 },
2944 /* 2744 */ { MAD_F(0x04b08000) /* 0.293090820 */, 17 },
2945 /* 2745 */ { MAD_F(0x04b11557) /* 0.293233244 */, 17 },
2946 /* 2746 */ { MAD_F(0x04b1aab4) /* 0.293375686 */, 17 },
2947 /* 2747 */ { MAD_F(0x04b24015) /* 0.293518144 */, 17 },
2948 /* 2748 */ { MAD_F(0x04b2d57a) /* 0.293660620 */, 17 },
2949 /* 2749 */ { MAD_F(0x04b36ae4) /* 0.293803113 */, 17 },
2950 /* 2750 */ { MAD_F(0x04b40053) /* 0.293945624 */, 17 },
2951 /* 2751 */ { MAD_F(0x04b495c7) /* 0.294088151 */, 17 },
2952
2953 /* 2752 */ { MAD_F(0x04b52b3f) /* 0.294230696 */, 17 },
2954 /* 2753 */ { MAD_F(0x04b5c0bc) /* 0.294373259 */, 17 },
2955 /* 2754 */ { MAD_F(0x04b6563d) /* 0.294515838 */, 17 },
2956 /* 2755 */ { MAD_F(0x04b6ebc3) /* 0.294658435 */, 17 },
2957 /* 2756 */ { MAD_F(0x04b7814e) /* 0.294801049 */, 17 },
2958 /* 2757 */ { MAD_F(0x04b816dd) /* 0.294943680 */, 17 },
2959 /* 2758 */ { MAD_F(0x04b8ac71) /* 0.295086329 */, 17 },
2960 /* 2759 */ { MAD_F(0x04b9420a) /* 0.295228995 */, 17 },
2961 /* 2760 */ { MAD_F(0x04b9d7a7) /* 0.295371678 */, 17 },
2962 /* 2761 */ { MAD_F(0x04ba6d49) /* 0.295514378 */, 17 },
2963 /* 2762 */ { MAD_F(0x04bb02ef) /* 0.295657095 */, 17 },
2964 /* 2763 */ { MAD_F(0x04bb989a) /* 0.295799830 */, 17 },
2965 /* 2764 */ { MAD_F(0x04bc2e4a) /* 0.295942582 */, 17 },
2966 /* 2765 */ { MAD_F(0x04bcc3fe) /* 0.296085351 */, 17 },
2967 /* 2766 */ { MAD_F(0x04bd59b7) /* 0.296228138 */, 17 },
2968 /* 2767 */ { MAD_F(0x04bdef74) /* 0.296370941 */, 17 },
2969
2970 /* 2768 */ { MAD_F(0x04be8537) /* 0.296513762 */, 17 },
2971 /* 2769 */ { MAD_F(0x04bf1afd) /* 0.296656600 */, 17 },
2972 /* 2770 */ { MAD_F(0x04bfb0c9) /* 0.296799455 */, 17 },
2973 /* 2771 */ { MAD_F(0x04c04699) /* 0.296942327 */, 17 },
2974 /* 2772 */ { MAD_F(0x04c0dc6d) /* 0.297085217 */, 17 },
2975 /* 2773 */ { MAD_F(0x04c17247) /* 0.297228124 */, 17 },
2976 /* 2774 */ { MAD_F(0x04c20824) /* 0.297371048 */, 17 },
2977 /* 2775 */ { MAD_F(0x04c29e07) /* 0.297513989 */, 17 },
2978 /* 2776 */ { MAD_F(0x04c333ee) /* 0.297656947 */, 17 },
2979 /* 2777 */ { MAD_F(0x04c3c9da) /* 0.297799922 */, 17 },
2980 /* 2778 */ { MAD_F(0x04c45fca) /* 0.297942915 */, 17 },
2981 /* 2779 */ { MAD_F(0x04c4f5bf) /* 0.298085925 */, 17 },
2982 /* 2780 */ { MAD_F(0x04c58bb8) /* 0.298228951 */, 17 },
2983 /* 2781 */ { MAD_F(0x04c621b6) /* 0.298371996 */, 17 },
2984 /* 2782 */ { MAD_F(0x04c6b7b9) /* 0.298515057 */, 17 },
2985 /* 2783 */ { MAD_F(0x04c74dc0) /* 0.298658135 */, 17 },
2986
2987 /* 2784 */ { MAD_F(0x04c7e3cc) /* 0.298801231 */, 17 },
2988 /* 2785 */ { MAD_F(0x04c879dd) /* 0.298944343 */, 17 },
2989 /* 2786 */ { MAD_F(0x04c90ff2) /* 0.299087473 */, 17 },
2990 /* 2787 */ { MAD_F(0x04c9a60c) /* 0.299230620 */, 17 },
2991 /* 2788 */ { MAD_F(0x04ca3c2a) /* 0.299373784 */, 17 },
2992 /* 2789 */ { MAD_F(0x04cad24d) /* 0.299516965 */, 17 },
2993 /* 2790 */ { MAD_F(0x04cb6874) /* 0.299660163 */, 17 },
2994 /* 2791 */ { MAD_F(0x04cbfea0) /* 0.299803378 */, 17 },
2995 /* 2792 */ { MAD_F(0x04cc94d1) /* 0.299946611 */, 17 },
2996 /* 2793 */ { MAD_F(0x04cd2b06) /* 0.300089860 */, 17 },
2997 /* 2794 */ { MAD_F(0x04cdc140) /* 0.300233127 */, 17 },
2998 /* 2795 */ { MAD_F(0x04ce577f) /* 0.300376411 */, 17 },
2999 /* 2796 */ { MAD_F(0x04ceedc2) /* 0.300519711 */, 17 },
3000 /* 2797 */ { MAD_F(0x04cf8409) /* 0.300663029 */, 17 },
3001 /* 2798 */ { MAD_F(0x04d01a55) /* 0.300806364 */, 17 },
3002 /* 2799 */ { MAD_F(0x04d0b0a6) /* 0.300949716 */, 17 },
3003
3004 /* 2800 */ { MAD_F(0x04d146fb) /* 0.301093085 */, 17 },
3005 /* 2801 */ { MAD_F(0x04d1dd55) /* 0.301236472 */, 17 },
3006 /* 2802 */ { MAD_F(0x04d273b4) /* 0.301379875 */, 17 },
3007 /* 2803 */ { MAD_F(0x04d30a17) /* 0.301523295 */, 17 },
3008 /* 2804 */ { MAD_F(0x04d3a07f) /* 0.301666733 */, 17 },
3009 /* 2805 */ { MAD_F(0x04d436eb) /* 0.301810187 */, 17 },
3010 /* 2806 */ { MAD_F(0x04d4cd5c) /* 0.301953659 */, 17 },
3011 /* 2807 */ { MAD_F(0x04d563d1) /* 0.302097147 */, 17 },
3012 /* 2808 */ { MAD_F(0x04d5fa4b) /* 0.302240653 */, 17 },
3013 /* 2809 */ { MAD_F(0x04d690ca) /* 0.302384175 */, 17 },
3014 /* 2810 */ { MAD_F(0x04d7274d) /* 0.302527715 */, 17 },
3015 /* 2811 */ { MAD_F(0x04d7bdd5) /* 0.302671271 */, 17 },
3016 /* 2812 */ { MAD_F(0x04d85461) /* 0.302814845 */, 17 },
3017 /* 2813 */ { MAD_F(0x04d8eaf2) /* 0.302958436 */, 17 },
3018 /* 2814 */ { MAD_F(0x04d98187) /* 0.303102044 */, 17 },
3019 /* 2815 */ { MAD_F(0x04da1821) /* 0.303245668 */, 17 },
3020
3021 /* 2816 */ { MAD_F(0x04daaec0) /* 0.303389310 */, 17 },
3022 /* 2817 */ { MAD_F(0x04db4563) /* 0.303532969 */, 17 },
3023 /* 2818 */ { MAD_F(0x04dbdc0a) /* 0.303676645 */, 17 },
3024 /* 2819 */ { MAD_F(0x04dc72b7) /* 0.303820337 */, 17 },
3025 /* 2820 */ { MAD_F(0x04dd0967) /* 0.303964047 */, 17 },
3026 /* 2821 */ { MAD_F(0x04dda01d) /* 0.304107774 */, 17 },
3027 /* 2822 */ { MAD_F(0x04de36d7) /* 0.304251517 */, 17 },
3028 /* 2823 */ { MAD_F(0x04decd95) /* 0.304395278 */, 17 },
3029 /* 2824 */ { MAD_F(0x04df6458) /* 0.304539056 */, 17 },
3030 /* 2825 */ { MAD_F(0x04dffb20) /* 0.304682850 */, 17 },
3031 /* 2826 */ { MAD_F(0x04e091ec) /* 0.304826662 */, 17 },
3032 /* 2827 */ { MAD_F(0x04e128bc) /* 0.304970491 */, 17 },
3033 /* 2828 */ { MAD_F(0x04e1bf92) /* 0.305114336 */, 17 },
3034 /* 2829 */ { MAD_F(0x04e2566b) /* 0.305258199 */, 17 },
3035 /* 2830 */ { MAD_F(0x04e2ed4a) /* 0.305402078 */, 17 },
3036 /* 2831 */ { MAD_F(0x04e3842d) /* 0.305545974 */, 17 },
3037
3038 /* 2832 */ { MAD_F(0x04e41b14) /* 0.305689888 */, 17 },
3039 /* 2833 */ { MAD_F(0x04e4b200) /* 0.305833818 */, 17 },
3040 /* 2834 */ { MAD_F(0x04e548f1) /* 0.305977765 */, 17 },
3041 /* 2835 */ { MAD_F(0x04e5dfe6) /* 0.306121729 */, 17 },
3042 /* 2836 */ { MAD_F(0x04e676df) /* 0.306265710 */, 17 },
3043 /* 2837 */ { MAD_F(0x04e70dde) /* 0.306409708 */, 17 },
3044 /* 2838 */ { MAD_F(0x04e7a4e0) /* 0.306553723 */, 17 },
3045 /* 2839 */ { MAD_F(0x04e83be7) /* 0.306697755 */, 17 },
3046 /* 2840 */ { MAD_F(0x04e8d2f3) /* 0.306841804 */, 17 },
3047 /* 2841 */ { MAD_F(0x04e96a04) /* 0.306985869 */, 17 },
3048 /* 2842 */ { MAD_F(0x04ea0118) /* 0.307129952 */, 17 },
3049 /* 2843 */ { MAD_F(0x04ea9832) /* 0.307274051 */, 17 },
3050 /* 2844 */ { MAD_F(0x04eb2f50) /* 0.307418168 */, 17 },
3051 /* 2845 */ { MAD_F(0x04ebc672) /* 0.307562301 */, 17 },
3052 /* 2846 */ { MAD_F(0x04ec5d99) /* 0.307706451 */, 17 },
3053 /* 2847 */ { MAD_F(0x04ecf4c5) /* 0.307850618 */, 17 },
3054
3055 /* 2848 */ { MAD_F(0x04ed8bf5) /* 0.307994802 */, 17 },
3056 /* 2849 */ { MAD_F(0x04ee2329) /* 0.308139003 */, 17 },
3057 /* 2850 */ { MAD_F(0x04eeba63) /* 0.308283220 */, 17 },
3058 /* 2851 */ { MAD_F(0x04ef51a0) /* 0.308427455 */, 17 },
3059 /* 2852 */ { MAD_F(0x04efe8e2) /* 0.308571706 */, 17 },
3060 /* 2853 */ { MAD_F(0x04f08029) /* 0.308715974 */, 17 },
3061 /* 2854 */ { MAD_F(0x04f11774) /* 0.308860260 */, 17 },
3062 /* 2855 */ { MAD_F(0x04f1aec4) /* 0.309004561 */, 17 },
3063 /* 2856 */ { MAD_F(0x04f24618) /* 0.309148880 */, 17 },
3064 /* 2857 */ { MAD_F(0x04f2dd71) /* 0.309293216 */, 17 },
3065 /* 2858 */ { MAD_F(0x04f374cf) /* 0.309437568 */, 17 },
3066 /* 2859 */ { MAD_F(0x04f40c30) /* 0.309581938 */, 17 },
3067 /* 2860 */ { MAD_F(0x04f4a397) /* 0.309726324 */, 17 },
3068 /* 2861 */ { MAD_F(0x04f53b02) /* 0.309870727 */, 17 },
3069 /* 2862 */ { MAD_F(0x04f5d271) /* 0.310015147 */, 17 },
3070 /* 2863 */ { MAD_F(0x04f669e5) /* 0.310159583 */, 17 },
3071
3072 /* 2864 */ { MAD_F(0x04f7015d) /* 0.310304037 */, 17 },
3073 /* 2865 */ { MAD_F(0x04f798da) /* 0.310448507 */, 17 },
3074 /* 2866 */ { MAD_F(0x04f8305c) /* 0.310592994 */, 17 },
3075 /* 2867 */ { MAD_F(0x04f8c7e2) /* 0.310737498 */, 17 },
3076 /* 2868 */ { MAD_F(0x04f95f6c) /* 0.310882018 */, 17 },
3077 /* 2869 */ { MAD_F(0x04f9f6fb) /* 0.311026556 */, 17 },
3078 /* 2870 */ { MAD_F(0x04fa8e8f) /* 0.311171110 */, 17 },
3079 /* 2871 */ { MAD_F(0x04fb2627) /* 0.311315681 */, 17 },
3080 /* 2872 */ { MAD_F(0x04fbbdc3) /* 0.311460269 */, 17 },
3081 /* 2873 */ { MAD_F(0x04fc5564) /* 0.311604874 */, 17 },
3082 /* 2874 */ { MAD_F(0x04fced0a) /* 0.311749495 */, 17 },
3083 /* 2875 */ { MAD_F(0x04fd84b4) /* 0.311894133 */, 17 },
3084 /* 2876 */ { MAD_F(0x04fe1c62) /* 0.312038788 */, 17 },
3085 /* 2877 */ { MAD_F(0x04feb415) /* 0.312183460 */, 17 },
3086 /* 2878 */ { MAD_F(0x04ff4bcd) /* 0.312328148 */, 17 },
3087 /* 2879 */ { MAD_F(0x04ffe389) /* 0.312472854 */, 17 },
3088
3089 /* 2880 */ { MAD_F(0x05007b49) /* 0.312617576 */, 17 },
3090 /* 2881 */ { MAD_F(0x0501130e) /* 0.312762314 */, 17 },
3091 /* 2882 */ { MAD_F(0x0501aad8) /* 0.312907070 */, 17 },
3092 /* 2883 */ { MAD_F(0x050242a6) /* 0.313051842 */, 17 },
3093 /* 2884 */ { MAD_F(0x0502da78) /* 0.313196631 */, 17 },
3094 /* 2885 */ { MAD_F(0x0503724f) /* 0.313341437 */, 17 },
3095 /* 2886 */ { MAD_F(0x05040a2b) /* 0.313486259 */, 17 },
3096 /* 2887 */ { MAD_F(0x0504a20b) /* 0.313631098 */, 17 },
3097 /* 2888 */ { MAD_F(0x050539ef) /* 0.313775954 */, 17 },
3098 /* 2889 */ { MAD_F(0x0505d1d8) /* 0.313920827 */, 17 },
3099 /* 2890 */ { MAD_F(0x050669c5) /* 0.314065716 */, 17 },
3100 /* 2891 */ { MAD_F(0x050701b7) /* 0.314210622 */, 17 },
3101 /* 2892 */ { MAD_F(0x050799ae) /* 0.314355545 */, 17 },
3102 /* 2893 */ { MAD_F(0x050831a9) /* 0.314500484 */, 17 },
3103 /* 2894 */ { MAD_F(0x0508c9a8) /* 0.314645440 */, 17 },
3104 /* 2895 */ { MAD_F(0x050961ac) /* 0.314790413 */, 17 },
3105
3106 /* 2896 */ { MAD_F(0x0509f9b4) /* 0.314935403 */, 17 },
3107 /* 2897 */ { MAD_F(0x050a91c1) /* 0.315080409 */, 17 },
3108 /* 2898 */ { MAD_F(0x050b29d2) /* 0.315225432 */, 17 },
3109 /* 2899 */ { MAD_F(0x050bc1e8) /* 0.315370472 */, 17 },
3110 /* 2900 */ { MAD_F(0x050c5a02) /* 0.315515528 */, 17 },
3111 /* 2901 */ { MAD_F(0x050cf221) /* 0.315660601 */, 17 },
3112 /* 2902 */ { MAD_F(0x050d8a44) /* 0.315805690 */, 17 },
3113 /* 2903 */ { MAD_F(0x050e226c) /* 0.315950797 */, 17 },
3114 /* 2904 */ { MAD_F(0x050eba98) /* 0.316095920 */, 17 },
3115 /* 2905 */ { MAD_F(0x050f52c9) /* 0.316241059 */, 17 },
3116 /* 2906 */ { MAD_F(0x050feafe) /* 0.316386216 */, 17 },
3117 /* 2907 */ { MAD_F(0x05108337) /* 0.316531388 */, 17 },
3118 /* 2908 */ { MAD_F(0x05111b75) /* 0.316676578 */, 17 },
3119 /* 2909 */ { MAD_F(0x0511b3b8) /* 0.316821784 */, 17 },
3120 /* 2910 */ { MAD_F(0x05124bff) /* 0.316967007 */, 17 },
3121 /* 2911 */ { MAD_F(0x0512e44a) /* 0.317112247 */, 17 },
3122
3123 /* 2912 */ { MAD_F(0x05137c9a) /* 0.317257503 */, 17 },
3124 /* 2913 */ { MAD_F(0x051414ee) /* 0.317402775 */, 17 },
3125 /* 2914 */ { MAD_F(0x0514ad47) /* 0.317548065 */, 17 },
3126 /* 2915 */ { MAD_F(0x051545a5) /* 0.317693371 */, 17 },
3127 /* 2916 */ { MAD_F(0x0515de06) /* 0.317838693 */, 17 },
3128 /* 2917 */ { MAD_F(0x0516766d) /* 0.317984033 */, 17 },
3129 /* 2918 */ { MAD_F(0x05170ed7) /* 0.318129388 */, 17 },
3130 /* 2919 */ { MAD_F(0x0517a746) /* 0.318274761 */, 17 },
3131 /* 2920 */ { MAD_F(0x05183fba) /* 0.318420150 */, 17 },
3132 /* 2921 */ { MAD_F(0x0518d832) /* 0.318565555 */, 17 },
3133 /* 2922 */ { MAD_F(0x051970ae) /* 0.318710978 */, 17 },
3134 /* 2923 */ { MAD_F(0x051a092f) /* 0.318856416 */, 17 },
3135 /* 2924 */ { MAD_F(0x051aa1b5) /* 0.319001872 */, 17 },
3136 /* 2925 */ { MAD_F(0x051b3a3f) /* 0.319147344 */, 17 },
3137 /* 2926 */ { MAD_F(0x051bd2cd) /* 0.319292832 */, 17 },
3138 /* 2927 */ { MAD_F(0x051c6b60) /* 0.319438338 */, 17 },
3139
3140 /* 2928 */ { MAD_F(0x051d03f7) /* 0.319583859 */, 17 },
3141 /* 2929 */ { MAD_F(0x051d9c92) /* 0.319729398 */, 17 },
3142 /* 2930 */ { MAD_F(0x051e3532) /* 0.319874952 */, 17 },
3143 /* 2931 */ { MAD_F(0x051ecdd7) /* 0.320020524 */, 17 },
3144 /* 2932 */ { MAD_F(0x051f6680) /* 0.320166112 */, 17 },
3145 /* 2933 */ { MAD_F(0x051fff2d) /* 0.320311716 */, 17 },
3146 /* 2934 */ { MAD_F(0x052097df) /* 0.320457337 */, 17 },
3147 /* 2935 */ { MAD_F(0x05213095) /* 0.320602975 */, 17 },
3148 /* 2936 */ { MAD_F(0x0521c950) /* 0.320748629 */, 17 },
3149 /* 2937 */ { MAD_F(0x0522620f) /* 0.320894300 */, 17 },
3150 /* 2938 */ { MAD_F(0x0522fad3) /* 0.321039987 */, 17 },
3151 /* 2939 */ { MAD_F(0x0523939b) /* 0.321185691 */, 17 },
3152 /* 2940 */ { MAD_F(0x05242c68) /* 0.321331411 */, 17 },
3153 /* 2941 */ { MAD_F(0x0524c538) /* 0.321477148 */, 17 },
3154 /* 2942 */ { MAD_F(0x05255e0e) /* 0.321622901 */, 17 },
3155 /* 2943 */ { MAD_F(0x0525f6e8) /* 0.321768671 */, 17 },
3156
3157 /* 2944 */ { MAD_F(0x05268fc6) /* 0.321914457 */, 17 },
3158 /* 2945 */ { MAD_F(0x052728a9) /* 0.322060260 */, 17 },
3159 /* 2946 */ { MAD_F(0x0527c190) /* 0.322206079 */, 17 },
3160 /* 2947 */ { MAD_F(0x05285a7b) /* 0.322351915 */, 17 },
3161 /* 2948 */ { MAD_F(0x0528f36b) /* 0.322497768 */, 17 },
3162 /* 2949 */ { MAD_F(0x05298c5f) /* 0.322643636 */, 17 },
3163 /* 2950 */ { MAD_F(0x052a2558) /* 0.322789522 */, 17 },
3164 /* 2951 */ { MAD_F(0x052abe55) /* 0.322935424 */, 17 },
3165 /* 2952 */ { MAD_F(0x052b5757) /* 0.323081342 */, 17 },
3166 /* 2953 */ { MAD_F(0x052bf05d) /* 0.323227277 */, 17 },
3167 /* 2954 */ { MAD_F(0x052c8968) /* 0.323373228 */, 17 },
3168 /* 2955 */ { MAD_F(0x052d2277) /* 0.323519196 */, 17 },
3169 /* 2956 */ { MAD_F(0x052dbb8a) /* 0.323665180 */, 17 },
3170 /* 2957 */ { MAD_F(0x052e54a2) /* 0.323811180 */, 17 },
3171 /* 2958 */ { MAD_F(0x052eedbe) /* 0.323957197 */, 17 },
3172 /* 2959 */ { MAD_F(0x052f86de) /* 0.324103231 */, 17 },
3173
3174 /* 2960 */ { MAD_F(0x05302003) /* 0.324249281 */, 17 },
3175 /* 2961 */ { MAD_F(0x0530b92d) /* 0.324395347 */, 17 },
3176 /* 2962 */ { MAD_F(0x0531525b) /* 0.324541430 */, 17 },
3177 /* 2963 */ { MAD_F(0x0531eb8d) /* 0.324687530 */, 17 },
3178 /* 2964 */ { MAD_F(0x053284c4) /* 0.324833646 */, 17 },
3179 /* 2965 */ { MAD_F(0x05331dff) /* 0.324979778 */, 17 },
3180 /* 2966 */ { MAD_F(0x0533b73e) /* 0.325125926 */, 17 },
3181 /* 2967 */ { MAD_F(0x05345082) /* 0.325272091 */, 17 },
3182 /* 2968 */ { MAD_F(0x0534e9ca) /* 0.325418273 */, 17 },
3183 /* 2969 */ { MAD_F(0x05358317) /* 0.325564471 */, 17 },
3184 /* 2970 */ { MAD_F(0x05361c68) /* 0.325710685 */, 17 },
3185 /* 2971 */ { MAD_F(0x0536b5be) /* 0.325856916 */, 17 },
3186 /* 2972 */ { MAD_F(0x05374f17) /* 0.326003163 */, 17 },
3187 /* 2973 */ { MAD_F(0x0537e876) /* 0.326149427 */, 17 },
3188 /* 2974 */ { MAD_F(0x053881d9) /* 0.326295707 */, 17 },
3189 /* 2975 */ { MAD_F(0x05391b40) /* 0.326442003 */, 17 },
3190
3191 /* 2976 */ { MAD_F(0x0539b4ab) /* 0.326588316 */, 17 },
3192 /* 2977 */ { MAD_F(0x053a4e1b) /* 0.326734645 */, 17 },
3193 /* 2978 */ { MAD_F(0x053ae78f) /* 0.326880990 */, 17 },
3194 /* 2979 */ { MAD_F(0x053b8108) /* 0.327027352 */, 17 },
3195 /* 2980 */ { MAD_F(0x053c1a85) /* 0.327173730 */, 17 },
3196 /* 2981 */ { MAD_F(0x053cb407) /* 0.327320125 */, 17 },
3197 /* 2982 */ { MAD_F(0x053d4d8d) /* 0.327466536 */, 17 },
3198 /* 2983 */ { MAD_F(0x053de717) /* 0.327612963 */, 17 },
3199 /* 2984 */ { MAD_F(0x053e80a6) /* 0.327759407 */, 17 },
3200 /* 2985 */ { MAD_F(0x053f1a39) /* 0.327905867 */, 17 },
3201 /* 2986 */ { MAD_F(0x053fb3d0) /* 0.328052344 */, 17 },
3202 /* 2987 */ { MAD_F(0x05404d6c) /* 0.328198837 */, 17 },
3203 /* 2988 */ { MAD_F(0x0540e70c) /* 0.328345346 */, 17 },
3204 /* 2989 */ { MAD_F(0x054180b1) /* 0.328491871 */, 17 },
3205 /* 2990 */ { MAD_F(0x05421a5a) /* 0.328638413 */, 17 },
3206 /* 2991 */ { MAD_F(0x0542b407) /* 0.328784971 */, 17 },
3207
3208 /* 2992 */ { MAD_F(0x05434db9) /* 0.328931546 */, 17 },
3209 /* 2993 */ { MAD_F(0x0543e76f) /* 0.329078137 */, 17 },
3210 /* 2994 */ { MAD_F(0x0544812a) /* 0.329224744 */, 17 },
3211 /* 2995 */ { MAD_F(0x05451ae9) /* 0.329371367 */, 17 },
3212 /* 2996 */ { MAD_F(0x0545b4ac) /* 0.329518007 */, 17 },
3213 /* 2997 */ { MAD_F(0x05464e74) /* 0.329664663 */, 17 },
3214 /* 2998 */ { MAD_F(0x0546e840) /* 0.329811336 */, 17 },
3215 /* 2999 */ { MAD_F(0x05478211) /* 0.329958024 */, 17 },
3216 /* 3000 */ { MAD_F(0x05481be5) /* 0.330104730 */, 17 },
3217 /* 3001 */ { MAD_F(0x0548b5bf) /* 0.330251451 */, 17 },
3218 /* 3002 */ { MAD_F(0x05494f9c) /* 0.330398189 */, 17 },
3219 /* 3003 */ { MAD_F(0x0549e97e) /* 0.330544943 */, 17 },
3220 /* 3004 */ { MAD_F(0x054a8364) /* 0.330691713 */, 17 },
3221 /* 3005 */ { MAD_F(0x054b1d4f) /* 0.330838499 */, 17 },
3222 /* 3006 */ { MAD_F(0x054bb73e) /* 0.330985302 */, 17 },
3223 /* 3007 */ { MAD_F(0x054c5132) /* 0.331132121 */, 17 },
3224
3225 /* 3008 */ { MAD_F(0x054ceb2a) /* 0.331278957 */, 17 },
3226 /* 3009 */ { MAD_F(0x054d8526) /* 0.331425808 */, 17 },
3227 /* 3010 */ { MAD_F(0x054e1f26) /* 0.331572676 */, 17 },
3228 /* 3011 */ { MAD_F(0x054eb92b) /* 0.331719560 */, 17 },
3229 /* 3012 */ { MAD_F(0x054f5334) /* 0.331866461 */, 17 },
3230 /* 3013 */ { MAD_F(0x054fed42) /* 0.332013377 */, 17 },
3231 /* 3014 */ { MAD_F(0x05508754) /* 0.332160310 */, 17 },
3232 /* 3015 */ { MAD_F(0x0551216b) /* 0.332307260 */, 17 },
3233 /* 3016 */ { MAD_F(0x0551bb85) /* 0.332454225 */, 17 },
3234 /* 3017 */ { MAD_F(0x055255a4) /* 0.332601207 */, 17 },
3235 /* 3018 */ { MAD_F(0x0552efc8) /* 0.332748205 */, 17 },
3236 /* 3019 */ { MAD_F(0x055389f0) /* 0.332895219 */, 17 },
3237 /* 3020 */ { MAD_F(0x0554241c) /* 0.333042249 */, 17 },
3238 /* 3021 */ { MAD_F(0x0554be4c) /* 0.333189296 */, 17 },
3239 /* 3022 */ { MAD_F(0x05555881) /* 0.333336359 */, 17 },
3240 /* 3023 */ { MAD_F(0x0555f2ba) /* 0.333483438 */, 17 },
3241
3242 /* 3024 */ { MAD_F(0x05568cf8) /* 0.333630533 */, 17 },
3243 /* 3025 */ { MAD_F(0x0557273a) /* 0.333777645 */, 17 },
3244 /* 3026 */ { MAD_F(0x0557c180) /* 0.333924772 */, 17 },
3245 /* 3027 */ { MAD_F(0x05585bcb) /* 0.334071916 */, 17 },
3246 /* 3028 */ { MAD_F(0x0558f61a) /* 0.334219076 */, 17 },
3247 /* 3029 */ { MAD_F(0x0559906d) /* 0.334366253 */, 17 },
3248 /* 3030 */ { MAD_F(0x055a2ac5) /* 0.334513445 */, 17 },
3249 /* 3031 */ { MAD_F(0x055ac521) /* 0.334660654 */, 17 },
3250 /* 3032 */ { MAD_F(0x055b5f81) /* 0.334807879 */, 17 },
3251 /* 3033 */ { MAD_F(0x055bf9e6) /* 0.334955120 */, 17 },
3252 /* 3034 */ { MAD_F(0x055c944f) /* 0.335102377 */, 17 },
3253 /* 3035 */ { MAD_F(0x055d2ebd) /* 0.335249651 */, 17 },
3254 /* 3036 */ { MAD_F(0x055dc92e) /* 0.335396941 */, 17 },
3255 /* 3037 */ { MAD_F(0x055e63a5) /* 0.335544246 */, 17 },
3256 /* 3038 */ { MAD_F(0x055efe1f) /* 0.335691568 */, 17 },
3257 /* 3039 */ { MAD_F(0x055f989e) /* 0.335838906 */, 17 },
3258
3259 /* 3040 */ { MAD_F(0x05603321) /* 0.335986261 */, 17 },
3260 /* 3041 */ { MAD_F(0x0560cda8) /* 0.336133631 */, 17 },
3261 /* 3042 */ { MAD_F(0x05616834) /* 0.336281018 */, 17 },
3262 /* 3043 */ { MAD_F(0x056202c4) /* 0.336428421 */, 17 },
3263 /* 3044 */ { MAD_F(0x05629d59) /* 0.336575840 */, 17 },
3264 /* 3045 */ { MAD_F(0x056337f2) /* 0.336723275 */, 17 },
3265 /* 3046 */ { MAD_F(0x0563d28f) /* 0.336870726 */, 17 },
3266 /* 3047 */ { MAD_F(0x05646d30) /* 0.337018193 */, 17 },
3267 /* 3048 */ { MAD_F(0x056507d6) /* 0.337165677 */, 17 },
3268 /* 3049 */ { MAD_F(0x0565a280) /* 0.337313176 */, 17 },
3269 /* 3050 */ { MAD_F(0x05663d2f) /* 0.337460692 */, 17 },
3270 /* 3051 */ { MAD_F(0x0566d7e1) /* 0.337608224 */, 17 },
3271 /* 3052 */ { MAD_F(0x05677298) /* 0.337755772 */, 17 },
3272 /* 3053 */ { MAD_F(0x05680d54) /* 0.337903336 */, 17 },
3273 /* 3054 */ { MAD_F(0x0568a814) /* 0.338050916 */, 17 },
3274 /* 3055 */ { MAD_F(0x056942d8) /* 0.338198513 */, 17 },
3275
3276 /* 3056 */ { MAD_F(0x0569dda0) /* 0.338346125 */, 17 },
3277 /* 3057 */ { MAD_F(0x056a786d) /* 0.338493753 */, 17 },
3278 /* 3058 */ { MAD_F(0x056b133e) /* 0.338641398 */, 17 },
3279 /* 3059 */ { MAD_F(0x056bae13) /* 0.338789059 */, 17 },
3280 /* 3060 */ { MAD_F(0x056c48ed) /* 0.338936736 */, 17 },
3281 /* 3061 */ { MAD_F(0x056ce3cb) /* 0.339084429 */, 17 },
3282 /* 3062 */ { MAD_F(0x056d7ead) /* 0.339232138 */, 17 },
3283 /* 3063 */ { MAD_F(0x056e1994) /* 0.339379863 */, 17 },
3284 /* 3064 */ { MAD_F(0x056eb47f) /* 0.339527604 */, 17 },
3285 /* 3065 */ { MAD_F(0x056f4f6e) /* 0.339675361 */, 17 },
3286 /* 3066 */ { MAD_F(0x056fea62) /* 0.339823134 */, 17 },
3287 /* 3067 */ { MAD_F(0x0570855a) /* 0.339970924 */, 17 },
3288 /* 3068 */ { MAD_F(0x05712056) /* 0.340118729 */, 17 },
3289 /* 3069 */ { MAD_F(0x0571bb56) /* 0.340266550 */, 17 },
3290 /* 3070 */ { MAD_F(0x0572565b) /* 0.340414388 */, 17 },
3291 /* 3071 */ { MAD_F(0x0572f164) /* 0.340562242 */, 17 },
3292
3293 /* 3072 */ { MAD_F(0x05738c72) /* 0.340710111 */, 17 },
3294 /* 3073 */ { MAD_F(0x05742784) /* 0.340857997 */, 17 },
3295 /* 3074 */ { MAD_F(0x0574c29a) /* 0.341005899 */, 17 },
3296 /* 3075 */ { MAD_F(0x05755db4) /* 0.341153816 */, 17 },
3297 /* 3076 */ { MAD_F(0x0575f8d3) /* 0.341301750 */, 17 },
3298 /* 3077 */ { MAD_F(0x057693f6) /* 0.341449700 */, 17 },
3299 /* 3078 */ { MAD_F(0x05772f1d) /* 0.341597666 */, 17 },
3300 /* 3079 */ { MAD_F(0x0577ca49) /* 0.341745648 */, 17 },
3301 /* 3080 */ { MAD_F(0x05786578) /* 0.341893646 */, 17 },
3302 /* 3081 */ { MAD_F(0x057900ad) /* 0.342041659 */, 17 },
3303 /* 3082 */ { MAD_F(0x05799be5) /* 0.342189689 */, 17 },
3304 /* 3083 */ { MAD_F(0x057a3722) /* 0.342337735 */, 17 },
3305 /* 3084 */ { MAD_F(0x057ad263) /* 0.342485797 */, 17 },
3306 /* 3085 */ { MAD_F(0x057b6da8) /* 0.342633875 */, 17 },
3307 /* 3086 */ { MAD_F(0x057c08f2) /* 0.342781969 */, 17 },
3308 /* 3087 */ { MAD_F(0x057ca440) /* 0.342930079 */, 17 },
3309
3310 /* 3088 */ { MAD_F(0x057d3f92) /* 0.343078205 */, 17 },
3311 /* 3089 */ { MAD_F(0x057ddae9) /* 0.343226347 */, 17 },
3312 /* 3090 */ { MAD_F(0x057e7644) /* 0.343374505 */, 17 },
3313 /* 3091 */ { MAD_F(0x057f11a3) /* 0.343522679 */, 17 },
3314 /* 3092 */ { MAD_F(0x057fad06) /* 0.343670869 */, 17 },
3315 /* 3093 */ { MAD_F(0x0580486e) /* 0.343819075 */, 17 },
3316 /* 3094 */ { MAD_F(0x0580e3da) /* 0.343967296 */, 17 },
3317 /* 3095 */ { MAD_F(0x05817f4a) /* 0.344115534 */, 17 },
3318 /* 3096 */ { MAD_F(0x05821abf) /* 0.344263788 */, 17 },
3319 /* 3097 */ { MAD_F(0x0582b638) /* 0.344412058 */, 17 },
3320 /* 3098 */ { MAD_F(0x058351b5) /* 0.344560343 */, 17 },
3321 /* 3099 */ { MAD_F(0x0583ed36) /* 0.344708645 */, 17 },
3322 /* 3100 */ { MAD_F(0x058488bc) /* 0.344856963 */, 17 },
3323 /* 3101 */ { MAD_F(0x05852446) /* 0.345005296 */, 17 },
3324 /* 3102 */ { MAD_F(0x0585bfd4) /* 0.345153646 */, 17 },
3325 /* 3103 */ { MAD_F(0x05865b67) /* 0.345302011 */, 17 },
3326
3327 /* 3104 */ { MAD_F(0x0586f6fd) /* 0.345450393 */, 17 },
3328 /* 3105 */ { MAD_F(0x05879298) /* 0.345598790 */, 17 },
3329 /* 3106 */ { MAD_F(0x05882e38) /* 0.345747203 */, 17 },
3330 /* 3107 */ { MAD_F(0x0588c9dc) /* 0.345895632 */, 17 },
3331 /* 3108 */ { MAD_F(0x05896583) /* 0.346044077 */, 17 },
3332 /* 3109 */ { MAD_F(0x058a0130) /* 0.346192538 */, 17 },
3333 /* 3110 */ { MAD_F(0x058a9ce0) /* 0.346341015 */, 17 },
3334 /* 3111 */ { MAD_F(0x058b3895) /* 0.346489508 */, 17 },
3335 /* 3112 */ { MAD_F(0x058bd44e) /* 0.346638017 */, 17 },
3336 /* 3113 */ { MAD_F(0x058c700b) /* 0.346786542 */, 17 },
3337 /* 3114 */ { MAD_F(0x058d0bcd) /* 0.346935082 */, 17 },
3338 /* 3115 */ { MAD_F(0x058da793) /* 0.347083639 */, 17 },
3339 /* 3116 */ { MAD_F(0x058e435d) /* 0.347232211 */, 17 },
3340 /* 3117 */ { MAD_F(0x058edf2b) /* 0.347380799 */, 17 },
3341 /* 3118 */ { MAD_F(0x058f7afe) /* 0.347529403 */, 17 },
3342 /* 3119 */ { MAD_F(0x059016d5) /* 0.347678023 */, 17 },
3343
3344 /* 3120 */ { MAD_F(0x0590b2b0) /* 0.347826659 */, 17 },
3345 /* 3121 */ { MAD_F(0x05914e8f) /* 0.347975311 */, 17 },
3346 /* 3122 */ { MAD_F(0x0591ea73) /* 0.348123979 */, 17 },
3347 /* 3123 */ { MAD_F(0x0592865b) /* 0.348272662 */, 17 },
3348 /* 3124 */ { MAD_F(0x05932247) /* 0.348421362 */, 17 },
3349 /* 3125 */ { MAD_F(0x0593be37) /* 0.348570077 */, 17 },
3350 /* 3126 */ { MAD_F(0x05945a2c) /* 0.348718808 */, 17 },
3351 /* 3127 */ { MAD_F(0x0594f625) /* 0.348867555 */, 17 },
3352 /* 3128 */ { MAD_F(0x05959222) /* 0.349016318 */, 17 },
3353 /* 3129 */ { MAD_F(0x05962e24) /* 0.349165097 */, 17 },
3354 /* 3130 */ { MAD_F(0x0596ca2a) /* 0.349313892 */, 17 },
3355 /* 3131 */ { MAD_F(0x05976634) /* 0.349462702 */, 17 },
3356 /* 3132 */ { MAD_F(0x05980242) /* 0.349611528 */, 17 },
3357 /* 3133 */ { MAD_F(0x05989e54) /* 0.349760370 */, 17 },
3358 /* 3134 */ { MAD_F(0x05993a6b) /* 0.349909228 */, 17 },
3359 /* 3135 */ { MAD_F(0x0599d686) /* 0.350058102 */, 17 },
3360
3361 /* 3136 */ { MAD_F(0x059a72a5) /* 0.350206992 */, 17 },
3362 /* 3137 */ { MAD_F(0x059b0ec9) /* 0.350355897 */, 17 },
3363 /* 3138 */ { MAD_F(0x059baaf1) /* 0.350504818 */, 17 },
3364 /* 3139 */ { MAD_F(0x059c471d) /* 0.350653756 */, 17 },
3365 /* 3140 */ { MAD_F(0x059ce34d) /* 0.350802708 */, 17 },
3366 /* 3141 */ { MAD_F(0x059d7f81) /* 0.350951677 */, 17 },
3367 /* 3142 */ { MAD_F(0x059e1bba) /* 0.351100662 */, 17 },
3368 /* 3143 */ { MAD_F(0x059eb7f7) /* 0.351249662 */, 17 },
3369 /* 3144 */ { MAD_F(0x059f5438) /* 0.351398678 */, 17 },
3370 /* 3145 */ { MAD_F(0x059ff07e) /* 0.351547710 */, 17 },
3371 /* 3146 */ { MAD_F(0x05a08cc7) /* 0.351696758 */, 17 },
3372 /* 3147 */ { MAD_F(0x05a12915) /* 0.351845821 */, 17 },
3373 /* 3148 */ { MAD_F(0x05a1c567) /* 0.351994901 */, 17 },
3374 /* 3149 */ { MAD_F(0x05a261be) /* 0.352143996 */, 17 },
3375 /* 3150 */ { MAD_F(0x05a2fe18) /* 0.352293107 */, 17 },
3376 /* 3151 */ { MAD_F(0x05a39a77) /* 0.352442233 */, 17 },
3377
3378 /* 3152 */ { MAD_F(0x05a436da) /* 0.352591376 */, 17 },
3379 /* 3153 */ { MAD_F(0x05a4d342) /* 0.352740534 */, 17 },
3380 /* 3154 */ { MAD_F(0x05a56fad) /* 0.352889708 */, 17 },
3381 /* 3155 */ { MAD_F(0x05a60c1d) /* 0.353038898 */, 17 },
3382 /* 3156 */ { MAD_F(0x05a6a891) /* 0.353188103 */, 17 },
3383 /* 3157 */ { MAD_F(0x05a7450a) /* 0.353337325 */, 17 },
3384 /* 3158 */ { MAD_F(0x05a7e186) /* 0.353486562 */, 17 },
3385 /* 3159 */ { MAD_F(0x05a87e07) /* 0.353635814 */, 17 },
3386 /* 3160 */ { MAD_F(0x05a91a8c) /* 0.353785083 */, 17 },
3387 /* 3161 */ { MAD_F(0x05a9b715) /* 0.353934367 */, 17 },
3388 /* 3162 */ { MAD_F(0x05aa53a2) /* 0.354083667 */, 17 },
3389 /* 3163 */ { MAD_F(0x05aaf034) /* 0.354232983 */, 17 },
3390 /* 3164 */ { MAD_F(0x05ab8cca) /* 0.354382314 */, 17 },
3391 /* 3165 */ { MAD_F(0x05ac2964) /* 0.354531662 */, 17 },
3392 /* 3166 */ { MAD_F(0x05acc602) /* 0.354681025 */, 17 },
3393 /* 3167 */ { MAD_F(0x05ad62a5) /* 0.354830403 */, 17 },
3394
3395 /* 3168 */ { MAD_F(0x05adff4c) /* 0.354979798 */, 17 },
3396 /* 3169 */ { MAD_F(0x05ae9bf7) /* 0.355129208 */, 17 },
3397 /* 3170 */ { MAD_F(0x05af38a6) /* 0.355278634 */, 17 },
3398 /* 3171 */ { MAD_F(0x05afd559) /* 0.355428075 */, 17 },
3399 /* 3172 */ { MAD_F(0x05b07211) /* 0.355577533 */, 17 },
3400 /* 3173 */ { MAD_F(0x05b10ecd) /* 0.355727006 */, 17 },
3401 /* 3174 */ { MAD_F(0x05b1ab8d) /* 0.355876494 */, 17 },
3402 /* 3175 */ { MAD_F(0x05b24851) /* 0.356025999 */, 17 },
3403 /* 3176 */ { MAD_F(0x05b2e51a) /* 0.356175519 */, 17 },
3404 /* 3177 */ { MAD_F(0x05b381e6) /* 0.356325054 */, 17 },
3405 /* 3178 */ { MAD_F(0x05b41eb7) /* 0.356474606 */, 17 },
3406 /* 3179 */ { MAD_F(0x05b4bb8c) /* 0.356624173 */, 17 },
3407 /* 3180 */ { MAD_F(0x05b55866) /* 0.356773756 */, 17 },
3408 /* 3181 */ { MAD_F(0x05b5f543) /* 0.356923354 */, 17 },
3409 /* 3182 */ { MAD_F(0x05b69225) /* 0.357072969 */, 17 },
3410 /* 3183 */ { MAD_F(0x05b72f0b) /* 0.357222598 */, 17 },
3411
3412 /* 3184 */ { MAD_F(0x05b7cbf5) /* 0.357372244 */, 17 },
3413 /* 3185 */ { MAD_F(0x05b868e3) /* 0.357521905 */, 17 },
3414 /* 3186 */ { MAD_F(0x05b905d6) /* 0.357671582 */, 17 },
3415 /* 3187 */ { MAD_F(0x05b9a2cd) /* 0.357821275 */, 17 },
3416 /* 3188 */ { MAD_F(0x05ba3fc8) /* 0.357970983 */, 17 },
3417 /* 3189 */ { MAD_F(0x05badcc7) /* 0.358120707 */, 17 },
3418 /* 3190 */ { MAD_F(0x05bb79ca) /* 0.358270446 */, 17 },
3419 /* 3191 */ { MAD_F(0x05bc16d2) /* 0.358420201 */, 17 },
3420 /* 3192 */ { MAD_F(0x05bcb3de) /* 0.358569972 */, 17 },
3421 /* 3193 */ { MAD_F(0x05bd50ee) /* 0.358719758 */, 17 },
3422 /* 3194 */ { MAD_F(0x05bdee02) /* 0.358869560 */, 17 },
3423 /* 3195 */ { MAD_F(0x05be8b1a) /* 0.359019378 */, 17 },
3424 /* 3196 */ { MAD_F(0x05bf2837) /* 0.359169211 */, 17 },
3425 /* 3197 */ { MAD_F(0x05bfc558) /* 0.359319060 */, 17 },
3426 /* 3198 */ { MAD_F(0x05c0627d) /* 0.359468925 */, 17 },
3427 /* 3199 */ { MAD_F(0x05c0ffa6) /* 0.359618805 */, 17 },
3428
3429 /* 3200 */ { MAD_F(0x05c19cd3) /* 0.359768701 */, 17 },
3430 /* 3201 */ { MAD_F(0x05c23a05) /* 0.359918612 */, 17 },
3431 /* 3202 */ { MAD_F(0x05c2d73a) /* 0.360068540 */, 17 },
3432 /* 3203 */ { MAD_F(0x05c37474) /* 0.360218482 */, 17 },
3433 /* 3204 */ { MAD_F(0x05c411b2) /* 0.360368440 */, 17 },
3434 /* 3205 */ { MAD_F(0x05c4aef5) /* 0.360518414 */, 17 },
3435 /* 3206 */ { MAD_F(0x05c54c3b) /* 0.360668404 */, 17 },
3436 /* 3207 */ { MAD_F(0x05c5e986) /* 0.360818409 */, 17 },
3437 /* 3208 */ { MAD_F(0x05c686d5) /* 0.360968429 */, 17 },
3438 /* 3209 */ { MAD_F(0x05c72428) /* 0.361118466 */, 17 },
3439 /* 3210 */ { MAD_F(0x05c7c17f) /* 0.361268517 */, 17 },
3440 /* 3211 */ { MAD_F(0x05c85eda) /* 0.361418585 */, 17 },
3441 /* 3212 */ { MAD_F(0x05c8fc3a) /* 0.361568668 */, 17 },
3442 /* 3213 */ { MAD_F(0x05c9999e) /* 0.361718766 */, 17 },
3443 /* 3214 */ { MAD_F(0x05ca3706) /* 0.361868881 */, 17 },
3444 /* 3215 */ { MAD_F(0x05cad472) /* 0.362019010 */, 17 },
3445
3446 /* 3216 */ { MAD_F(0x05cb71e2) /* 0.362169156 */, 17 },
3447 /* 3217 */ { MAD_F(0x05cc0f57) /* 0.362319316 */, 17 },
3448 /* 3218 */ { MAD_F(0x05ccaccf) /* 0.362469493 */, 17 },
3449 /* 3219 */ { MAD_F(0x05cd4a4c) /* 0.362619685 */, 17 },
3450 /* 3220 */ { MAD_F(0x05cde7cd) /* 0.362769892 */, 17 },
3451 /* 3221 */ { MAD_F(0x05ce8552) /* 0.362920115 */, 17 },
3452 /* 3222 */ { MAD_F(0x05cf22dc) /* 0.363070354 */, 17 },
3453 /* 3223 */ { MAD_F(0x05cfc069) /* 0.363220608 */, 17 },
3454 /* 3224 */ { MAD_F(0x05d05dfb) /* 0.363370878 */, 17 },
3455 /* 3225 */ { MAD_F(0x05d0fb91) /* 0.363521163 */, 17 },
3456 /* 3226 */ { MAD_F(0x05d1992b) /* 0.363671464 */, 17 },
3457 /* 3227 */ { MAD_F(0x05d236c9) /* 0.363821780 */, 17 },
3458 /* 3228 */ { MAD_F(0x05d2d46c) /* 0.363972112 */, 17 },
3459 /* 3229 */ { MAD_F(0x05d37212) /* 0.364122459 */, 17 },
3460 /* 3230 */ { MAD_F(0x05d40fbd) /* 0.364272822 */, 17 },
3461 /* 3231 */ { MAD_F(0x05d4ad6c) /* 0.364423200 */, 17 },
3462
3463 /* 3232 */ { MAD_F(0x05d54b1f) /* 0.364573594 */, 17 },
3464 /* 3233 */ { MAD_F(0x05d5e8d6) /* 0.364724004 */, 17 },
3465 /* 3234 */ { MAD_F(0x05d68691) /* 0.364874429 */, 17 },
3466 /* 3235 */ { MAD_F(0x05d72451) /* 0.365024869 */, 17 },
3467 /* 3236 */ { MAD_F(0x05d7c215) /* 0.365175325 */, 17 },
3468 /* 3237 */ { MAD_F(0x05d85fdc) /* 0.365325796 */, 17 },
3469 /* 3238 */ { MAD_F(0x05d8fda8) /* 0.365476283 */, 17 },
3470 /* 3239 */ { MAD_F(0x05d99b79) /* 0.365626786 */, 17 },
3471 /* 3240 */ { MAD_F(0x05da394d) /* 0.365777304 */, 17 },
3472 /* 3241 */ { MAD_F(0x05dad726) /* 0.365927837 */, 17 },
3473 /* 3242 */ { MAD_F(0x05db7502) /* 0.366078386 */, 17 },
3474 /* 3243 */ { MAD_F(0x05dc12e3) /* 0.366228950 */, 17 },
3475 /* 3244 */ { MAD_F(0x05dcb0c8) /* 0.366379530 */, 17 },
3476 /* 3245 */ { MAD_F(0x05dd4eb1) /* 0.366530125 */, 17 },
3477 /* 3246 */ { MAD_F(0x05ddec9e) /* 0.366680736 */, 17 },
3478 /* 3247 */ { MAD_F(0x05de8a90) /* 0.366831362 */, 17 },
3479
3480 /* 3248 */ { MAD_F(0x05df2885) /* 0.366982004 */, 17 },
3481 /* 3249 */ { MAD_F(0x05dfc67f) /* 0.367132661 */, 17 },
3482 /* 3250 */ { MAD_F(0x05e0647d) /* 0.367283334 */, 17 },
3483 /* 3251 */ { MAD_F(0x05e1027f) /* 0.367434022 */, 17 },
3484 /* 3252 */ { MAD_F(0x05e1a085) /* 0.367584725 */, 17 },
3485 /* 3253 */ { MAD_F(0x05e23e8f) /* 0.367735444 */, 17 },
3486 /* 3254 */ { MAD_F(0x05e2dc9e) /* 0.367886179 */, 17 },
3487 /* 3255 */ { MAD_F(0x05e37ab0) /* 0.368036929 */, 17 },
3488 /* 3256 */ { MAD_F(0x05e418c7) /* 0.368187694 */, 17 },
3489 /* 3257 */ { MAD_F(0x05e4b6e2) /* 0.368338475 */, 17 },
3490 /* 3258 */ { MAD_F(0x05e55501) /* 0.368489271 */, 17 },
3491 /* 3259 */ { MAD_F(0x05e5f324) /* 0.368640082 */, 17 },
3492 /* 3260 */ { MAD_F(0x05e6914c) /* 0.368790909 */, 17 },
3493 /* 3261 */ { MAD_F(0x05e72f77) /* 0.368941752 */, 17 },
3494 /* 3262 */ { MAD_F(0x05e7cda7) /* 0.369092610 */, 17 },
3495 /* 3263 */ { MAD_F(0x05e86bda) /* 0.369243483 */, 17 },
3496
3497 /* 3264 */ { MAD_F(0x05e90a12) /* 0.369394372 */, 17 },
3498 /* 3265 */ { MAD_F(0x05e9a84e) /* 0.369545276 */, 17 },
3499 /* 3266 */ { MAD_F(0x05ea468e) /* 0.369696195 */, 17 },
3500 /* 3267 */ { MAD_F(0x05eae4d3) /* 0.369847130 */, 17 },
3501 /* 3268 */ { MAD_F(0x05eb831b) /* 0.369998080 */, 17 },
3502 /* 3269 */ { MAD_F(0x05ec2168) /* 0.370149046 */, 17 },
3503 /* 3270 */ { MAD_F(0x05ecbfb8) /* 0.370300027 */, 17 },
3504 /* 3271 */ { MAD_F(0x05ed5e0d) /* 0.370451024 */, 17 },
3505 /* 3272 */ { MAD_F(0x05edfc66) /* 0.370602036 */, 17 },
3506 /* 3273 */ { MAD_F(0x05ee9ac3) /* 0.370753063 */, 17 },
3507 /* 3274 */ { MAD_F(0x05ef3924) /* 0.370904105 */, 17 },
3508 /* 3275 */ { MAD_F(0x05efd78a) /* 0.371055163 */, 17 },
3509 /* 3276 */ { MAD_F(0x05f075f3) /* 0.371206237 */, 17 },
3510 /* 3277 */ { MAD_F(0x05f11461) /* 0.371357326 */, 17 },
3511 /* 3278 */ { MAD_F(0x05f1b2d3) /* 0.371508430 */, 17 },
3512 /* 3279 */ { MAD_F(0x05f25148) /* 0.371659549 */, 17 },
3513
3514 /* 3280 */ { MAD_F(0x05f2efc2) /* 0.371810684 */, 17 },
3515 /* 3281 */ { MAD_F(0x05f38e40) /* 0.371961834 */, 17 },
3516 /* 3282 */ { MAD_F(0x05f42cc3) /* 0.372113000 */, 17 },
3517 /* 3283 */ { MAD_F(0x05f4cb49) /* 0.372264181 */, 17 },
3518 /* 3284 */ { MAD_F(0x05f569d3) /* 0.372415377 */, 17 },
3519 /* 3285 */ { MAD_F(0x05f60862) /* 0.372566589 */, 17 },
3520 /* 3286 */ { MAD_F(0x05f6a6f5) /* 0.372717816 */, 17 },
3521 /* 3287 */ { MAD_F(0x05f7458b) /* 0.372869058 */, 17 },
3522 /* 3288 */ { MAD_F(0x05f7e426) /* 0.373020316 */, 17 },
3523 /* 3289 */ { MAD_F(0x05f882c5) /* 0.373171589 */, 17 },
3524 /* 3290 */ { MAD_F(0x05f92169) /* 0.373322877 */, 17 },
3525 /* 3291 */ { MAD_F(0x05f9c010) /* 0.373474181 */, 17 },
3526 /* 3292 */ { MAD_F(0x05fa5ebb) /* 0.373625500 */, 17 },
3527 /* 3293 */ { MAD_F(0x05fafd6b) /* 0.373776834 */, 17 },
3528 /* 3294 */ { MAD_F(0x05fb9c1e) /* 0.373928184 */, 17 },
3529 /* 3295 */ { MAD_F(0x05fc3ad6) /* 0.374079549 */, 17 },
3530
3531 /* 3296 */ { MAD_F(0x05fcd992) /* 0.374230929 */, 17 },
3532 /* 3297 */ { MAD_F(0x05fd7852) /* 0.374382325 */, 17 },
3533 /* 3298 */ { MAD_F(0x05fe1716) /* 0.374533735 */, 17 },
3534 /* 3299 */ { MAD_F(0x05feb5de) /* 0.374685162 */, 17 },
3535 /* 3300 */ { MAD_F(0x05ff54aa) /* 0.374836603 */, 17 },
3536 /* 3301 */ { MAD_F(0x05fff37b) /* 0.374988060 */, 17 },
3537 /* 3302 */ { MAD_F(0x0600924f) /* 0.375139532 */, 17 },
3538 /* 3303 */ { MAD_F(0x06013128) /* 0.375291019 */, 17 },
3539 /* 3304 */ { MAD_F(0x0601d004) /* 0.375442522 */, 17 },
3540 /* 3305 */ { MAD_F(0x06026ee5) /* 0.375594040 */, 17 },
3541 /* 3306 */ { MAD_F(0x06030dca) /* 0.375745573 */, 17 },
3542 /* 3307 */ { MAD_F(0x0603acb3) /* 0.375897122 */, 17 },
3543 /* 3308 */ { MAD_F(0x06044ba0) /* 0.376048685 */, 17 },
3544 /* 3309 */ { MAD_F(0x0604ea91) /* 0.376200265 */, 17 },
3545 /* 3310 */ { MAD_F(0x06058987) /* 0.376351859 */, 17 },
3546 /* 3311 */ { MAD_F(0x06062880) /* 0.376503468 */, 17 },
3547
3548 /* 3312 */ { MAD_F(0x0606c77d) /* 0.376655093 */, 17 },
3549 /* 3313 */ { MAD_F(0x0607667f) /* 0.376806733 */, 17 },
3550 /* 3314 */ { MAD_F(0x06080585) /* 0.376958389 */, 17 },
3551 /* 3315 */ { MAD_F(0x0608a48f) /* 0.377110059 */, 17 },
3552 /* 3316 */ { MAD_F(0x0609439c) /* 0.377261745 */, 17 },
3553 /* 3317 */ { MAD_F(0x0609e2ae) /* 0.377413446 */, 17 },
3554 /* 3318 */ { MAD_F(0x060a81c4) /* 0.377565163 */, 17 },
3555 /* 3319 */ { MAD_F(0x060b20df) /* 0.377716894 */, 17 },
3556 /* 3320 */ { MAD_F(0x060bbffd) /* 0.377868641 */, 17 },
3557 /* 3321 */ { MAD_F(0x060c5f1f) /* 0.378020403 */, 17 },
3558 /* 3322 */ { MAD_F(0x060cfe46) /* 0.378172181 */, 17 },
3559 /* 3323 */ { MAD_F(0x060d9d70) /* 0.378323973 */, 17 },
3560 /* 3324 */ { MAD_F(0x060e3c9f) /* 0.378475781 */, 17 },
3561 /* 3325 */ { MAD_F(0x060edbd1) /* 0.378627604 */, 17 },
3562 /* 3326 */ { MAD_F(0x060f7b08) /* 0.378779442 */, 17 },
3563 /* 3327 */ { MAD_F(0x06101a43) /* 0.378931296 */, 17 },
3564
3565 /* 3328 */ { MAD_F(0x0610b982) /* 0.379083164 */, 17 },
3566 /* 3329 */ { MAD_F(0x061158c5) /* 0.379235048 */, 17 },
3567 /* 3330 */ { MAD_F(0x0611f80c) /* 0.379386947 */, 17 },
3568 /* 3331 */ { MAD_F(0x06129757) /* 0.379538862 */, 17 },
3569 /* 3332 */ { MAD_F(0x061336a6) /* 0.379690791 */, 17 },
3570 /* 3333 */ { MAD_F(0x0613d5fa) /* 0.379842736 */, 17 },
3571 /* 3334 */ { MAD_F(0x06147551) /* 0.379994696 */, 17 },
3572 /* 3335 */ { MAD_F(0x061514ad) /* 0.380146671 */, 17 },
3573 /* 3336 */ { MAD_F(0x0615b40c) /* 0.380298661 */, 17 },
3574 /* 3337 */ { MAD_F(0x06165370) /* 0.380450666 */, 17 },
3575 /* 3338 */ { MAD_F(0x0616f2d8) /* 0.380602687 */, 17 },
3576 /* 3339 */ { MAD_F(0x06179243) /* 0.380754723 */, 17 },
3577 /* 3340 */ { MAD_F(0x061831b3) /* 0.380906774 */, 17 },
3578 /* 3341 */ { MAD_F(0x0618d127) /* 0.381058840 */, 17 },
3579 /* 3342 */ { MAD_F(0x0619709f) /* 0.381210921 */, 17 },
3580 /* 3343 */ { MAD_F(0x061a101b) /* 0.381363018 */, 17 },
3581
3582 /* 3344 */ { MAD_F(0x061aaf9c) /* 0.381515130 */, 17 },
3583 /* 3345 */ { MAD_F(0x061b4f20) /* 0.381667257 */, 17 },
3584 /* 3346 */ { MAD_F(0x061beea8) /* 0.381819399 */, 17 },
3585 /* 3347 */ { MAD_F(0x061c8e34) /* 0.381971556 */, 17 },
3586 /* 3348 */ { MAD_F(0x061d2dc5) /* 0.382123728 */, 17 },
3587 /* 3349 */ { MAD_F(0x061dcd59) /* 0.382275916 */, 17 },
3588 /* 3350 */ { MAD_F(0x061e6cf2) /* 0.382428118 */, 17 },
3589 /* 3351 */ { MAD_F(0x061f0c8f) /* 0.382580336 */, 17 },
3590 /* 3352 */ { MAD_F(0x061fac2f) /* 0.382732569 */, 17 },
3591 /* 3353 */ { MAD_F(0x06204bd4) /* 0.382884817 */, 17 },
3592 /* 3354 */ { MAD_F(0x0620eb7d) /* 0.383037080 */, 17 },
3593 /* 3355 */ { MAD_F(0x06218b2a) /* 0.383189358 */, 17 },
3594 /* 3356 */ { MAD_F(0x06222adb) /* 0.383341652 */, 17 },
3595 /* 3357 */ { MAD_F(0x0622ca90) /* 0.383493960 */, 17 },
3596 /* 3358 */ { MAD_F(0x06236a49) /* 0.383646284 */, 17 },
3597 /* 3359 */ { MAD_F(0x06240a06) /* 0.383798623 */, 17 },
3598
3599 /* 3360 */ { MAD_F(0x0624a9c7) /* 0.383950977 */, 17 },
3600 /* 3361 */ { MAD_F(0x0625498d) /* 0.384103346 */, 17 },
3601 /* 3362 */ { MAD_F(0x0625e956) /* 0.384255730 */, 17 },
3602 /* 3363 */ { MAD_F(0x06268923) /* 0.384408129 */, 17 },
3603 /* 3364 */ { MAD_F(0x062728f5) /* 0.384560544 */, 17 },
3604 /* 3365 */ { MAD_F(0x0627c8ca) /* 0.384712973 */, 17 },
3605 /* 3366 */ { MAD_F(0x062868a4) /* 0.384865418 */, 17 },
3606 /* 3367 */ { MAD_F(0x06290881) /* 0.385017878 */, 17 },
3607 /* 3368 */ { MAD_F(0x0629a863) /* 0.385170352 */, 17 },
3608 /* 3369 */ { MAD_F(0x062a4849) /* 0.385322842 */, 17 },
3609 /* 3370 */ { MAD_F(0x062ae832) /* 0.385475347 */, 17 },
3610 /* 3371 */ { MAD_F(0x062b8820) /* 0.385627867 */, 17 },
3611 /* 3372 */ { MAD_F(0x062c2812) /* 0.385780402 */, 17 },
3612 /* 3373 */ { MAD_F(0x062cc808) /* 0.385932953 */, 17 },
3613 /* 3374 */ { MAD_F(0x062d6802) /* 0.386085518 */, 17 },
3614 /* 3375 */ { MAD_F(0x062e0800) /* 0.386238098 */, 17 },
3615
3616 /* 3376 */ { MAD_F(0x062ea802) /* 0.386390694 */, 17 },
3617 /* 3377 */ { MAD_F(0x062f4808) /* 0.386543304 */, 17 },
3618 /* 3378 */ { MAD_F(0x062fe812) /* 0.386695930 */, 17 },
3619 /* 3379 */ { MAD_F(0x06308820) /* 0.386848570 */, 17 },
3620 /* 3380 */ { MAD_F(0x06312832) /* 0.387001226 */, 17 },
3621 /* 3381 */ { MAD_F(0x0631c849) /* 0.387153897 */, 17 },
3622 /* 3382 */ { MAD_F(0x06326863) /* 0.387306582 */, 17 },
3623 /* 3383 */ { MAD_F(0x06330881) /* 0.387459283 */, 17 },
3624 /* 3384 */ { MAD_F(0x0633a8a3) /* 0.387611999 */, 17 },
3625 /* 3385 */ { MAD_F(0x063448ca) /* 0.387764730 */, 17 },
3626 /* 3386 */ { MAD_F(0x0634e8f4) /* 0.387917476 */, 17 },
3627 /* 3387 */ { MAD_F(0x06358923) /* 0.388070237 */, 17 },
3628 /* 3388 */ { MAD_F(0x06362955) /* 0.388223013 */, 17 },
3629 /* 3389 */ { MAD_F(0x0636c98c) /* 0.388375804 */, 17 },
3630 /* 3390 */ { MAD_F(0x063769c6) /* 0.388528610 */, 17 },
3631 /* 3391 */ { MAD_F(0x06380a05) /* 0.388681431 */, 17 },
3632
3633 /* 3392 */ { MAD_F(0x0638aa48) /* 0.388834268 */, 17 },
3634 /* 3393 */ { MAD_F(0x06394a8e) /* 0.388987119 */, 17 },
3635 /* 3394 */ { MAD_F(0x0639ead9) /* 0.389139985 */, 17 },
3636 /* 3395 */ { MAD_F(0x063a8b28) /* 0.389292866 */, 17 },
3637 /* 3396 */ { MAD_F(0x063b2b7b) /* 0.389445762 */, 17 },
3638 /* 3397 */ { MAD_F(0x063bcbd1) /* 0.389598674 */, 17 },
3639 /* 3398 */ { MAD_F(0x063c6c2c) /* 0.389751600 */, 17 },
3640 /* 3399 */ { MAD_F(0x063d0c8b) /* 0.389904541 */, 17 },
3641 /* 3400 */ { MAD_F(0x063dacee) /* 0.390057497 */, 17 },
3642 /* 3401 */ { MAD_F(0x063e4d55) /* 0.390210468 */, 17 },
3643 /* 3402 */ { MAD_F(0x063eedc0) /* 0.390363455 */, 17 },
3644 /* 3403 */ { MAD_F(0x063f8e2f) /* 0.390516456 */, 17 },
3645 /* 3404 */ { MAD_F(0x06402ea2) /* 0.390669472 */, 17 },
3646 /* 3405 */ { MAD_F(0x0640cf19) /* 0.390822503 */, 17 },
3647 /* 3406 */ { MAD_F(0x06416f94) /* 0.390975549 */, 17 },
3648 /* 3407 */ { MAD_F(0x06421013) /* 0.391128611 */, 17 },
3649
3650 /* 3408 */ { MAD_F(0x0642b096) /* 0.391281687 */, 17 },
3651 /* 3409 */ { MAD_F(0x0643511d) /* 0.391434778 */, 17 },
3652 /* 3410 */ { MAD_F(0x0643f1a8) /* 0.391587884 */, 17 },
3653 /* 3411 */ { MAD_F(0x06449237) /* 0.391741005 */, 17 },
3654 /* 3412 */ { MAD_F(0x064532ca) /* 0.391894141 */, 17 },
3655 /* 3413 */ { MAD_F(0x0645d361) /* 0.392047292 */, 17 },
3656 /* 3414 */ { MAD_F(0x064673fc) /* 0.392200458 */, 17 },
3657 /* 3415 */ { MAD_F(0x0647149c) /* 0.392353638 */, 17 },
3658 /* 3416 */ { MAD_F(0x0647b53f) /* 0.392506834 */, 17 },
3659 /* 3417 */ { MAD_F(0x064855e6) /* 0.392660045 */, 17 },
3660 /* 3418 */ { MAD_F(0x0648f691) /* 0.392813271 */, 17 },
3661 /* 3419 */ { MAD_F(0x06499740) /* 0.392966511 */, 17 },
3662 /* 3420 */ { MAD_F(0x064a37f4) /* 0.393119767 */, 17 },
3663 /* 3421 */ { MAD_F(0x064ad8ab) /* 0.393273038 */, 17 },
3664 /* 3422 */ { MAD_F(0x064b7966) /* 0.393426323 */, 17 },
3665 /* 3423 */ { MAD_F(0x064c1a25) /* 0.393579623 */, 17 },
3666
3667 /* 3424 */ { MAD_F(0x064cbae9) /* 0.393732939 */, 17 },
3668 /* 3425 */ { MAD_F(0x064d5bb0) /* 0.393886269 */, 17 },
3669 /* 3426 */ { MAD_F(0x064dfc7b) /* 0.394039614 */, 17 },
3670 /* 3427 */ { MAD_F(0x064e9d4b) /* 0.394192974 */, 17 },
3671 /* 3428 */ { MAD_F(0x064f3e1e) /* 0.394346349 */, 17 },
3672 /* 3429 */ { MAD_F(0x064fdef5) /* 0.394499739 */, 17 },
3673 /* 3430 */ { MAD_F(0x06507fd0) /* 0.394653144 */, 17 },
3674 /* 3431 */ { MAD_F(0x065120b0) /* 0.394806564 */, 17 },
3675 /* 3432 */ { MAD_F(0x0651c193) /* 0.394959999 */, 17 },
3676 /* 3433 */ { MAD_F(0x0652627a) /* 0.395113448 */, 17 },
3677 /* 3434 */ { MAD_F(0x06530366) /* 0.395266913 */, 17 },
3678 /* 3435 */ { MAD_F(0x0653a455) /* 0.395420392 */, 17 },
3679 /* 3436 */ { MAD_F(0x06544548) /* 0.395573886 */, 17 },
3680 /* 3437 */ { MAD_F(0x0654e640) /* 0.395727395 */, 17 },
3681 /* 3438 */ { MAD_F(0x0655873b) /* 0.395880919 */, 17 },
3682 /* 3439 */ { MAD_F(0x0656283a) /* 0.396034458 */, 17 },
3683
3684 /* 3440 */ { MAD_F(0x0656c93d) /* 0.396188012 */, 17 },
3685 /* 3441 */ { MAD_F(0x06576a45) /* 0.396341581 */, 17 },
3686 /* 3442 */ { MAD_F(0x06580b50) /* 0.396495164 */, 17 },
3687 /* 3443 */ { MAD_F(0x0658ac5f) /* 0.396648763 */, 17 },
3688 /* 3444 */ { MAD_F(0x06594d73) /* 0.396802376 */, 17 },
3689 /* 3445 */ { MAD_F(0x0659ee8a) /* 0.396956004 */, 17 },
3690 /* 3446 */ { MAD_F(0x065a8fa5) /* 0.397109647 */, 17 },
3691 /* 3447 */ { MAD_F(0x065b30c4) /* 0.397263305 */, 17 },
3692 /* 3448 */ { MAD_F(0x065bd1e7) /* 0.397416978 */, 17 },
3693 /* 3449 */ { MAD_F(0x065c730f) /* 0.397570666 */, 17 },
3694 /* 3450 */ { MAD_F(0x065d143a) /* 0.397724368 */, 17 },
3695 /* 3451 */ { MAD_F(0x065db569) /* 0.397878085 */, 17 },
3696 /* 3452 */ { MAD_F(0x065e569c) /* 0.398031818 */, 17 },
3697 /* 3453 */ { MAD_F(0x065ef7d3) /* 0.398185565 */, 17 },
3698 /* 3454 */ { MAD_F(0x065f990e) /* 0.398339326 */, 17 },
3699 /* 3455 */ { MAD_F(0x06603a4e) /* 0.398493103 */, 17 },
3700
3701 /* 3456 */ { MAD_F(0x0660db91) /* 0.398646895 */, 17 },
3702 /* 3457 */ { MAD_F(0x06617cd8) /* 0.398800701 */, 17 },
3703 /* 3458 */ { MAD_F(0x06621e23) /* 0.398954522 */, 17 },
3704 /* 3459 */ { MAD_F(0x0662bf72) /* 0.399108358 */, 17 },
3705 /* 3460 */ { MAD_F(0x066360c5) /* 0.399262209 */, 17 },
3706 /* 3461 */ { MAD_F(0x0664021c) /* 0.399416075 */, 17 },
3707 /* 3462 */ { MAD_F(0x0664a377) /* 0.399569955 */, 17 },
3708 /* 3463 */ { MAD_F(0x066544d6) /* 0.399723851 */, 17 },
3709 /* 3464 */ { MAD_F(0x0665e639) /* 0.399877761 */, 17 },
3710 /* 3465 */ { MAD_F(0x066687a0) /* 0.400031686 */, 17 },
3711 /* 3466 */ { MAD_F(0x0667290b) /* 0.400185625 */, 17 },
3712 /* 3467 */ { MAD_F(0x0667ca79) /* 0.400339580 */, 17 },
3713 /* 3468 */ { MAD_F(0x06686bec) /* 0.400493549 */, 17 },
3714 /* 3469 */ { MAD_F(0x06690d63) /* 0.400647534 */, 17 },
3715 /* 3470 */ { MAD_F(0x0669aede) /* 0.400801533 */, 17 },
3716 /* 3471 */ { MAD_F(0x066a505d) /* 0.400955546 */, 17 },
3717
3718 /* 3472 */ { MAD_F(0x066af1df) /* 0.401109575 */, 17 },
3719 /* 3473 */ { MAD_F(0x066b9366) /* 0.401263618 */, 17 },
3720 /* 3474 */ { MAD_F(0x066c34f1) /* 0.401417676 */, 17 },
3721 /* 3475 */ { MAD_F(0x066cd67f) /* 0.401571749 */, 17 },
3722 /* 3476 */ { MAD_F(0x066d7812) /* 0.401725837 */, 17 },
3723 /* 3477 */ { MAD_F(0x066e19a9) /* 0.401879939 */, 17 },
3724 /* 3478 */ { MAD_F(0x066ebb43) /* 0.402034056 */, 17 },
3725 /* 3479 */ { MAD_F(0x066f5ce2) /* 0.402188188 */, 17 },
3726 /* 3480 */ { MAD_F(0x066ffe84) /* 0.402342335 */, 17 },
3727 /* 3481 */ { MAD_F(0x0670a02a) /* 0.402496497 */, 17 },
3728 /* 3482 */ { MAD_F(0x067141d5) /* 0.402650673 */, 17 },
3729 /* 3483 */ { MAD_F(0x0671e383) /* 0.402804864 */, 17 },
3730 /* 3484 */ { MAD_F(0x06728535) /* 0.402959070 */, 17 },
3731 /* 3485 */ { MAD_F(0x067326ec) /* 0.403113291 */, 17 },
3732 /* 3486 */ { MAD_F(0x0673c8a6) /* 0.403267526 */, 17 },
3733 /* 3487 */ { MAD_F(0x06746a64) /* 0.403421776 */, 17 },
3734
3735 /* 3488 */ { MAD_F(0x06750c26) /* 0.403576041 */, 17 },
3736 /* 3489 */ { MAD_F(0x0675adec) /* 0.403730320 */, 17 },
3737 /* 3490 */ { MAD_F(0x06764fb6) /* 0.403884615 */, 17 },
3738 /* 3491 */ { MAD_F(0x0676f184) /* 0.404038924 */, 17 },
3739 /* 3492 */ { MAD_F(0x06779356) /* 0.404193247 */, 17 },
3740 /* 3493 */ { MAD_F(0x0678352c) /* 0.404347586 */, 17 },
3741 /* 3494 */ { MAD_F(0x0678d706) /* 0.404501939 */, 17 },
3742 /* 3495 */ { MAD_F(0x067978e4) /* 0.404656307 */, 17 },
3743 /* 3496 */ { MAD_F(0x067a1ac6) /* 0.404810690 */, 17 },
3744 /* 3497 */ { MAD_F(0x067abcac) /* 0.404965087 */, 17 },
3745 /* 3498 */ { MAD_F(0x067b5e95) /* 0.405119499 */, 17 },
3746 /* 3499 */ { MAD_F(0x067c0083) /* 0.405273926 */, 17 },
3747 /* 3500 */ { MAD_F(0x067ca275) /* 0.405428368 */, 17 },
3748 /* 3501 */ { MAD_F(0x067d446a) /* 0.405582824 */, 17 },
3749 /* 3502 */ { MAD_F(0x067de664) /* 0.405737295 */, 17 },
3750 /* 3503 */ { MAD_F(0x067e8861) /* 0.405891781 */, 17 },
3751
3752 /* 3504 */ { MAD_F(0x067f2a62) /* 0.406046281 */, 17 },
3753 /* 3505 */ { MAD_F(0x067fcc68) /* 0.406200796 */, 17 },
3754 /* 3506 */ { MAD_F(0x06806e71) /* 0.406355326 */, 17 },
3755 /* 3507 */ { MAD_F(0x0681107e) /* 0.406509870 */, 17 },
3756 /* 3508 */ { MAD_F(0x0681b28f) /* 0.406664429 */, 17 },
3757 /* 3509 */ { MAD_F(0x068254a4) /* 0.406819003 */, 17 },
3758 /* 3510 */ { MAD_F(0x0682f6bd) /* 0.406973592 */, 17 },
3759 /* 3511 */ { MAD_F(0x068398da) /* 0.407128195 */, 17 },
3760 /* 3512 */ { MAD_F(0x06843afb) /* 0.407282813 */, 17 },
3761 /* 3513 */ { MAD_F(0x0684dd20) /* 0.407437445 */, 17 },
3762 /* 3514 */ { MAD_F(0x06857f49) /* 0.407592093 */, 17 },
3763 /* 3515 */ { MAD_F(0x06862176) /* 0.407746754 */, 17 },
3764 /* 3516 */ { MAD_F(0x0686c3a6) /* 0.407901431 */, 17 },
3765 /* 3517 */ { MAD_F(0x068765db) /* 0.408056122 */, 17 },
3766 /* 3518 */ { MAD_F(0x06880814) /* 0.408210828 */, 17 },
3767 /* 3519 */ { MAD_F(0x0688aa50) /* 0.408365549 */, 17 },
3768
3769 /* 3520 */ { MAD_F(0x06894c90) /* 0.408520284 */, 17 },
3770 /* 3521 */ { MAD_F(0x0689eed5) /* 0.408675034 */, 17 },
3771 /* 3522 */ { MAD_F(0x068a911d) /* 0.408829798 */, 17 },
3772 /* 3523 */ { MAD_F(0x068b3369) /* 0.408984577 */, 17 },
3773 /* 3524 */ { MAD_F(0x068bd5b9) /* 0.409139371 */, 17 },
3774 /* 3525 */ { MAD_F(0x068c780e) /* 0.409294180 */, 17 },
3775 /* 3526 */ { MAD_F(0x068d1a66) /* 0.409449003 */, 17 },
3776 /* 3527 */ { MAD_F(0x068dbcc1) /* 0.409603840 */, 17 },
3777 /* 3528 */ { MAD_F(0x068e5f21) /* 0.409758693 */, 17 },
3778 /* 3529 */ { MAD_F(0x068f0185) /* 0.409913560 */, 17 },
3779 /* 3530 */ { MAD_F(0x068fa3ed) /* 0.410068441 */, 17 },
3780 /* 3531 */ { MAD_F(0x06904658) /* 0.410223338 */, 17 },
3781 /* 3532 */ { MAD_F(0x0690e8c8) /* 0.410378249 */, 17 },
3782 /* 3533 */ { MAD_F(0x06918b3c) /* 0.410533174 */, 17 },
3783 /* 3534 */ { MAD_F(0x06922db3) /* 0.410688114 */, 17 },
3784 /* 3535 */ { MAD_F(0x0692d02e) /* 0.410843069 */, 17 },
3785
3786 /* 3536 */ { MAD_F(0x069372ae) /* 0.410998038 */, 17 },
3787 /* 3537 */ { MAD_F(0x06941531) /* 0.411153022 */, 17 },
3788 /* 3538 */ { MAD_F(0x0694b7b8) /* 0.411308021 */, 17 },
3789 /* 3539 */ { MAD_F(0x06955a43) /* 0.411463034 */, 17 },
3790 /* 3540 */ { MAD_F(0x0695fcd2) /* 0.411618062 */, 17 },
3791 /* 3541 */ { MAD_F(0x06969f65) /* 0.411773104 */, 17 },
3792 /* 3542 */ { MAD_F(0x069741fb) /* 0.411928161 */, 17 },
3793 /* 3543 */ { MAD_F(0x0697e496) /* 0.412083232 */, 17 },
3794 /* 3544 */ { MAD_F(0x06988735) /* 0.412238319 */, 17 },
3795 /* 3545 */ { MAD_F(0x069929d7) /* 0.412393419 */, 17 },
3796 /* 3546 */ { MAD_F(0x0699cc7e) /* 0.412548535 */, 17 },
3797 /* 3547 */ { MAD_F(0x069a6f28) /* 0.412703664 */, 17 },
3798 /* 3548 */ { MAD_F(0x069b11d6) /* 0.412858809 */, 17 },
3799 /* 3549 */ { MAD_F(0x069bb489) /* 0.413013968 */, 17 },
3800 /* 3550 */ { MAD_F(0x069c573f) /* 0.413169142 */, 17 },
3801 /* 3551 */ { MAD_F(0x069cf9f9) /* 0.413324330 */, 17 },
3802
3803 /* 3552 */ { MAD_F(0x069d9cb7) /* 0.413479532 */, 17 },
3804 /* 3553 */ { MAD_F(0x069e3f78) /* 0.413634750 */, 17 },
3805 /* 3554 */ { MAD_F(0x069ee23e) /* 0.413789982 */, 17 },
3806 /* 3555 */ { MAD_F(0x069f8508) /* 0.413945228 */, 17 },
3807 /* 3556 */ { MAD_F(0x06a027d5) /* 0.414100489 */, 17 },
3808 /* 3557 */ { MAD_F(0x06a0caa7) /* 0.414255765 */, 17 },
3809 /* 3558 */ { MAD_F(0x06a16d7c) /* 0.414411055 */, 17 },
3810 /* 3559 */ { MAD_F(0x06a21055) /* 0.414566359 */, 17 },
3811 /* 3560 */ { MAD_F(0x06a2b333) /* 0.414721679 */, 17 },
3812 /* 3561 */ { MAD_F(0x06a35614) /* 0.414877012 */, 17 },
3813 /* 3562 */ { MAD_F(0x06a3f8f9) /* 0.415032361 */, 17 },
3814 /* 3563 */ { MAD_F(0x06a49be2) /* 0.415187723 */, 17 },
3815 /* 3564 */ { MAD_F(0x06a53ece) /* 0.415343101 */, 17 },
3816 /* 3565 */ { MAD_F(0x06a5e1bf) /* 0.415498493 */, 17 },
3817 /* 3566 */ { MAD_F(0x06a684b4) /* 0.415653899 */, 17 },
3818 /* 3567 */ { MAD_F(0x06a727ac) /* 0.415809320 */, 17 },
3819
3820 /* 3568 */ { MAD_F(0x06a7caa9) /* 0.415964756 */, 17 },
3821 /* 3569 */ { MAD_F(0x06a86da9) /* 0.416120206 */, 17 },
3822 /* 3570 */ { MAD_F(0x06a910ad) /* 0.416275670 */, 17 },
3823 /* 3571 */ { MAD_F(0x06a9b3b5) /* 0.416431149 */, 17 },
3824 /* 3572 */ { MAD_F(0x06aa56c1) /* 0.416586643 */, 17 },
3825 /* 3573 */ { MAD_F(0x06aaf9d1) /* 0.416742151 */, 17 },
3826 /* 3574 */ { MAD_F(0x06ab9ce5) /* 0.416897673 */, 17 },
3827 /* 3575 */ { MAD_F(0x06ac3ffc) /* 0.417053210 */, 17 },
3828 /* 3576 */ { MAD_F(0x06ace318) /* 0.417208762 */, 17 },
3829 /* 3577 */ { MAD_F(0x06ad8637) /* 0.417364328 */, 17 },
3830 /* 3578 */ { MAD_F(0x06ae295b) /* 0.417519909 */, 17 },
3831 /* 3579 */ { MAD_F(0x06aecc82) /* 0.417675504 */, 17 },
3832 /* 3580 */ { MAD_F(0x06af6fad) /* 0.417831113 */, 17 },
3833 /* 3581 */ { MAD_F(0x06b012dc) /* 0.417986737 */, 17 },
3834 /* 3582 */ { MAD_F(0x06b0b60f) /* 0.418142376 */, 17 },
3835 /* 3583 */ { MAD_F(0x06b15946) /* 0.418298029 */, 17 },
3836
3837 /* 3584 */ { MAD_F(0x06b1fc81) /* 0.418453696 */, 17 },
3838 /* 3585 */ { MAD_F(0x06b29fbf) /* 0.418609378 */, 17 },
3839 /* 3586 */ { MAD_F(0x06b34302) /* 0.418765075 */, 17 },
3840 /* 3587 */ { MAD_F(0x06b3e648) /* 0.418920786 */, 17 },
3841 /* 3588 */ { MAD_F(0x06b48992) /* 0.419076511 */, 17 },
3842 /* 3589 */ { MAD_F(0x06b52ce0) /* 0.419232251 */, 17 },
3843 /* 3590 */ { MAD_F(0x06b5d032) /* 0.419388005 */, 17 },
3844 /* 3591 */ { MAD_F(0x06b67388) /* 0.419543774 */, 17 },
3845 /* 3592 */ { MAD_F(0x06b716e2) /* 0.419699557 */, 17 },
3846 /* 3593 */ { MAD_F(0x06b7ba3f) /* 0.419855355 */, 17 },
3847 /* 3594 */ { MAD_F(0x06b85da1) /* 0.420011167 */, 17 },
3848 /* 3595 */ { MAD_F(0x06b90106) /* 0.420166994 */, 17 },
3849 /* 3596 */ { MAD_F(0x06b9a470) /* 0.420322835 */, 17 },
3850 /* 3597 */ { MAD_F(0x06ba47dd) /* 0.420478690 */, 17 },
3851 /* 3598 */ { MAD_F(0x06baeb4e) /* 0.420634560 */, 17 },
3852 /* 3599 */ { MAD_F(0x06bb8ec3) /* 0.420790445 */, 17 },
3853
3854 /* 3600 */ { MAD_F(0x06bc323b) /* 0.420946343 */, 17 },
3855 /* 3601 */ { MAD_F(0x06bcd5b8) /* 0.421102257 */, 17 },
3856 /* 3602 */ { MAD_F(0x06bd7939) /* 0.421258184 */, 17 },
3857 /* 3603 */ { MAD_F(0x06be1cbd) /* 0.421414127 */, 17 },
3858 /* 3604 */ { MAD_F(0x06bec045) /* 0.421570083 */, 17 },
3859 /* 3605 */ { MAD_F(0x06bf63d1) /* 0.421726054 */, 17 },
3860 /* 3606 */ { MAD_F(0x06c00761) /* 0.421882040 */, 17 },
3861 /* 3607 */ { MAD_F(0x06c0aaf5) /* 0.422038039 */, 17 },
3862 /* 3608 */ { MAD_F(0x06c14e8d) /* 0.422194054 */, 17 },
3863 /* 3609 */ { MAD_F(0x06c1f229) /* 0.422350082 */, 17 },
3864 /* 3610 */ { MAD_F(0x06c295c8) /* 0.422506125 */, 17 },
3865 /* 3611 */ { MAD_F(0x06c3396c) /* 0.422662183 */, 17 },
3866 /* 3612 */ { MAD_F(0x06c3dd13) /* 0.422818255 */, 17 },
3867 /* 3613 */ { MAD_F(0x06c480be) /* 0.422974341 */, 17 },
3868 /* 3614 */ { MAD_F(0x06c5246d) /* 0.423130442 */, 17 },
3869 /* 3615 */ { MAD_F(0x06c5c820) /* 0.423286557 */, 17 },
3870
3871 /* 3616 */ { MAD_F(0x06c66bd6) /* 0.423442686 */, 17 },
3872 /* 3617 */ { MAD_F(0x06c70f91) /* 0.423598830 */, 17 },
3873 /* 3618 */ { MAD_F(0x06c7b34f) /* 0.423754988 */, 17 },
3874 /* 3619 */ { MAD_F(0x06c85712) /* 0.423911161 */, 17 },
3875 /* 3620 */ { MAD_F(0x06c8fad8) /* 0.424067348 */, 17 },
3876 /* 3621 */ { MAD_F(0x06c99ea2) /* 0.424223550 */, 17 },
3877 /* 3622 */ { MAD_F(0x06ca4270) /* 0.424379765 */, 17 },
3878 /* 3623 */ { MAD_F(0x06cae641) /* 0.424535996 */, 17 },
3879 /* 3624 */ { MAD_F(0x06cb8a17) /* 0.424692240 */, 17 },
3880 /* 3625 */ { MAD_F(0x06cc2df0) /* 0.424848499 */, 17 },
3881 /* 3626 */ { MAD_F(0x06ccd1ce) /* 0.425004772 */, 17 },
3882 /* 3627 */ { MAD_F(0x06cd75af) /* 0.425161060 */, 17 },
3883 /* 3628 */ { MAD_F(0x06ce1994) /* 0.425317362 */, 17 },
3884 /* 3629 */ { MAD_F(0x06cebd7d) /* 0.425473678 */, 17 },
3885 /* 3630 */ { MAD_F(0x06cf6169) /* 0.425630009 */, 17 },
3886 /* 3631 */ { MAD_F(0x06d0055a) /* 0.425786354 */, 17 },
3887
3888 /* 3632 */ { MAD_F(0x06d0a94e) /* 0.425942714 */, 17 },
3889 /* 3633 */ { MAD_F(0x06d14d47) /* 0.426099088 */, 17 },
3890 /* 3634 */ { MAD_F(0x06d1f143) /* 0.426255476 */, 17 },
3891 /* 3635 */ { MAD_F(0x06d29543) /* 0.426411878 */, 17 },
3892 /* 3636 */ { MAD_F(0x06d33947) /* 0.426568295 */, 17 },
3893 /* 3637 */ { MAD_F(0x06d3dd4e) /* 0.426724726 */, 17 },
3894 /* 3638 */ { MAD_F(0x06d4815a) /* 0.426881172 */, 17 },
3895 /* 3639 */ { MAD_F(0x06d52569) /* 0.427037632 */, 17 },
3896 /* 3640 */ { MAD_F(0x06d5c97c) /* 0.427194106 */, 17 },
3897 /* 3641 */ { MAD_F(0x06d66d93) /* 0.427350594 */, 17 },
3898 /* 3642 */ { MAD_F(0x06d711ae) /* 0.427507097 */, 17 },
3899 /* 3643 */ { MAD_F(0x06d7b5cd) /* 0.427663614 */, 17 },
3900 /* 3644 */ { MAD_F(0x06d859f0) /* 0.427820146 */, 17 },
3901 /* 3645 */ { MAD_F(0x06d8fe16) /* 0.427976692 */, 17 },
3902 /* 3646 */ { MAD_F(0x06d9a240) /* 0.428133252 */, 17 },
3903 /* 3647 */ { MAD_F(0x06da466f) /* 0.428289826 */, 17 },
3904
3905 /* 3648 */ { MAD_F(0x06daeaa1) /* 0.428446415 */, 17 },
3906 /* 3649 */ { MAD_F(0x06db8ed6) /* 0.428603018 */, 17 },
3907 /* 3650 */ { MAD_F(0x06dc3310) /* 0.428759635 */, 17 },
3908 /* 3651 */ { MAD_F(0x06dcd74d) /* 0.428916267 */, 17 },
3909 /* 3652 */ { MAD_F(0x06dd7b8f) /* 0.429072913 */, 17 },
3910 /* 3653 */ { MAD_F(0x06de1fd4) /* 0.429229573 */, 17 },
3911 /* 3654 */ { MAD_F(0x06dec41d) /* 0.429386248 */, 17 },
3912 /* 3655 */ { MAD_F(0x06df686a) /* 0.429542937 */, 17 },
3913 /* 3656 */ { MAD_F(0x06e00cbb) /* 0.429699640 */, 17 },
3914 /* 3657 */ { MAD_F(0x06e0b10f) /* 0.429856357 */, 17 },
3915 /* 3658 */ { MAD_F(0x06e15567) /* 0.430013089 */, 17 },
3916 /* 3659 */ { MAD_F(0x06e1f9c4) /* 0.430169835 */, 17 },
3917 /* 3660 */ { MAD_F(0x06e29e24) /* 0.430326595 */, 17 },
3918 /* 3661 */ { MAD_F(0x06e34287) /* 0.430483370 */, 17 },
3919 /* 3662 */ { MAD_F(0x06e3e6ef) /* 0.430640159 */, 17 },
3920 /* 3663 */ { MAD_F(0x06e48b5b) /* 0.430796962 */, 17 },
3921
3922 /* 3664 */ { MAD_F(0x06e52fca) /* 0.430953779 */, 17 },
3923 /* 3665 */ { MAD_F(0x06e5d43d) /* 0.431110611 */, 17 },
3924 /* 3666 */ { MAD_F(0x06e678b4) /* 0.431267457 */, 17 },
3925 /* 3667 */ { MAD_F(0x06e71d2f) /* 0.431424317 */, 17 },
3926 /* 3668 */ { MAD_F(0x06e7c1ae) /* 0.431581192 */, 17 },
3927 /* 3669 */ { MAD_F(0x06e86630) /* 0.431738080 */, 17 },
3928 /* 3670 */ { MAD_F(0x06e90ab7) /* 0.431894983 */, 17 },
3929 /* 3671 */ { MAD_F(0x06e9af41) /* 0.432051900 */, 17 },
3930 /* 3672 */ { MAD_F(0x06ea53cf) /* 0.432208832 */, 17 },
3931 /* 3673 */ { MAD_F(0x06eaf860) /* 0.432365778 */, 17 },
3932 /* 3674 */ { MAD_F(0x06eb9cf6) /* 0.432522737 */, 17 },
3933 /* 3675 */ { MAD_F(0x06ec418f) /* 0.432679712 */, 17 },
3934 /* 3676 */ { MAD_F(0x06ece62d) /* 0.432836700 */, 17 },
3935 /* 3677 */ { MAD_F(0x06ed8ace) /* 0.432993703 */, 17 },
3936 /* 3678 */ { MAD_F(0x06ee2f73) /* 0.433150720 */, 17 },
3937 /* 3679 */ { MAD_F(0x06eed41b) /* 0.433307751 */, 17 },
3938
3939 /* 3680 */ { MAD_F(0x06ef78c8) /* 0.433464796 */, 17 },
3940 /* 3681 */ { MAD_F(0x06f01d78) /* 0.433621856 */, 17 },
3941 /* 3682 */ { MAD_F(0x06f0c22c) /* 0.433778929 */, 17 },
3942 /* 3683 */ { MAD_F(0x06f166e4) /* 0.433936017 */, 17 },
3943 /* 3684 */ { MAD_F(0x06f20ba0) /* 0.434093120 */, 17 },
3944 /* 3685 */ { MAD_F(0x06f2b060) /* 0.434250236 */, 17 },
3945 /* 3686 */ { MAD_F(0x06f35523) /* 0.434407367 */, 17 },
3946 /* 3687 */ { MAD_F(0x06f3f9eb) /* 0.434564512 */, 17 },
3947 /* 3688 */ { MAD_F(0x06f49eb6) /* 0.434721671 */, 17 },
3948 /* 3689 */ { MAD_F(0x06f54385) /* 0.434878844 */, 17 },
3949 /* 3690 */ { MAD_F(0x06f5e857) /* 0.435036032 */, 17 },
3950 /* 3691 */ { MAD_F(0x06f68d2e) /* 0.435193233 */, 17 },
3951 /* 3692 */ { MAD_F(0x06f73208) /* 0.435350449 */, 17 },
3952 /* 3693 */ { MAD_F(0x06f7d6e6) /* 0.435507679 */, 17 },
3953 /* 3694 */ { MAD_F(0x06f87bc8) /* 0.435664924 */, 17 },
3954 /* 3695 */ { MAD_F(0x06f920ae) /* 0.435822182 */, 17 },
3955
3956 /* 3696 */ { MAD_F(0x06f9c597) /* 0.435979455 */, 17 },
3957 /* 3697 */ { MAD_F(0x06fa6a85) /* 0.436136741 */, 17 },
3958 /* 3698 */ { MAD_F(0x06fb0f76) /* 0.436294042 */, 17 },
3959 /* 3699 */ { MAD_F(0x06fbb46b) /* 0.436451358 */, 17 },
3960 /* 3700 */ { MAD_F(0x06fc5964) /* 0.436608687 */, 17 },
3961 /* 3701 */ { MAD_F(0x06fcfe60) /* 0.436766031 */, 17 },
3962 /* 3702 */ { MAD_F(0x06fda361) /* 0.436923388 */, 17 },
3963 /* 3703 */ { MAD_F(0x06fe4865) /* 0.437080760 */, 17 },
3964 /* 3704 */ { MAD_F(0x06feed6d) /* 0.437238146 */, 17 },
3965 /* 3705 */ { MAD_F(0x06ff9279) /* 0.437395547 */, 17 },
3966 /* 3706 */ { MAD_F(0x07003788) /* 0.437552961 */, 17 },
3967 /* 3707 */ { MAD_F(0x0700dc9c) /* 0.437710389 */, 17 },
3968 /* 3708 */ { MAD_F(0x070181b3) /* 0.437867832 */, 17 },
3969 /* 3709 */ { MAD_F(0x070226ce) /* 0.438025289 */, 17 },
3970 /* 3710 */ { MAD_F(0x0702cbed) /* 0.438182760 */, 17 },
3971 /* 3711 */ { MAD_F(0x0703710f) /* 0.438340245 */, 17 },
3972
3973 /* 3712 */ { MAD_F(0x07041636) /* 0.438497744 */, 17 },
3974 /* 3713 */ { MAD_F(0x0704bb60) /* 0.438655258 */, 17 },
3975 /* 3714 */ { MAD_F(0x0705608e) /* 0.438812785 */, 17 },
3976 /* 3715 */ { MAD_F(0x070605c0) /* 0.438970327 */, 17 },
3977 /* 3716 */ { MAD_F(0x0706aaf5) /* 0.439127883 */, 17 },
3978 /* 3717 */ { MAD_F(0x0707502f) /* 0.439285453 */, 17 },
3979 /* 3718 */ { MAD_F(0x0707f56c) /* 0.439443037 */, 17 },
3980 /* 3719 */ { MAD_F(0x07089aad) /* 0.439600635 */, 17 },
3981 /* 3720 */ { MAD_F(0x07093ff2) /* 0.439758248 */, 17 },
3982 /* 3721 */ { MAD_F(0x0709e53a) /* 0.439915874 */, 17 },
3983 /* 3722 */ { MAD_F(0x070a8a86) /* 0.440073515 */, 17 },
3984 /* 3723 */ { MAD_F(0x070b2fd7) /* 0.440231170 */, 17 },
3985 /* 3724 */ { MAD_F(0x070bd52a) /* 0.440388839 */, 17 },
3986 /* 3725 */ { MAD_F(0x070c7a82) /* 0.440546522 */, 17 },
3987 /* 3726 */ { MAD_F(0x070d1fde) /* 0.440704219 */, 17 },
3988 /* 3727 */ { MAD_F(0x070dc53d) /* 0.440861930 */, 17 },
3989
3990 /* 3728 */ { MAD_F(0x070e6aa0) /* 0.441019655 */, 17 },
3991 /* 3729 */ { MAD_F(0x070f1007) /* 0.441177395 */, 17 },
3992 /* 3730 */ { MAD_F(0x070fb571) /* 0.441335148 */, 17 },
3993 /* 3731 */ { MAD_F(0x07105ae0) /* 0.441492916 */, 17 },
3994 /* 3732 */ { MAD_F(0x07110052) /* 0.441650697 */, 17 },
3995 /* 3733 */ { MAD_F(0x0711a5c8) /* 0.441808493 */, 17 },
3996 /* 3734 */ { MAD_F(0x07124b42) /* 0.441966303 */, 17 },
3997 /* 3735 */ { MAD_F(0x0712f0bf) /* 0.442124127 */, 17 },
3998 /* 3736 */ { MAD_F(0x07139641) /* 0.442281965 */, 17 },
3999 /* 3737 */ { MAD_F(0x07143bc6) /* 0.442439817 */, 17 },
4000 /* 3738 */ { MAD_F(0x0714e14f) /* 0.442597683 */, 17 },
4001 /* 3739 */ { MAD_F(0x071586db) /* 0.442755564 */, 17 },
4002 /* 3740 */ { MAD_F(0x07162c6c) /* 0.442913458 */, 17 },
4003 /* 3741 */ { MAD_F(0x0716d200) /* 0.443071366 */, 17 },
4004 /* 3742 */ { MAD_F(0x07177798) /* 0.443229289 */, 17 },
4005 /* 3743 */ { MAD_F(0x07181d34) /* 0.443387226 */, 17 },
4006
4007 /* 3744 */ { MAD_F(0x0718c2d3) /* 0.443545176 */, 17 },
4008 /* 3745 */ { MAD_F(0x07196877) /* 0.443703141 */, 17 },
4009 /* 3746 */ { MAD_F(0x071a0e1e) /* 0.443861120 */, 17 },
4010 /* 3747 */ { MAD_F(0x071ab3c9) /* 0.444019113 */, 17 },
4011 /* 3748 */ { MAD_F(0x071b5977) /* 0.444177119 */, 17 },
4012 /* 3749 */ { MAD_F(0x071bff2a) /* 0.444335140 */, 17 },
4013 /* 3750 */ { MAD_F(0x071ca4e0) /* 0.444493175 */, 17 },
4014 /* 3751 */ { MAD_F(0x071d4a9a) /* 0.444651224 */, 17 },
4015 /* 3752 */ { MAD_F(0x071df058) /* 0.444809288 */, 17 },
4016 /* 3753 */ { MAD_F(0x071e9619) /* 0.444967365 */, 17 },
4017 /* 3754 */ { MAD_F(0x071f3bde) /* 0.445125456 */, 17 },
4018 /* 3755 */ { MAD_F(0x071fe1a8) /* 0.445283561 */, 17 },
4019 /* 3756 */ { MAD_F(0x07208774) /* 0.445441680 */, 17 },
4020 /* 3757 */ { MAD_F(0x07212d45) /* 0.445599814 */, 17 },
4021 /* 3758 */ { MAD_F(0x0721d319) /* 0.445757961 */, 17 },
4022 /* 3759 */ { MAD_F(0x072278f1) /* 0.445916122 */, 17 },
4023
4024 /* 3760 */ { MAD_F(0x07231ecd) /* 0.446074298 */, 17 },
4025 /* 3761 */ { MAD_F(0x0723c4ad) /* 0.446232487 */, 17 },
4026 /* 3762 */ { MAD_F(0x07246a90) /* 0.446390690 */, 17 },
4027 /* 3763 */ { MAD_F(0x07251077) /* 0.446548908 */, 17 },
4028 /* 3764 */ { MAD_F(0x0725b662) /* 0.446707139 */, 17 },
4029 /* 3765 */ { MAD_F(0x07265c51) /* 0.446865385 */, 17 },
4030 /* 3766 */ { MAD_F(0x07270244) /* 0.447023644 */, 17 },
4031 /* 3767 */ { MAD_F(0x0727a83a) /* 0.447181918 */, 17 },
4032 /* 3768 */ { MAD_F(0x07284e34) /* 0.447340205 */, 17 },
4033 /* 3769 */ { MAD_F(0x0728f431) /* 0.447498507 */, 17 },
4034 /* 3770 */ { MAD_F(0x07299a33) /* 0.447656822 */, 17 },
4035 /* 3771 */ { MAD_F(0x072a4038) /* 0.447815152 */, 17 },
4036 /* 3772 */ { MAD_F(0x072ae641) /* 0.447973495 */, 17 },
4037 /* 3773 */ { MAD_F(0x072b8c4e) /* 0.448131853 */, 17 },
4038 /* 3774 */ { MAD_F(0x072c325e) /* 0.448290224 */, 17 },
4039 /* 3775 */ { MAD_F(0x072cd873) /* 0.448448609 */, 17 },
4040
4041 /* 3776 */ { MAD_F(0x072d7e8b) /* 0.448607009 */, 17 },
4042 /* 3777 */ { MAD_F(0x072e24a7) /* 0.448765422 */, 17 },
4043 /* 3778 */ { MAD_F(0x072ecac6) /* 0.448923850 */, 17 },
4044 /* 3779 */ { MAD_F(0x072f70e9) /* 0.449082291 */, 17 },
4045 /* 3780 */ { MAD_F(0x07301710) /* 0.449240746 */, 17 },
4046 /* 3781 */ { MAD_F(0x0730bd3b) /* 0.449399216 */, 17 },
4047 /* 3782 */ { MAD_F(0x0731636a) /* 0.449557699 */, 17 },
4048 /* 3783 */ { MAD_F(0x0732099c) /* 0.449716196 */, 17 },
4049 /* 3784 */ { MAD_F(0x0732afd2) /* 0.449874708 */, 17 },
4050 /* 3785 */ { MAD_F(0x0733560c) /* 0.450033233 */, 17 },
4051 /* 3786 */ { MAD_F(0x0733fc49) /* 0.450191772 */, 17 },
4052 /* 3787 */ { MAD_F(0x0734a28b) /* 0.450350325 */, 17 },
4053 /* 3788 */ { MAD_F(0x073548d0) /* 0.450508892 */, 17 },
4054 /* 3789 */ { MAD_F(0x0735ef18) /* 0.450667473 */, 17 },
4055 /* 3790 */ { MAD_F(0x07369565) /* 0.450826068 */, 17 },
4056 /* 3791 */ { MAD_F(0x07373bb5) /* 0.450984677 */, 17 },
4057
4058 /* 3792 */ { MAD_F(0x0737e209) /* 0.451143300 */, 17 },
4059 /* 3793 */ { MAD_F(0x07388861) /* 0.451301937 */, 17 },
4060 /* 3794 */ { MAD_F(0x07392ebc) /* 0.451460588 */, 17 },
4061 /* 3795 */ { MAD_F(0x0739d51c) /* 0.451619252 */, 17 },
4062 /* 3796 */ { MAD_F(0x073a7b7f) /* 0.451777931 */, 17 },
4063 /* 3797 */ { MAD_F(0x073b21e5) /* 0.451936623 */, 17 },
4064 /* 3798 */ { MAD_F(0x073bc850) /* 0.452095330 */, 17 },
4065 /* 3799 */ { MAD_F(0x073c6ebe) /* 0.452254050 */, 17 },
4066 /* 3800 */ { MAD_F(0x073d1530) /* 0.452412785 */, 17 },
4067 /* 3801 */ { MAD_F(0x073dbba6) /* 0.452571533 */, 17 },
4068 /* 3802 */ { MAD_F(0x073e621f) /* 0.452730295 */, 17 },
4069 /* 3803 */ { MAD_F(0x073f089c) /* 0.452889071 */, 17 },
4070 /* 3804 */ { MAD_F(0x073faf1d) /* 0.453047861 */, 17 },
4071 /* 3805 */ { MAD_F(0x074055a2) /* 0.453206665 */, 17 },
4072 /* 3806 */ { MAD_F(0x0740fc2a) /* 0.453365483 */, 17 },
4073 /* 3807 */ { MAD_F(0x0741a2b6) /* 0.453524315 */, 17 },
4074
4075 /* 3808 */ { MAD_F(0x07424946) /* 0.453683161 */, 17 },
4076 /* 3809 */ { MAD_F(0x0742efd9) /* 0.453842020 */, 17 },
4077 /* 3810 */ { MAD_F(0x07439671) /* 0.454000894 */, 17 },
4078 /* 3811 */ { MAD_F(0x07443d0c) /* 0.454159781 */, 17 },
4079 /* 3812 */ { MAD_F(0x0744e3aa) /* 0.454318683 */, 17 },
4080 /* 3813 */ { MAD_F(0x07458a4d) /* 0.454477598 */, 17 },
4081 /* 3814 */ { MAD_F(0x074630f3) /* 0.454636527 */, 17 },
4082 /* 3815 */ { MAD_F(0x0746d79d) /* 0.454795470 */, 17 },
4083 /* 3816 */ { MAD_F(0x07477e4b) /* 0.454954427 */, 17 },
4084 /* 3817 */ { MAD_F(0x074824fc) /* 0.455113397 */, 17 },
4085 /* 3818 */ { MAD_F(0x0748cbb1) /* 0.455272382 */, 17 },
4086 /* 3819 */ { MAD_F(0x0749726a) /* 0.455431381 */, 17 },
4087 /* 3820 */ { MAD_F(0x074a1927) /* 0.455590393 */, 17 },
4088 /* 3821 */ { MAD_F(0x074abfe7) /* 0.455749419 */, 17 },
4089 /* 3822 */ { MAD_F(0x074b66ab) /* 0.455908459 */, 17 },
4090 /* 3823 */ { MAD_F(0x074c0d73) /* 0.456067513 */, 17 },
4091
4092 /* 3824 */ { MAD_F(0x074cb43e) /* 0.456226581 */, 17 },
4093 /* 3825 */ { MAD_F(0x074d5b0d) /* 0.456385663 */, 17 },
4094 /* 3826 */ { MAD_F(0x074e01e0) /* 0.456544759 */, 17 },
4095 /* 3827 */ { MAD_F(0x074ea8b7) /* 0.456703868 */, 17 },
4096 /* 3828 */ { MAD_F(0x074f4f91) /* 0.456862992 */, 17 },
4097 /* 3829 */ { MAD_F(0x074ff66f) /* 0.457022129 */, 17 },
4098 /* 3830 */ { MAD_F(0x07509d51) /* 0.457181280 */, 17 },
4099 /* 3831 */ { MAD_F(0x07514437) /* 0.457340445 */, 17 },
4100 /* 3832 */ { MAD_F(0x0751eb20) /* 0.457499623 */, 17 },
4101 /* 3833 */ { MAD_F(0x0752920d) /* 0.457658816 */, 17 },
4102 /* 3834 */ { MAD_F(0x075338fd) /* 0.457818022 */, 17 },
4103 /* 3835 */ { MAD_F(0x0753dff2) /* 0.457977243 */, 17 },
4104 /* 3836 */ { MAD_F(0x075486ea) /* 0.458136477 */, 17 },
4105 /* 3837 */ { MAD_F(0x07552de6) /* 0.458295725 */, 17 },
4106 /* 3838 */ { MAD_F(0x0755d4e5) /* 0.458454987 */, 17 },
4107 /* 3839 */ { MAD_F(0x07567be8) /* 0.458614262 */, 17 },
4108
4109 /* 3840 */ { MAD_F(0x075722ef) /* 0.458773552 */, 17 },
4110 /* 3841 */ { MAD_F(0x0757c9fa) /* 0.458932855 */, 17 },
4111 /* 3842 */ { MAD_F(0x07587108) /* 0.459092172 */, 17 },
4112 /* 3843 */ { MAD_F(0x0759181a) /* 0.459251503 */, 17 },
4113 /* 3844 */ { MAD_F(0x0759bf30) /* 0.459410848 */, 17 },
4114 /* 3845 */ { MAD_F(0x075a664a) /* 0.459570206 */, 17 },
4115 /* 3846 */ { MAD_F(0x075b0d67) /* 0.459729579 */, 17 },
4116 /* 3847 */ { MAD_F(0x075bb488) /* 0.459888965 */, 17 },
4117 /* 3848 */ { MAD_F(0x075c5bac) /* 0.460048365 */, 17 },
4118 /* 3849 */ { MAD_F(0x075d02d5) /* 0.460207779 */, 17 },
4119 /* 3850 */ { MAD_F(0x075daa01) /* 0.460367206 */, 17 },
4120 /* 3851 */ { MAD_F(0x075e5130) /* 0.460526648 */, 17 },
4121 /* 3852 */ { MAD_F(0x075ef864) /* 0.460686103 */, 17 },
4122 /* 3853 */ { MAD_F(0x075f9f9b) /* 0.460845572 */, 17 },
4123 /* 3854 */ { MAD_F(0x076046d6) /* 0.461005055 */, 17 },
4124 /* 3855 */ { MAD_F(0x0760ee14) /* 0.461164552 */, 17 },
4125
4126 /* 3856 */ { MAD_F(0x07619557) /* 0.461324062 */, 17 },
4127 /* 3857 */ { MAD_F(0x07623c9d) /* 0.461483586 */, 17 },
4128 /* 3858 */ { MAD_F(0x0762e3e6) /* 0.461643124 */, 17 },
4129 /* 3859 */ { MAD_F(0x07638b34) /* 0.461802676 */, 17 },
4130 /* 3860 */ { MAD_F(0x07643285) /* 0.461962242 */, 17 },
4131 /* 3861 */ { MAD_F(0x0764d9d9) /* 0.462121821 */, 17 },
4132 /* 3862 */ { MAD_F(0x07658132) /* 0.462281414 */, 17 },
4133 /* 3863 */ { MAD_F(0x0766288e) /* 0.462441021 */, 17 },
4134 /* 3864 */ { MAD_F(0x0766cfee) /* 0.462600642 */, 17 },
4135 /* 3865 */ { MAD_F(0x07677751) /* 0.462760276 */, 17 },
4136 /* 3866 */ { MAD_F(0x07681eb9) /* 0.462919924 */, 17 },
4137 /* 3867 */ { MAD_F(0x0768c624) /* 0.463079586 */, 17 },
4138 /* 3868 */ { MAD_F(0x07696d92) /* 0.463239262 */, 17 },
4139 /* 3869 */ { MAD_F(0x076a1505) /* 0.463398951 */, 17 },
4140 /* 3870 */ { MAD_F(0x076abc7b) /* 0.463558655 */, 17 },
4141 /* 3871 */ { MAD_F(0x076b63f4) /* 0.463718372 */, 17 },
4142
4143 /* 3872 */ { MAD_F(0x076c0b72) /* 0.463878102 */, 17 },
4144 /* 3873 */ { MAD_F(0x076cb2f3) /* 0.464037847 */, 17 },
4145 /* 3874 */ { MAD_F(0x076d5a78) /* 0.464197605 */, 17 },
4146 /* 3875 */ { MAD_F(0x076e0200) /* 0.464357377 */, 17 },
4147 /* 3876 */ { MAD_F(0x076ea98c) /* 0.464517163 */, 17 },
4148 /* 3877 */ { MAD_F(0x076f511c) /* 0.464676962 */, 17 },
4149 /* 3878 */ { MAD_F(0x076ff8b0) /* 0.464836776 */, 17 },
4150 /* 3879 */ { MAD_F(0x0770a047) /* 0.464996603 */, 17 },
4151 /* 3880 */ { MAD_F(0x077147e2) /* 0.465156443 */, 17 },
4152 /* 3881 */ { MAD_F(0x0771ef80) /* 0.465316298 */, 17 },
4153 /* 3882 */ { MAD_F(0x07729723) /* 0.465476166 */, 17 },
4154 /* 3883 */ { MAD_F(0x07733ec9) /* 0.465636048 */, 17 },
4155 /* 3884 */ { MAD_F(0x0773e672) /* 0.465795943 */, 17 },
4156 /* 3885 */ { MAD_F(0x07748e20) /* 0.465955853 */, 17 },
4157 /* 3886 */ { MAD_F(0x077535d1) /* 0.466115776 */, 17 },
4158 /* 3887 */ { MAD_F(0x0775dd85) /* 0.466275713 */, 17 },
4159
4160 /* 3888 */ { MAD_F(0x0776853e) /* 0.466435663 */, 17 },
4161 /* 3889 */ { MAD_F(0x07772cfa) /* 0.466595627 */, 17 },
4162 /* 3890 */ { MAD_F(0x0777d4ba) /* 0.466755605 */, 17 },
4163 /* 3891 */ { MAD_F(0x07787c7d) /* 0.466915597 */, 17 },
4164 /* 3892 */ { MAD_F(0x07792444) /* 0.467075602 */, 17 },
4165 /* 3893 */ { MAD_F(0x0779cc0f) /* 0.467235621 */, 17 },
4166 /* 3894 */ { MAD_F(0x077a73dd) /* 0.467395654 */, 17 },
4167 /* 3895 */ { MAD_F(0x077b1baf) /* 0.467555701 */, 17 },
4168 /* 3896 */ { MAD_F(0x077bc385) /* 0.467715761 */, 17 },
4169 /* 3897 */ { MAD_F(0x077c6b5f) /* 0.467875835 */, 17 },
4170 /* 3898 */ { MAD_F(0x077d133c) /* 0.468035922 */, 17 },
4171 /* 3899 */ { MAD_F(0x077dbb1d) /* 0.468196023 */, 17 },
4172 /* 3900 */ { MAD_F(0x077e6301) /* 0.468356138 */, 17 },
4173 /* 3901 */ { MAD_F(0x077f0ae9) /* 0.468516267 */, 17 },
4174 /* 3902 */ { MAD_F(0x077fb2d5) /* 0.468676409 */, 17 },
4175 /* 3903 */ { MAD_F(0x07805ac5) /* 0.468836565 */, 17 },
4176
4177 /* 3904 */ { MAD_F(0x078102b8) /* 0.468996735 */, 17 },
4178 /* 3905 */ { MAD_F(0x0781aaaf) /* 0.469156918 */, 17 },
4179 /* 3906 */ { MAD_F(0x078252aa) /* 0.469317115 */, 17 },
4180 /* 3907 */ { MAD_F(0x0782faa8) /* 0.469477326 */, 17 },
4181 /* 3908 */ { MAD_F(0x0783a2aa) /* 0.469637550 */, 17 },
4182 /* 3909 */ { MAD_F(0x07844aaf) /* 0.469797788 */, 17 },
4183 /* 3910 */ { MAD_F(0x0784f2b8) /* 0.469958040 */, 17 },
4184 /* 3911 */ { MAD_F(0x07859ac5) /* 0.470118305 */, 17 },
4185 /* 3912 */ { MAD_F(0x078642d6) /* 0.470278584 */, 17 },
4186 /* 3913 */ { MAD_F(0x0786eaea) /* 0.470438877 */, 17 },
4187 /* 3914 */ { MAD_F(0x07879302) /* 0.470599183 */, 17 },
4188 /* 3915 */ { MAD_F(0x07883b1e) /* 0.470759503 */, 17 },
4189 /* 3916 */ { MAD_F(0x0788e33d) /* 0.470919836 */, 17 },
4190 /* 3917 */ { MAD_F(0x07898b60) /* 0.471080184 */, 17 },
4191 /* 3918 */ { MAD_F(0x078a3386) /* 0.471240545 */, 17 },
4192 /* 3919 */ { MAD_F(0x078adbb0) /* 0.471400919 */, 17 },
4193
4194 /* 3920 */ { MAD_F(0x078b83de) /* 0.471561307 */, 17 },
4195 /* 3921 */ { MAD_F(0x078c2c10) /* 0.471721709 */, 17 },
4196 /* 3922 */ { MAD_F(0x078cd445) /* 0.471882125 */, 17 },
4197 /* 3923 */ { MAD_F(0x078d7c7e) /* 0.472042554 */, 17 },
4198 /* 3924 */ { MAD_F(0x078e24ba) /* 0.472202996 */, 17 },
4199 /* 3925 */ { MAD_F(0x078eccfb) /* 0.472363453 */, 17 },
4200 /* 3926 */ { MAD_F(0x078f753e) /* 0.472523923 */, 17 },
4201 /* 3927 */ { MAD_F(0x07901d86) /* 0.472684406 */, 17 },
4202 /* 3928 */ { MAD_F(0x0790c5d1) /* 0.472844904 */, 17 },
4203 /* 3929 */ { MAD_F(0x07916e20) /* 0.473005414 */, 17 },
4204 /* 3930 */ { MAD_F(0x07921672) /* 0.473165939 */, 17 },
4205 /* 3931 */ { MAD_F(0x0792bec8) /* 0.473326477 */, 17 },
4206 /* 3932 */ { MAD_F(0x07936722) /* 0.473487029 */, 17 },
4207 /* 3933 */ { MAD_F(0x07940f80) /* 0.473647594 */, 17 },
4208 /* 3934 */ { MAD_F(0x0794b7e1) /* 0.473808173 */, 17 },
4209 /* 3935 */ { MAD_F(0x07956045) /* 0.473968765 */, 17 },
4210
4211 /* 3936 */ { MAD_F(0x079608ae) /* 0.474129372 */, 17 },
4212 /* 3937 */ { MAD_F(0x0796b11a) /* 0.474289991 */, 17 },
4213 /* 3938 */ { MAD_F(0x0797598a) /* 0.474450625 */, 17 },
4214 /* 3939 */ { MAD_F(0x079801fd) /* 0.474611272 */, 17 },
4215 /* 3940 */ { MAD_F(0x0798aa74) /* 0.474771932 */, 17 },
4216 /* 3941 */ { MAD_F(0x079952ee) /* 0.474932606 */, 17 },
4217 /* 3942 */ { MAD_F(0x0799fb6d) /* 0.475093294 */, 17 },
4218 /* 3943 */ { MAD_F(0x079aa3ef) /* 0.475253995 */, 17 },
4219 /* 3944 */ { MAD_F(0x079b4c74) /* 0.475414710 */, 17 },
4220 /* 3945 */ { MAD_F(0x079bf4fd) /* 0.475575439 */, 17 },
4221 /* 3946 */ { MAD_F(0x079c9d8a) /* 0.475736181 */, 17 },
4222 /* 3947 */ { MAD_F(0x079d461b) /* 0.475896936 */, 17 },
4223 /* 3948 */ { MAD_F(0x079deeaf) /* 0.476057705 */, 17 },
4224 /* 3949 */ { MAD_F(0x079e9747) /* 0.476218488 */, 17 },
4225 /* 3950 */ { MAD_F(0x079f3fe2) /* 0.476379285 */, 17 },
4226 /* 3951 */ { MAD_F(0x079fe881) /* 0.476540095 */, 17 },
4227
4228 /* 3952 */ { MAD_F(0x07a09124) /* 0.476700918 */, 17 },
4229 /* 3953 */ { MAD_F(0x07a139ca) /* 0.476861755 */, 17 },
4230 /* 3954 */ { MAD_F(0x07a1e274) /* 0.477022606 */, 17 },
4231 /* 3955 */ { MAD_F(0x07a28b22) /* 0.477183470 */, 17 },
4232 /* 3956 */ { MAD_F(0x07a333d3) /* 0.477344348 */, 17 },
4233 /* 3957 */ { MAD_F(0x07a3dc88) /* 0.477505239 */, 17 },
4234 /* 3958 */ { MAD_F(0x07a48541) /* 0.477666144 */, 17 },
4235 /* 3959 */ { MAD_F(0x07a52dfd) /* 0.477827062 */, 17 },
4236 /* 3960 */ { MAD_F(0x07a5d6bd) /* 0.477987994 */, 17 },
4237 /* 3961 */ { MAD_F(0x07a67f80) /* 0.478148940 */, 17 },
4238 /* 3962 */ { MAD_F(0x07a72847) /* 0.478309899 */, 17 },
4239 /* 3963 */ { MAD_F(0x07a7d112) /* 0.478470871 */, 17 },
4240 /* 3964 */ { MAD_F(0x07a879e1) /* 0.478631857 */, 17 },
4241 /* 3965 */ { MAD_F(0x07a922b3) /* 0.478792857 */, 17 },
4242 /* 3966 */ { MAD_F(0x07a9cb88) /* 0.478953870 */, 17 },
4243 /* 3967 */ { MAD_F(0x07aa7462) /* 0.479114897 */, 17 },
4244
4245 /* 3968 */ { MAD_F(0x07ab1d3e) /* 0.479275937 */, 17 },
4246 /* 3969 */ { MAD_F(0x07abc61f) /* 0.479436991 */, 17 },
4247 /* 3970 */ { MAD_F(0x07ac6f03) /* 0.479598058 */, 17 },
4248 /* 3971 */ { MAD_F(0x07ad17eb) /* 0.479759139 */, 17 },
4249 /* 3972 */ { MAD_F(0x07adc0d6) /* 0.479920233 */, 17 },
4250 /* 3973 */ { MAD_F(0x07ae69c6) /* 0.480081341 */, 17 },
4251 /* 3974 */ { MAD_F(0x07af12b8) /* 0.480242463 */, 17 },
4252 /* 3975 */ { MAD_F(0x07afbbaf) /* 0.480403598 */, 17 },
4253 /* 3976 */ { MAD_F(0x07b064a8) /* 0.480564746 */, 17 },
4254 /* 3977 */ { MAD_F(0x07b10da6) /* 0.480725908 */, 17 },
4255 /* 3978 */ { MAD_F(0x07b1b6a7) /* 0.480887083 */, 17 },
4256 /* 3979 */ { MAD_F(0x07b25fac) /* 0.481048272 */, 17 },
4257 /* 3980 */ { MAD_F(0x07b308b5) /* 0.481209475 */, 17 },
4258 /* 3981 */ { MAD_F(0x07b3b1c1) /* 0.481370691 */, 17 },
4259 /* 3982 */ { MAD_F(0x07b45ad0) /* 0.481531920 */, 17 },
4260 /* 3983 */ { MAD_F(0x07b503e4) /* 0.481693163 */, 17 },
4261
4262 /* 3984 */ { MAD_F(0x07b5acfb) /* 0.481854420 */, 17 },
4263 /* 3985 */ { MAD_F(0x07b65615) /* 0.482015690 */, 17 },
4264 /* 3986 */ { MAD_F(0x07b6ff33) /* 0.482176973 */, 17 },
4265 /* 3987 */ { MAD_F(0x07b7a855) /* 0.482338270 */, 17 },
4266 /* 3988 */ { MAD_F(0x07b8517b) /* 0.482499580 */, 17 },
4267 /* 3989 */ { MAD_F(0x07b8faa4) /* 0.482660904 */, 17 },
4268 /* 3990 */ { MAD_F(0x07b9a3d0) /* 0.482822242 */, 17 },
4269 /* 3991 */ { MAD_F(0x07ba4d01) /* 0.482983592 */, 17 },
4270 /* 3992 */ { MAD_F(0x07baf635) /* 0.483144957 */, 17 },
4271 /* 3993 */ { MAD_F(0x07bb9f6c) /* 0.483306335 */, 17 },
4272 /* 3994 */ { MAD_F(0x07bc48a7) /* 0.483467726 */, 17 },
4273 /* 3995 */ { MAD_F(0x07bcf1e6) /* 0.483629131 */, 17 },
4274 /* 3996 */ { MAD_F(0x07bd9b28) /* 0.483790549 */, 17 },
4275 /* 3997 */ { MAD_F(0x07be446e) /* 0.483951980 */, 17 },
4276 /* 3998 */ { MAD_F(0x07beedb8) /* 0.484113426 */, 17 },
4277 /* 3999 */ { MAD_F(0x07bf9705) /* 0.484274884 */, 17 },
4278
4279 /* 4000 */ { MAD_F(0x07c04056) /* 0.484436356 */, 17 },
4280 /* 4001 */ { MAD_F(0x07c0e9aa) /* 0.484597842 */, 17 },
4281 /* 4002 */ { MAD_F(0x07c19302) /* 0.484759341 */, 17 },
4282 /* 4003 */ { MAD_F(0x07c23c5e) /* 0.484920853 */, 17 },
4283 /* 4004 */ { MAD_F(0x07c2e5bd) /* 0.485082379 */, 17 },
4284 /* 4005 */ { MAD_F(0x07c38f20) /* 0.485243918 */, 17 },
4285 /* 4006 */ { MAD_F(0x07c43887) /* 0.485405471 */, 17 },
4286 /* 4007 */ { MAD_F(0x07c4e1f1) /* 0.485567037 */, 17 },
4287 /* 4008 */ { MAD_F(0x07c58b5f) /* 0.485728617 */, 17 },
4288 /* 4009 */ { MAD_F(0x07c634d0) /* 0.485890210 */, 17 },
4289 /* 4010 */ { MAD_F(0x07c6de45) /* 0.486051817 */, 17 },
4290 /* 4011 */ { MAD_F(0x07c787bd) /* 0.486213436 */, 17 },
4291 /* 4012 */ { MAD_F(0x07c83139) /* 0.486375070 */, 17 },
4292 /* 4013 */ { MAD_F(0x07c8dab9) /* 0.486536717 */, 17 },
4293 /* 4014 */ { MAD_F(0x07c9843c) /* 0.486698377 */, 17 },
4294 /* 4015 */ { MAD_F(0x07ca2dc3) /* 0.486860051 */, 17 },
4295
4296 /* 4016 */ { MAD_F(0x07cad74e) /* 0.487021738 */, 17 },
4297 /* 4017 */ { MAD_F(0x07cb80dc) /* 0.487183438 */, 17 },
4298 /* 4018 */ { MAD_F(0x07cc2a6e) /* 0.487345152 */, 17 },
4299 /* 4019 */ { MAD_F(0x07ccd403) /* 0.487506879 */, 17 },
4300 /* 4020 */ { MAD_F(0x07cd7d9c) /* 0.487668620 */, 17 },
4301 /* 4021 */ { MAD_F(0x07ce2739) /* 0.487830374 */, 17 },
4302 /* 4022 */ { MAD_F(0x07ced0d9) /* 0.487992142 */, 17 },
4303 /* 4023 */ { MAD_F(0x07cf7a7d) /* 0.488153923 */, 17 },
4304 /* 4024 */ { MAD_F(0x07d02424) /* 0.488315717 */, 17 },
4305 /* 4025 */ { MAD_F(0x07d0cdcf) /* 0.488477525 */, 17 },
4306 /* 4026 */ { MAD_F(0x07d1777e) /* 0.488639346 */, 17 },
4307 /* 4027 */ { MAD_F(0x07d22130) /* 0.488801181 */, 17 },
4308 /* 4028 */ { MAD_F(0x07d2cae5) /* 0.488963029 */, 17 },
4309 /* 4029 */ { MAD_F(0x07d3749f) /* 0.489124890 */, 17 },
4310 /* 4030 */ { MAD_F(0x07d41e5c) /* 0.489286765 */, 17 },
4311 /* 4031 */ { MAD_F(0x07d4c81c) /* 0.489448653 */, 17 },
4312
4313 /* 4032 */ { MAD_F(0x07d571e0) /* 0.489610555 */, 17 },
4314 /* 4033 */ { MAD_F(0x07d61ba8) /* 0.489772470 */, 17 },
4315 /* 4034 */ { MAD_F(0x07d6c573) /* 0.489934398 */, 17 },
4316 /* 4035 */ { MAD_F(0x07d76f42) /* 0.490096340 */, 17 },
4317 /* 4036 */ { MAD_F(0x07d81915) /* 0.490258295 */, 17 },
4318 /* 4037 */ { MAD_F(0x07d8c2eb) /* 0.490420263 */, 17 },
4319 /* 4038 */ { MAD_F(0x07d96cc4) /* 0.490582245 */, 17 },
4320 /* 4039 */ { MAD_F(0x07da16a2) /* 0.490744240 */, 17 },
4321 /* 4040 */ { MAD_F(0x07dac083) /* 0.490906249 */, 17 },
4322 /* 4041 */ { MAD_F(0x07db6a67) /* 0.491068271 */, 17 },
4323 /* 4042 */ { MAD_F(0x07dc144f) /* 0.491230306 */, 17 },
4324 /* 4043 */ { MAD_F(0x07dcbe3b) /* 0.491392355 */, 17 },
4325 /* 4044 */ { MAD_F(0x07dd682a) /* 0.491554417 */, 17 },
4326 /* 4045 */ { MAD_F(0x07de121d) /* 0.491716492 */, 17 },
4327 /* 4046 */ { MAD_F(0x07debc13) /* 0.491878581 */, 17 },
4328 /* 4047 */ { MAD_F(0x07df660d) /* 0.492040683 */, 17 },
4329
4330 /* 4048 */ { MAD_F(0x07e0100a) /* 0.492202799 */, 17 },
4331 /* 4049 */ { MAD_F(0x07e0ba0c) /* 0.492364928 */, 17 },
4332 /* 4050 */ { MAD_F(0x07e16410) /* 0.492527070 */, 17 },
4333 /* 4051 */ { MAD_F(0x07e20e19) /* 0.492689225 */, 17 },
4334 /* 4052 */ { MAD_F(0x07e2b824) /* 0.492851394 */, 17 },
4335 /* 4053 */ { MAD_F(0x07e36234) /* 0.493013576 */, 17 },
4336 /* 4054 */ { MAD_F(0x07e40c47) /* 0.493175772 */, 17 },
4337 /* 4055 */ { MAD_F(0x07e4b65e) /* 0.493337981 */, 17 },
4338 /* 4056 */ { MAD_F(0x07e56078) /* 0.493500203 */, 17 },
4339 /* 4057 */ { MAD_F(0x07e60a95) /* 0.493662438 */, 17 },
4340 /* 4058 */ { MAD_F(0x07e6b4b7) /* 0.493824687 */, 17 },
4341 /* 4059 */ { MAD_F(0x07e75edc) /* 0.493986949 */, 17 },
4342 /* 4060 */ { MAD_F(0x07e80904) /* 0.494149225 */, 17 },
4343 /* 4061 */ { MAD_F(0x07e8b330) /* 0.494311514 */, 17 },
4344 /* 4062 */ { MAD_F(0x07e95d60) /* 0.494473816 */, 17 },
4345 /* 4063 */ { MAD_F(0x07ea0793) /* 0.494636131 */, 17 },
4346
4347 /* 4064 */ { MAD_F(0x07eab1ca) /* 0.494798460 */, 17 },
4348 /* 4065 */ { MAD_F(0x07eb5c04) /* 0.494960802 */, 17 },
4349 /* 4066 */ { MAD_F(0x07ec0642) /* 0.495123158 */, 17 },
4350 /* 4067 */ { MAD_F(0x07ecb084) /* 0.495285526 */, 17 },
4351 /* 4068 */ { MAD_F(0x07ed5ac9) /* 0.495447908 */, 17 },
4352 /* 4069 */ { MAD_F(0x07ee0512) /* 0.495610304 */, 17 },
4353 /* 4070 */ { MAD_F(0x07eeaf5e) /* 0.495772712 */, 17 },
4354 /* 4071 */ { MAD_F(0x07ef59ae) /* 0.495935134 */, 17 },
4355 /* 4072 */ { MAD_F(0x07f00401) /* 0.496097570 */, 17 },
4356 /* 4073 */ { MAD_F(0x07f0ae58) /* 0.496260018 */, 17 },
4357 /* 4074 */ { MAD_F(0x07f158b3) /* 0.496422480 */, 17 },
4358 /* 4075 */ { MAD_F(0x07f20311) /* 0.496584955 */, 17 },
4359 /* 4076 */ { MAD_F(0x07f2ad72) /* 0.496747444 */, 17 },
4360 /* 4077 */ { MAD_F(0x07f357d8) /* 0.496909945 */, 17 },
4361 /* 4078 */ { MAD_F(0x07f40240) /* 0.497072460 */, 17 },
4362 /* 4079 */ { MAD_F(0x07f4acad) /* 0.497234989 */, 17 },
4363
4364 /* 4080 */ { MAD_F(0x07f5571d) /* 0.497397530 */, 17 },
4365 /* 4081 */ { MAD_F(0x07f60190) /* 0.497560085 */, 17 },
4366 /* 4082 */ { MAD_F(0x07f6ac07) /* 0.497722653 */, 17 },
4367 /* 4083 */ { MAD_F(0x07f75682) /* 0.497885235 */, 17 },
4368 /* 4084 */ { MAD_F(0x07f80100) /* 0.498047829 */, 17 },
4369 /* 4085 */ { MAD_F(0x07f8ab82) /* 0.498210437 */, 17 },
4370 /* 4086 */ { MAD_F(0x07f95607) /* 0.498373058 */, 17 },
4371 /* 4087 */ { MAD_F(0x07fa0090) /* 0.498535693 */, 17 },
4372 /* 4088 */ { MAD_F(0x07faab1c) /* 0.498698341 */, 17 },
4373 /* 4089 */ { MAD_F(0x07fb55ac) /* 0.498861002 */, 17 },
4374 /* 4090 */ { MAD_F(0x07fc0040) /* 0.499023676 */, 17 },
4375 /* 4091 */ { MAD_F(0x07fcaad7) /* 0.499186364 */, 17 },
4376 /* 4092 */ { MAD_F(0x07fd5572) /* 0.499349064 */, 17 },
4377 /* 4093 */ { MAD_F(0x07fe0010) /* 0.499511778 */, 17 },
4378 /* 4094 */ { MAD_F(0x07feaab2) /* 0.499674506 */, 17 },
4379 /* 4095 */ { MAD_F(0x07ff5557) /* 0.499837246 */, 17 },
4380
4381 /* 4096 */ { MAD_F(0x04000000) /* 0.250000000 */, 18 },
4382 /* 4097 */ { MAD_F(0x04005556) /* 0.250081384 */, 18 },
4383 /* 4098 */ { MAD_F(0x0400aaae) /* 0.250162774 */, 18 },
4384 /* 4099 */ { MAD_F(0x04010008) /* 0.250244170 */, 18 },
4385 /* 4100 */ { MAD_F(0x04015563) /* 0.250325574 */, 18 },
4386 /* 4101 */ { MAD_F(0x0401aac1) /* 0.250406984 */, 18 },
4387 /* 4102 */ { MAD_F(0x04020020) /* 0.250488400 */, 18 },
4388 /* 4103 */ { MAD_F(0x04025581) /* 0.250569824 */, 18 },
4389 /* 4104 */ { MAD_F(0x0402aae3) /* 0.250651254 */, 18 },
4390 /* 4105 */ { MAD_F(0x04030048) /* 0.250732690 */, 18 },
4391 /* 4106 */ { MAD_F(0x040355ae) /* 0.250814133 */, 18 },
4392 /* 4107 */ { MAD_F(0x0403ab16) /* 0.250895583 */, 18 },
4393 /* 4108 */ { MAD_F(0x04040080) /* 0.250977039 */, 18 },
4394 /* 4109 */ { MAD_F(0x040455eb) /* 0.251058502 */, 18 },
4395 /* 4110 */ { MAD_F(0x0404ab59) /* 0.251139971 */, 18 },
4396 /* 4111 */ { MAD_F(0x040500c8) /* 0.251221448 */, 18 },
4397
4398 /* 4112 */ { MAD_F(0x04055638) /* 0.251302930 */, 18 },
4399 /* 4113 */ { MAD_F(0x0405abab) /* 0.251384420 */, 18 },
4400 /* 4114 */ { MAD_F(0x0406011f) /* 0.251465916 */, 18 },
4401 /* 4115 */ { MAD_F(0x04065696) /* 0.251547418 */, 18 },
4402 /* 4116 */ { MAD_F(0x0406ac0e) /* 0.251628927 */, 18 },
4403 /* 4117 */ { MAD_F(0x04070187) /* 0.251710443 */, 18 },
4404 /* 4118 */ { MAD_F(0x04075703) /* 0.251791965 */, 18 },
4405 /* 4119 */ { MAD_F(0x0407ac80) /* 0.251873494 */, 18 },
4406 /* 4120 */ { MAD_F(0x040801ff) /* 0.251955030 */, 18 },
4407 /* 4121 */ { MAD_F(0x04085780) /* 0.252036572 */, 18 },
4408 /* 4122 */ { MAD_F(0x0408ad02) /* 0.252118121 */, 18 },
4409 /* 4123 */ { MAD_F(0x04090287) /* 0.252199676 */, 18 },
4410 /* 4124 */ { MAD_F(0x0409580d) /* 0.252281238 */, 18 },
4411 /* 4125 */ { MAD_F(0x0409ad95) /* 0.252362807 */, 18 },
4412 /* 4126 */ { MAD_F(0x040a031e) /* 0.252444382 */, 18 },
4413 /* 4127 */ { MAD_F(0x040a58aa) /* 0.252525963 */, 18 },
4414
4415 /* 4128 */ { MAD_F(0x040aae37) /* 0.252607552 */, 18 },
4416 /* 4129 */ { MAD_F(0x040b03c6) /* 0.252689147 */, 18 },
4417 /* 4130 */ { MAD_F(0x040b5957) /* 0.252770748 */, 18 },
4418 /* 4131 */ { MAD_F(0x040baee9) /* 0.252852356 */, 18 },
4419 /* 4132 */ { MAD_F(0x040c047e) /* 0.252933971 */, 18 },
4420 /* 4133 */ { MAD_F(0x040c5a14) /* 0.253015592 */, 18 },
4421 /* 4134 */ { MAD_F(0x040cafab) /* 0.253097220 */, 18 },
4422 /* 4135 */ { MAD_F(0x040d0545) /* 0.253178854 */, 18 },
4423 /* 4136 */ { MAD_F(0x040d5ae0) /* 0.253260495 */, 18 },
4424 /* 4137 */ { MAD_F(0x040db07d) /* 0.253342143 */, 18 },
4425 /* 4138 */ { MAD_F(0x040e061c) /* 0.253423797 */, 18 },
4426 /* 4139 */ { MAD_F(0x040e5bbd) /* 0.253505457 */, 18 },
4427 /* 4140 */ { MAD_F(0x040eb15f) /* 0.253587125 */, 18 },
4428 /* 4141 */ { MAD_F(0x040f0703) /* 0.253668799 */, 18 },
4429 /* 4142 */ { MAD_F(0x040f5ca9) /* 0.253750479 */, 18 },
4430 /* 4143 */ { MAD_F(0x040fb251) /* 0.253832166 */, 18 },
4431
4432 /* 4144 */ { MAD_F(0x041007fa) /* 0.253913860 */, 18 },
4433 /* 4145 */ { MAD_F(0x04105da6) /* 0.253995560 */, 18 },
4434 /* 4146 */ { MAD_F(0x0410b353) /* 0.254077266 */, 18 },
4435 /* 4147 */ { MAD_F(0x04110901) /* 0.254158980 */, 18 },
4436 /* 4148 */ { MAD_F(0x04115eb2) /* 0.254240700 */, 18 },
4437 /* 4149 */ { MAD_F(0x0411b464) /* 0.254322426 */, 18 },
4438 /* 4150 */ { MAD_F(0x04120a18) /* 0.254404159 */, 18 },
4439 /* 4151 */ { MAD_F(0x04125fce) /* 0.254485899 */, 18 },
4440 /* 4152 */ { MAD_F(0x0412b586) /* 0.254567645 */, 18 },
4441 /* 4153 */ { MAD_F(0x04130b3f) /* 0.254649397 */, 18 },
4442 /* 4154 */ { MAD_F(0x041360fa) /* 0.254731157 */, 18 },
4443 /* 4155 */ { MAD_F(0x0413b6b7) /* 0.254812922 */, 18 },
4444 /* 4156 */ { MAD_F(0x04140c75) /* 0.254894695 */, 18 },
4445 /* 4157 */ { MAD_F(0x04146236) /* 0.254976474 */, 18 },
4446 /* 4158 */ { MAD_F(0x0414b7f8) /* 0.255058259 */, 18 },
4447 /* 4159 */ { MAD_F(0x04150dbc) /* 0.255140051 */, 18 },
4448
4449 /* 4160 */ { MAD_F(0x04156381) /* 0.255221850 */, 18 },
4450 /* 4161 */ { MAD_F(0x0415b949) /* 0.255303655 */, 18 },
4451 /* 4162 */ { MAD_F(0x04160f12) /* 0.255385467 */, 18 },
4452 /* 4163 */ { MAD_F(0x041664dd) /* 0.255467285 */, 18 },
4453 /* 4164 */ { MAD_F(0x0416baaa) /* 0.255549110 */, 18 },
4454 /* 4165 */ { MAD_F(0x04171078) /* 0.255630941 */, 18 },
4455 /* 4166 */ { MAD_F(0x04176648) /* 0.255712779 */, 18 },
4456 /* 4167 */ { MAD_F(0x0417bc1a) /* 0.255794624 */, 18 },
4457 /* 4168 */ { MAD_F(0x041811ee) /* 0.255876475 */, 18 },
4458 /* 4169 */ { MAD_F(0x041867c3) /* 0.255958332 */, 18 },
4459 /* 4170 */ { MAD_F(0x0418bd9b) /* 0.256040196 */, 18 },
4460 /* 4171 */ { MAD_F(0x04191374) /* 0.256122067 */, 18 },
4461 /* 4172 */ { MAD_F(0x0419694e) /* 0.256203944 */, 18 },
4462 /* 4173 */ { MAD_F(0x0419bf2b) /* 0.256285828 */, 18 },
4463 /* 4174 */ { MAD_F(0x041a1509) /* 0.256367718 */, 18 },
4464 /* 4175 */ { MAD_F(0x041a6ae9) /* 0.256449615 */, 18 },
4465
4466 /* 4176 */ { MAD_F(0x041ac0cb) /* 0.256531518 */, 18 },
4467 /* 4177 */ { MAD_F(0x041b16ae) /* 0.256613428 */, 18 },
4468 /* 4178 */ { MAD_F(0x041b6c94) /* 0.256695344 */, 18 },
4469 /* 4179 */ { MAD_F(0x041bc27b) /* 0.256777267 */, 18 },
4470 /* 4180 */ { MAD_F(0x041c1863) /* 0.256859197 */, 18 },
4471 /* 4181 */ { MAD_F(0x041c6e4e) /* 0.256941133 */, 18 },
4472 /* 4182 */ { MAD_F(0x041cc43a) /* 0.257023076 */, 18 },
4473 /* 4183 */ { MAD_F(0x041d1a28) /* 0.257105025 */, 18 },
4474 /* 4184 */ { MAD_F(0x041d7018) /* 0.257186980 */, 18 },
4475 /* 4185 */ { MAD_F(0x041dc60a) /* 0.257268942 */, 18 },
4476 /* 4186 */ { MAD_F(0x041e1bfd) /* 0.257350911 */, 18 },
4477 /* 4187 */ { MAD_F(0x041e71f2) /* 0.257432886 */, 18 },
4478 /* 4188 */ { MAD_F(0x041ec7e9) /* 0.257514868 */, 18 },
4479 /* 4189 */ { MAD_F(0x041f1de1) /* 0.257596856 */, 18 },
4480 /* 4190 */ { MAD_F(0x041f73dc) /* 0.257678851 */, 18 },
4481 /* 4191 */ { MAD_F(0x041fc9d8) /* 0.257760852 */, 18 },
4482
4483 /* 4192 */ { MAD_F(0x04201fd5) /* 0.257842860 */, 18 },
4484 /* 4193 */ { MAD_F(0x042075d5) /* 0.257924875 */, 18 },
4485 /* 4194 */ { MAD_F(0x0420cbd6) /* 0.258006895 */, 18 },
4486 /* 4195 */ { MAD_F(0x042121d9) /* 0.258088923 */, 18 },
4487 /* 4196 */ { MAD_F(0x042177de) /* 0.258170957 */, 18 },
4488 /* 4197 */ { MAD_F(0x0421cde5) /* 0.258252997 */, 18 },
4489 /* 4198 */ { MAD_F(0x042223ed) /* 0.258335044 */, 18 },
4490 /* 4199 */ { MAD_F(0x042279f7) /* 0.258417097 */, 18 },
4491 /* 4200 */ { MAD_F(0x0422d003) /* 0.258499157 */, 18 },
4492 /* 4201 */ { MAD_F(0x04232611) /* 0.258581224 */, 18 },
4493 /* 4202 */ { MAD_F(0x04237c20) /* 0.258663297 */, 18 },
4494 /* 4203 */ { MAD_F(0x0423d231) /* 0.258745376 */, 18 },
4495 /* 4204 */ { MAD_F(0x04242844) /* 0.258827462 */, 18 },
4496 /* 4205 */ { MAD_F(0x04247e58) /* 0.258909555 */, 18 },
4497 /* 4206 */ { MAD_F(0x0424d46e) /* 0.258991654 */, 18 },
4498 /* 4207 */ { MAD_F(0x04252a87) /* 0.259073760 */, 18 },
4499
4500 /* 4208 */ { MAD_F(0x042580a0) /* 0.259155872 */, 18 },
4501 /* 4209 */ { MAD_F(0x0425d6bc) /* 0.259237990 */, 18 },
4502 /* 4210 */ { MAD_F(0x04262cd9) /* 0.259320115 */, 18 },
4503 /* 4211 */ { MAD_F(0x042682f8) /* 0.259402247 */, 18 },
4504 /* 4212 */ { MAD_F(0x0426d919) /* 0.259484385 */, 18 },
4505 /* 4213 */ { MAD_F(0x04272f3b) /* 0.259566529 */, 18 },
4506 /* 4214 */ { MAD_F(0x04278560) /* 0.259648680 */, 18 },
4507 /* 4215 */ { MAD_F(0x0427db86) /* 0.259730838 */, 18 },
4508 /* 4216 */ { MAD_F(0x042831ad) /* 0.259813002 */, 18 },
4509 /* 4217 */ { MAD_F(0x042887d7) /* 0.259895173 */, 18 },
4510 /* 4218 */ { MAD_F(0x0428de02) /* 0.259977350 */, 18 },
4511 /* 4219 */ { MAD_F(0x0429342f) /* 0.260059533 */, 18 },
4512 /* 4220 */ { MAD_F(0x04298a5e) /* 0.260141723 */, 18 },
4513 /* 4221 */ { MAD_F(0x0429e08e) /* 0.260223920 */, 18 },
4514 /* 4222 */ { MAD_F(0x042a36c0) /* 0.260306123 */, 18 },
4515 /* 4223 */ { MAD_F(0x042a8cf4) /* 0.260388332 */, 18 },
4516
4517 /* 4224 */ { MAD_F(0x042ae32a) /* 0.260470548 */, 18 },
4518 /* 4225 */ { MAD_F(0x042b3962) /* 0.260552771 */, 18 },
4519 /* 4226 */ { MAD_F(0x042b8f9b) /* 0.260635000 */, 18 },
4520 /* 4227 */ { MAD_F(0x042be5d6) /* 0.260717235 */, 18 },
4521 /* 4228 */ { MAD_F(0x042c3c12) /* 0.260799477 */, 18 },
4522 /* 4229 */ { MAD_F(0x042c9251) /* 0.260881725 */, 18 },
4523 /* 4230 */ { MAD_F(0x042ce891) /* 0.260963980 */, 18 },
4524 /* 4231 */ { MAD_F(0x042d3ed3) /* 0.261046242 */, 18 },
4525 /* 4232 */ { MAD_F(0x042d9516) /* 0.261128510 */, 18 },
4526 /* 4233 */ { MAD_F(0x042deb5c) /* 0.261210784 */, 18 },
4527 /* 4234 */ { MAD_F(0x042e41a3) /* 0.261293065 */, 18 },
4528 /* 4235 */ { MAD_F(0x042e97ec) /* 0.261375352 */, 18 },
4529 /* 4236 */ { MAD_F(0x042eee36) /* 0.261457646 */, 18 },
4530 /* 4237 */ { MAD_F(0x042f4482) /* 0.261539946 */, 18 },
4531 /* 4238 */ { MAD_F(0x042f9ad1) /* 0.261622253 */, 18 },
4532 /* 4239 */ { MAD_F(0x042ff120) /* 0.261704566 */, 18 },
4533
4534 /* 4240 */ { MAD_F(0x04304772) /* 0.261786886 */, 18 },
4535 /* 4241 */ { MAD_F(0x04309dc5) /* 0.261869212 */, 18 },
4536 /* 4242 */ { MAD_F(0x0430f41a) /* 0.261951545 */, 18 },
4537 /* 4243 */ { MAD_F(0x04314a71) /* 0.262033884 */, 18 },
4538 /* 4244 */ { MAD_F(0x0431a0c9) /* 0.262116229 */, 18 },
4539 /* 4245 */ { MAD_F(0x0431f723) /* 0.262198581 */, 18 },
4540 /* 4246 */ { MAD_F(0x04324d7f) /* 0.262280940 */, 18 },
4541 /* 4247 */ { MAD_F(0x0432a3dd) /* 0.262363305 */, 18 },
4542 /* 4248 */ { MAD_F(0x0432fa3d) /* 0.262445676 */, 18 },
4543 /* 4249 */ { MAD_F(0x0433509e) /* 0.262528054 */, 18 },
4544 /* 4250 */ { MAD_F(0x0433a701) /* 0.262610438 */, 18 },
4545 /* 4251 */ { MAD_F(0x0433fd65) /* 0.262692829 */, 18 },
4546 /* 4252 */ { MAD_F(0x043453cc) /* 0.262775227 */, 18 },
4547 /* 4253 */ { MAD_F(0x0434aa34) /* 0.262857630 */, 18 },
4548 /* 4254 */ { MAD_F(0x0435009d) /* 0.262940040 */, 18 },
4549 /* 4255 */ { MAD_F(0x04355709) /* 0.263022457 */, 18 },
4550
4551 /* 4256 */ { MAD_F(0x0435ad76) /* 0.263104880 */, 18 },
4552 /* 4257 */ { MAD_F(0x043603e5) /* 0.263187310 */, 18 },
4553 /* 4258 */ { MAD_F(0x04365a56) /* 0.263269746 */, 18 },
4554 /* 4259 */ { MAD_F(0x0436b0c9) /* 0.263352188 */, 18 },
4555 /* 4260 */ { MAD_F(0x0437073d) /* 0.263434637 */, 18 },
4556 /* 4261 */ { MAD_F(0x04375db3) /* 0.263517093 */, 18 },
4557 /* 4262 */ { MAD_F(0x0437b42a) /* 0.263599554 */, 18 },
4558 /* 4263 */ { MAD_F(0x04380aa4) /* 0.263682023 */, 18 },
4559 /* 4264 */ { MAD_F(0x0438611f) /* 0.263764497 */, 18 },
4560 /* 4265 */ { MAD_F(0x0438b79c) /* 0.263846979 */, 18 },
4561 /* 4266 */ { MAD_F(0x04390e1a) /* 0.263929466 */, 18 },
4562 /* 4267 */ { MAD_F(0x0439649b) /* 0.264011960 */, 18 },
4563 /* 4268 */ { MAD_F(0x0439bb1d) /* 0.264094461 */, 18 },
4564 /* 4269 */ { MAD_F(0x043a11a1) /* 0.264176968 */, 18 },
4565 /* 4270 */ { MAD_F(0x043a6826) /* 0.264259481 */, 18 },
4566 /* 4271 */ { MAD_F(0x043abead) /* 0.264342001 */, 18 },
4567
4568 /* 4272 */ { MAD_F(0x043b1536) /* 0.264424527 */, 18 },
4569 /* 4273 */ { MAD_F(0x043b6bc1) /* 0.264507060 */, 18 },
4570 /* 4274 */ { MAD_F(0x043bc24d) /* 0.264589599 */, 18 },
4571 /* 4275 */ { MAD_F(0x043c18dc) /* 0.264672145 */, 18 },
4572 /* 4276 */ { MAD_F(0x043c6f6c) /* 0.264754697 */, 18 },
4573 /* 4277 */ { MAD_F(0x043cc5fd) /* 0.264837255 */, 18 },
4574 /* 4278 */ { MAD_F(0x043d1c91) /* 0.264919820 */, 18 },
4575 /* 4279 */ { MAD_F(0x043d7326) /* 0.265002392 */, 18 },
4576 /* 4280 */ { MAD_F(0x043dc9bc) /* 0.265084969 */, 18 },
4577 /* 4281 */ { MAD_F(0x043e2055) /* 0.265167554 */, 18 },
4578 /* 4282 */ { MAD_F(0x043e76ef) /* 0.265250144 */, 18 },
4579 /* 4283 */ { MAD_F(0x043ecd8b) /* 0.265332741 */, 18 },
4580 /* 4284 */ { MAD_F(0x043f2429) /* 0.265415345 */, 18 },
4581 /* 4285 */ { MAD_F(0x043f7ac8) /* 0.265497955 */, 18 },
4582 /* 4286 */ { MAD_F(0x043fd169) /* 0.265580571 */, 18 },
4583 /* 4287 */ { MAD_F(0x0440280c) /* 0.265663194 */, 18 },
4584
4585 /* 4288 */ { MAD_F(0x04407eb1) /* 0.265745823 */, 18 },
4586 /* 4289 */ { MAD_F(0x0440d557) /* 0.265828459 */, 18 },
4587 /* 4290 */ { MAD_F(0x04412bff) /* 0.265911101 */, 18 },
4588 /* 4291 */ { MAD_F(0x044182a9) /* 0.265993749 */, 18 },
4589 /* 4292 */ { MAD_F(0x0441d955) /* 0.266076404 */, 18 },
4590 /* 4293 */ { MAD_F(0x04423002) /* 0.266159065 */, 18 },
4591 /* 4294 */ { MAD_F(0x044286b1) /* 0.266241733 */, 18 },
4592 /* 4295 */ { MAD_F(0x0442dd61) /* 0.266324407 */, 18 },
4593 /* 4296 */ { MAD_F(0x04433414) /* 0.266407088 */, 18 },
4594 /* 4297 */ { MAD_F(0x04438ac8) /* 0.266489775 */, 18 },
4595 /* 4298 */ { MAD_F(0x0443e17e) /* 0.266572468 */, 18 },
4596 /* 4299 */ { MAD_F(0x04443835) /* 0.266655168 */, 18 },
4597 /* 4300 */ { MAD_F(0x04448eef) /* 0.266737874 */, 18 },
4598 /* 4301 */ { MAD_F(0x0444e5aa) /* 0.266820587 */, 18 },
4599 /* 4302 */ { MAD_F(0x04453c66) /* 0.266903306 */, 18 },
4600 /* 4303 */ { MAD_F(0x04459325) /* 0.266986031 */, 18 },
4601
4602 /* 4304 */ { MAD_F(0x0445e9e5) /* 0.267068763 */, 18 },
4603 /* 4305 */ { MAD_F(0x044640a7) /* 0.267151501 */, 18 },
4604 /* 4306 */ { MAD_F(0x0446976a) /* 0.267234246 */, 18 },
4605 /* 4307 */ { MAD_F(0x0446ee30) /* 0.267316997 */, 18 },
4606 /* 4308 */ { MAD_F(0x044744f7) /* 0.267399755 */, 18 },
4607 /* 4309 */ { MAD_F(0x04479bc0) /* 0.267482518 */, 18 },
4608 /* 4310 */ { MAD_F(0x0447f28a) /* 0.267565289 */, 18 },
4609 /* 4311 */ { MAD_F(0x04484956) /* 0.267648065 */, 18 },
4610 /* 4312 */ { MAD_F(0x0448a024) /* 0.267730848 */, 18 },
4611 /* 4313 */ { MAD_F(0x0448f6f4) /* 0.267813638 */, 18 },
4612 /* 4314 */ { MAD_F(0x04494dc5) /* 0.267896434 */, 18 },
4613 /* 4315 */ { MAD_F(0x0449a498) /* 0.267979236 */, 18 },
4614 /* 4316 */ { MAD_F(0x0449fb6d) /* 0.268062045 */, 18 },
4615 /* 4317 */ { MAD_F(0x044a5243) /* 0.268144860 */, 18 },
4616 /* 4318 */ { MAD_F(0x044aa91c) /* 0.268227681 */, 18 },
4617 /* 4319 */ { MAD_F(0x044afff6) /* 0.268310509 */, 18 },
4618
4619 /* 4320 */ { MAD_F(0x044b56d1) /* 0.268393343 */, 18 },
4620 /* 4321 */ { MAD_F(0x044badaf) /* 0.268476184 */, 18 },
4621 /* 4322 */ { MAD_F(0x044c048e) /* 0.268559031 */, 18 },
4622 /* 4323 */ { MAD_F(0x044c5b6f) /* 0.268641885 */, 18 },
4623 /* 4324 */ { MAD_F(0x044cb251) /* 0.268724744 */, 18 },
4624 /* 4325 */ { MAD_F(0x044d0935) /* 0.268807611 */, 18 },
4625 /* 4326 */ { MAD_F(0x044d601b) /* 0.268890483 */, 18 },
4626 /* 4327 */ { MAD_F(0x044db703) /* 0.268973362 */, 18 },
4627 /* 4328 */ { MAD_F(0x044e0dec) /* 0.269056248 */, 18 },
4628 /* 4329 */ { MAD_F(0x044e64d7) /* 0.269139139 */, 18 },
4629 /* 4330 */ { MAD_F(0x044ebbc4) /* 0.269222037 */, 18 },
4630 /* 4331 */ { MAD_F(0x044f12b3) /* 0.269304942 */, 18 },
4631 /* 4332 */ { MAD_F(0x044f69a3) /* 0.269387853 */, 18 },
4632 /* 4333 */ { MAD_F(0x044fc095) /* 0.269470770 */, 18 },
4633 /* 4334 */ { MAD_F(0x04501788) /* 0.269553694 */, 18 },
4634 /* 4335 */ { MAD_F(0x04506e7e) /* 0.269636624 */, 18 },
4635
4636 /* 4336 */ { MAD_F(0x0450c575) /* 0.269719560 */, 18 },
4637 /* 4337 */ { MAD_F(0x04511c6e) /* 0.269802503 */, 18 },
4638 /* 4338 */ { MAD_F(0x04517368) /* 0.269885452 */, 18 },
4639 /* 4339 */ { MAD_F(0x0451ca64) /* 0.269968408 */, 18 },
4640 /* 4340 */ { MAD_F(0x04522162) /* 0.270051370 */, 18 },
4641 /* 4341 */ { MAD_F(0x04527862) /* 0.270134338 */, 18 },
4642 /* 4342 */ { MAD_F(0x0452cf63) /* 0.270217312 */, 18 },
4643 /* 4343 */ { MAD_F(0x04532666) /* 0.270300293 */, 18 },
4644 /* 4344 */ { MAD_F(0x04537d6b) /* 0.270383281 */, 18 },
4645 /* 4345 */ { MAD_F(0x0453d472) /* 0.270466275 */, 18 },
4646 /* 4346 */ { MAD_F(0x04542b7a) /* 0.270549275 */, 18 },
4647 /* 4347 */ { MAD_F(0x04548284) /* 0.270632281 */, 18 },
4648 /* 4348 */ { MAD_F(0x0454d98f) /* 0.270715294 */, 18 },
4649 /* 4349 */ { MAD_F(0x0455309c) /* 0.270798313 */, 18 },
4650 /* 4350 */ { MAD_F(0x045587ab) /* 0.270881339 */, 18 },
4651 /* 4351 */ { MAD_F(0x0455debc) /* 0.270964371 */, 18 },
4652
4653 /* 4352 */ { MAD_F(0x045635cf) /* 0.271047409 */, 18 },
4654 /* 4353 */ { MAD_F(0x04568ce3) /* 0.271130454 */, 18 },
4655 /* 4354 */ { MAD_F(0x0456e3f9) /* 0.271213505 */, 18 },
4656 /* 4355 */ { MAD_F(0x04573b10) /* 0.271296562 */, 18 },
4657 /* 4356 */ { MAD_F(0x04579229) /* 0.271379626 */, 18 },
4658 /* 4357 */ { MAD_F(0x0457e944) /* 0.271462696 */, 18 },
4659 /* 4358 */ { MAD_F(0x04584061) /* 0.271545772 */, 18 },
4660 /* 4359 */ { MAD_F(0x0458977f) /* 0.271628855 */, 18 },
4661 /* 4360 */ { MAD_F(0x0458ee9f) /* 0.271711944 */, 18 },
4662 /* 4361 */ { MAD_F(0x045945c1) /* 0.271795040 */, 18 },
4663 /* 4362 */ { MAD_F(0x04599ce5) /* 0.271878142 */, 18 },
4664 /* 4363 */ { MAD_F(0x0459f40a) /* 0.271961250 */, 18 },
4665 /* 4364 */ { MAD_F(0x045a4b31) /* 0.272044365 */, 18 },
4666 /* 4365 */ { MAD_F(0x045aa259) /* 0.272127486 */, 18 },
4667 /* 4366 */ { MAD_F(0x045af984) /* 0.272210613 */, 18 },
4668 /* 4367 */ { MAD_F(0x045b50b0) /* 0.272293746 */, 18 },
4669
4670 /* 4368 */ { MAD_F(0x045ba7dd) /* 0.272376886 */, 18 },
4671 /* 4369 */ { MAD_F(0x045bff0d) /* 0.272460033 */, 18 },
4672 /* 4370 */ { MAD_F(0x045c563e) /* 0.272543185 */, 18 },
4673 /* 4371 */ { MAD_F(0x045cad71) /* 0.272626344 */, 18 },
4674 /* 4372 */ { MAD_F(0x045d04a5) /* 0.272709510 */, 18 },
4675 /* 4373 */ { MAD_F(0x045d5bdc) /* 0.272792681 */, 18 },
4676 /* 4374 */ { MAD_F(0x045db313) /* 0.272875859 */, 18 },
4677 /* 4375 */ { MAD_F(0x045e0a4d) /* 0.272959044 */, 18 },
4678 /* 4376 */ { MAD_F(0x045e6188) /* 0.273042234 */, 18 },
4679 /* 4377 */ { MAD_F(0x045eb8c5) /* 0.273125431 */, 18 },
4680 /* 4378 */ { MAD_F(0x045f1004) /* 0.273208635 */, 18 },
4681 /* 4379 */ { MAD_F(0x045f6745) /* 0.273291844 */, 18 },
4682 /* 4380 */ { MAD_F(0x045fbe87) /* 0.273375060 */, 18 },
4683 /* 4381 */ { MAD_F(0x046015cb) /* 0.273458283 */, 18 },
4684 /* 4382 */ { MAD_F(0x04606d10) /* 0.273541511 */, 18 },
4685 /* 4383 */ { MAD_F(0x0460c457) /* 0.273624747 */, 18 },
4686
4687 /* 4384 */ { MAD_F(0x04611ba0) /* 0.273707988 */, 18 },
4688 /* 4385 */ { MAD_F(0x046172eb) /* 0.273791236 */, 18 },
4689 /* 4386 */ { MAD_F(0x0461ca37) /* 0.273874490 */, 18 },
4690 /* 4387 */ { MAD_F(0x04622185) /* 0.273957750 */, 18 },
4691 /* 4388 */ { MAD_F(0x046278d5) /* 0.274041017 */, 18 },
4692 /* 4389 */ { MAD_F(0x0462d026) /* 0.274124290 */, 18 },
4693 /* 4390 */ { MAD_F(0x0463277a) /* 0.274207569 */, 18 },
4694 /* 4391 */ { MAD_F(0x04637ece) /* 0.274290855 */, 18 },
4695 /* 4392 */ { MAD_F(0x0463d625) /* 0.274374147 */, 18 },
4696 /* 4393 */ { MAD_F(0x04642d7d) /* 0.274457445 */, 18 },
4697 /* 4394 */ { MAD_F(0x046484d7) /* 0.274540749 */, 18 },
4698 /* 4395 */ { MAD_F(0x0464dc33) /* 0.274624060 */, 18 },
4699 /* 4396 */ { MAD_F(0x04653390) /* 0.274707378 */, 18 },
4700 /* 4397 */ { MAD_F(0x04658aef) /* 0.274790701 */, 18 },
4701 /* 4398 */ { MAD_F(0x0465e250) /* 0.274874031 */, 18 },
4702 /* 4399 */ { MAD_F(0x046639b2) /* 0.274957367 */, 18 },
4703
4704 /* 4400 */ { MAD_F(0x04669116) /* 0.275040710 */, 18 },
4705 /* 4401 */ { MAD_F(0x0466e87c) /* 0.275124059 */, 18 },
4706 /* 4402 */ { MAD_F(0x04673fe3) /* 0.275207414 */, 18 },
4707 /* 4403 */ { MAD_F(0x0467974d) /* 0.275290775 */, 18 },
4708 /* 4404 */ { MAD_F(0x0467eeb7) /* 0.275374143 */, 18 },
4709 /* 4405 */ { MAD_F(0x04684624) /* 0.275457517 */, 18 },
4710 /* 4406 */ { MAD_F(0x04689d92) /* 0.275540897 */, 18 },
4711 /* 4407 */ { MAD_F(0x0468f502) /* 0.275624284 */, 18 },
4712 /* 4408 */ { MAD_F(0x04694c74) /* 0.275707677 */, 18 },
4713 /* 4409 */ { MAD_F(0x0469a3e7) /* 0.275791076 */, 18 },
4714 /* 4410 */ { MAD_F(0x0469fb5c) /* 0.275874482 */, 18 },
4715 /* 4411 */ { MAD_F(0x046a52d3) /* 0.275957894 */, 18 },
4716 /* 4412 */ { MAD_F(0x046aaa4b) /* 0.276041312 */, 18 },
4717 /* 4413 */ { MAD_F(0x046b01c5) /* 0.276124737 */, 18 },
4718 /* 4414 */ { MAD_F(0x046b5941) /* 0.276208167 */, 18 },
4719 /* 4415 */ { MAD_F(0x046bb0bf) /* 0.276291605 */, 18 },
4720
4721 /* 4416 */ { MAD_F(0x046c083e) /* 0.276375048 */, 18 },
4722 /* 4417 */ { MAD_F(0x046c5fbf) /* 0.276458498 */, 18 },
4723 /* 4418 */ { MAD_F(0x046cb741) /* 0.276541954 */, 18 },
4724 /* 4419 */ { MAD_F(0x046d0ec5) /* 0.276625416 */, 18 },
4725 /* 4420 */ { MAD_F(0x046d664b) /* 0.276708885 */, 18 },
4726 /* 4421 */ { MAD_F(0x046dbdd3) /* 0.276792360 */, 18 },
4727 /* 4422 */ { MAD_F(0x046e155c) /* 0.276875841 */, 18 },
4728 /* 4423 */ { MAD_F(0x046e6ce7) /* 0.276959328 */, 18 },
4729 /* 4424 */ { MAD_F(0x046ec474) /* 0.277042822 */, 18 },
4730 /* 4425 */ { MAD_F(0x046f1c02) /* 0.277126322 */, 18 },
4731 /* 4426 */ { MAD_F(0x046f7392) /* 0.277209829 */, 18 },
4732 /* 4427 */ { MAD_F(0x046fcb24) /* 0.277293341 */, 18 },
4733 /* 4428 */ { MAD_F(0x047022b8) /* 0.277376860 */, 18 },
4734 /* 4429 */ { MAD_F(0x04707a4d) /* 0.277460385 */, 18 },
4735 /* 4430 */ { MAD_F(0x0470d1e4) /* 0.277543917 */, 18 },
4736 /* 4431 */ { MAD_F(0x0471297c) /* 0.277627455 */, 18 },
4737
4738 /* 4432 */ { MAD_F(0x04718116) /* 0.277710999 */, 18 },
4739 /* 4433 */ { MAD_F(0x0471d8b2) /* 0.277794549 */, 18 },
4740 /* 4434 */ { MAD_F(0x04723050) /* 0.277878106 */, 18 },
4741 /* 4435 */ { MAD_F(0x047287ef) /* 0.277961669 */, 18 },
4742 /* 4436 */ { MAD_F(0x0472df90) /* 0.278045238 */, 18 },
4743 /* 4437 */ { MAD_F(0x04733733) /* 0.278128813 */, 18 },
4744 /* 4438 */ { MAD_F(0x04738ed7) /* 0.278212395 */, 18 },
4745 /* 4439 */ { MAD_F(0x0473e67d) /* 0.278295983 */, 18 },
4746 /* 4440 */ { MAD_F(0x04743e25) /* 0.278379578 */, 18 },
4747 /* 4441 */ { MAD_F(0x047495ce) /* 0.278463178 */, 18 },
4748 /* 4442 */ { MAD_F(0x0474ed79) /* 0.278546785 */, 18 },
4749 /* 4443 */ { MAD_F(0x04754526) /* 0.278630398 */, 18 },
4750 /* 4444 */ { MAD_F(0x04759cd4) /* 0.278714018 */, 18 },
4751 /* 4445 */ { MAD_F(0x0475f484) /* 0.278797643 */, 18 },
4752 /* 4446 */ { MAD_F(0x04764c36) /* 0.278881275 */, 18 },
4753 /* 4447 */ { MAD_F(0x0476a3ea) /* 0.278964914 */, 18 },
4754
4755 /* 4448 */ { MAD_F(0x0476fb9f) /* 0.279048558 */, 18 },
4756 /* 4449 */ { MAD_F(0x04775356) /* 0.279132209 */, 18 },
4757 /* 4450 */ { MAD_F(0x0477ab0e) /* 0.279215866 */, 18 },
4758 /* 4451 */ { MAD_F(0x047802c8) /* 0.279299529 */, 18 },
4759 /* 4452 */ { MAD_F(0x04785a84) /* 0.279383199 */, 18 },
4760 /* 4453 */ { MAD_F(0x0478b242) /* 0.279466875 */, 18 },
4761 /* 4454 */ { MAD_F(0x04790a01) /* 0.279550557 */, 18 },
4762 /* 4455 */ { MAD_F(0x047961c2) /* 0.279634245 */, 18 },
4763 /* 4456 */ { MAD_F(0x0479b984) /* 0.279717940 */, 18 },
4764 /* 4457 */ { MAD_F(0x047a1149) /* 0.279801641 */, 18 },
4765 /* 4458 */ { MAD_F(0x047a690f) /* 0.279885348 */, 18 },
4766 /* 4459 */ { MAD_F(0x047ac0d6) /* 0.279969061 */, 18 },
4767 /* 4460 */ { MAD_F(0x047b18a0) /* 0.280052781 */, 18 },
4768 /* 4461 */ { MAD_F(0x047b706b) /* 0.280136507 */, 18 },
4769 /* 4462 */ { MAD_F(0x047bc837) /* 0.280220239 */, 18 },
4770 /* 4463 */ { MAD_F(0x047c2006) /* 0.280303978 */, 18 },
4771
4772 /* 4464 */ { MAD_F(0x047c77d6) /* 0.280387722 */, 18 },
4773 /* 4465 */ { MAD_F(0x047ccfa8) /* 0.280471473 */, 18 },
4774 /* 4466 */ { MAD_F(0x047d277b) /* 0.280555230 */, 18 },
4775 /* 4467 */ { MAD_F(0x047d7f50) /* 0.280638994 */, 18 },
4776 /* 4468 */ { MAD_F(0x047dd727) /* 0.280722764 */, 18 },
4777 /* 4469 */ { MAD_F(0x047e2eff) /* 0.280806540 */, 18 },
4778 /* 4470 */ { MAD_F(0x047e86d9) /* 0.280890322 */, 18 },
4779 /* 4471 */ { MAD_F(0x047edeb5) /* 0.280974110 */, 18 },
4780 /* 4472 */ { MAD_F(0x047f3693) /* 0.281057905 */, 18 },
4781 /* 4473 */ { MAD_F(0x047f8e72) /* 0.281141706 */, 18 },
4782 /* 4474 */ { MAD_F(0x047fe653) /* 0.281225513 */, 18 },
4783 /* 4475 */ { MAD_F(0x04803e35) /* 0.281309326 */, 18 },
4784 /* 4476 */ { MAD_F(0x04809619) /* 0.281393146 */, 18 },
4785 /* 4477 */ { MAD_F(0x0480edff) /* 0.281476972 */, 18 },
4786 /* 4478 */ { MAD_F(0x048145e7) /* 0.281560804 */, 18 },
4787 /* 4479 */ { MAD_F(0x04819dd0) /* 0.281644643 */, 18 },
4788
4789 /* 4480 */ { MAD_F(0x0481f5bb) /* 0.281728487 */, 18 },
4790 /* 4481 */ { MAD_F(0x04824da7) /* 0.281812338 */, 18 },
4791 /* 4482 */ { MAD_F(0x0482a595) /* 0.281896195 */, 18 },
4792 /* 4483 */ { MAD_F(0x0482fd85) /* 0.281980059 */, 18 },
4793 /* 4484 */ { MAD_F(0x04835577) /* 0.282063928 */, 18 },
4794 /* 4485 */ { MAD_F(0x0483ad6a) /* 0.282147804 */, 18 },
4795 /* 4486 */ { MAD_F(0x0484055f) /* 0.282231686 */, 18 },
4796 /* 4487 */ { MAD_F(0x04845d56) /* 0.282315574 */, 18 },
4797 /* 4488 */ { MAD_F(0x0484b54e) /* 0.282399469 */, 18 },
4798 /* 4489 */ { MAD_F(0x04850d48) /* 0.282483370 */, 18 },
4799 /* 4490 */ { MAD_F(0x04856544) /* 0.282567277 */, 18 },
4800 /* 4491 */ { MAD_F(0x0485bd41) /* 0.282651190 */, 18 },
4801 /* 4492 */ { MAD_F(0x04861540) /* 0.282735109 */, 18 },
4802 /* 4493 */ { MAD_F(0x04866d40) /* 0.282819035 */, 18 },
4803 /* 4494 */ { MAD_F(0x0486c543) /* 0.282902967 */, 18 },
4804 /* 4495 */ { MAD_F(0x04871d47) /* 0.282986905 */, 18 },
4805
4806 /* 4496 */ { MAD_F(0x0487754c) /* 0.283070849 */, 18 },
4807 /* 4497 */ { MAD_F(0x0487cd54) /* 0.283154800 */, 18 },
4808 /* 4498 */ { MAD_F(0x0488255d) /* 0.283238757 */, 18 },
4809 /* 4499 */ { MAD_F(0x04887d67) /* 0.283322720 */, 18 },
4810 /* 4500 */ { MAD_F(0x0488d574) /* 0.283406689 */, 18 },
4811 /* 4501 */ { MAD_F(0x04892d82) /* 0.283490665 */, 18 },
4812 /* 4502 */ { MAD_F(0x04898591) /* 0.283574646 */, 18 },
4813 /* 4503 */ { MAD_F(0x0489dda3) /* 0.283658634 */, 18 },
4814 /* 4504 */ { MAD_F(0x048a35b6) /* 0.283742628 */, 18 },
4815 /* 4505 */ { MAD_F(0x048a8dca) /* 0.283826629 */, 18 },
4816 /* 4506 */ { MAD_F(0x048ae5e1) /* 0.283910635 */, 18 },
4817 /* 4507 */ { MAD_F(0x048b3df9) /* 0.283994648 */, 18 },
4818 /* 4508 */ { MAD_F(0x048b9612) /* 0.284078667 */, 18 },
4819 /* 4509 */ { MAD_F(0x048bee2e) /* 0.284162692 */, 18 },
4820 /* 4510 */ { MAD_F(0x048c464b) /* 0.284246723 */, 18 },
4821 /* 4511 */ { MAD_F(0x048c9e69) /* 0.284330761 */, 18 },
4822
4823 /* 4512 */ { MAD_F(0x048cf68a) /* 0.284414805 */, 18 },
4824 /* 4513 */ { MAD_F(0x048d4eac) /* 0.284498855 */, 18 },
4825 /* 4514 */ { MAD_F(0x048da6cf) /* 0.284582911 */, 18 },
4826 /* 4515 */ { MAD_F(0x048dfef5) /* 0.284666974 */, 18 },
4827 /* 4516 */ { MAD_F(0x048e571c) /* 0.284751042 */, 18 },
4828 /* 4517 */ { MAD_F(0x048eaf44) /* 0.284835117 */, 18 },
4829 /* 4518 */ { MAD_F(0x048f076f) /* 0.284919198 */, 18 },
4830 /* 4519 */ { MAD_F(0x048f5f9b) /* 0.285003285 */, 18 },
4831 /* 4520 */ { MAD_F(0x048fb7c8) /* 0.285087379 */, 18 },
4832 /* 4521 */ { MAD_F(0x04900ff8) /* 0.285171479 */, 18 },
4833 /* 4522 */ { MAD_F(0x04906829) /* 0.285255584 */, 18 },
4834 /* 4523 */ { MAD_F(0x0490c05b) /* 0.285339697 */, 18 },
4835 /* 4524 */ { MAD_F(0x04911890) /* 0.285423815 */, 18 },
4836 /* 4525 */ { MAD_F(0x049170c6) /* 0.285507939 */, 18 },
4837 /* 4526 */ { MAD_F(0x0491c8fd) /* 0.285592070 */, 18 },
4838 /* 4527 */ { MAD_F(0x04922137) /* 0.285676207 */, 18 },
4839
4840 /* 4528 */ { MAD_F(0x04927972) /* 0.285760350 */, 18 },
4841 /* 4529 */ { MAD_F(0x0492d1ae) /* 0.285844499 */, 18 },
4842 /* 4530 */ { MAD_F(0x049329ed) /* 0.285928655 */, 18 },
4843 /* 4531 */ { MAD_F(0x0493822c) /* 0.286012816 */, 18 },
4844 /* 4532 */ { MAD_F(0x0493da6e) /* 0.286096984 */, 18 },
4845 /* 4533 */ { MAD_F(0x049432b1) /* 0.286181158 */, 18 },
4846 /* 4534 */ { MAD_F(0x04948af6) /* 0.286265338 */, 18 },
4847 /* 4535 */ { MAD_F(0x0494e33d) /* 0.286349525 */, 18 },
4848 /* 4536 */ { MAD_F(0x04953b85) /* 0.286433717 */, 18 },
4849 /* 4537 */ { MAD_F(0x049593cf) /* 0.286517916 */, 18 },
4850 /* 4538 */ { MAD_F(0x0495ec1b) /* 0.286602121 */, 18 },
4851 /* 4539 */ { MAD_F(0x04964468) /* 0.286686332 */, 18 },
4852 /* 4540 */ { MAD_F(0x04969cb7) /* 0.286770550 */, 18 },
4853 /* 4541 */ { MAD_F(0x0496f508) /* 0.286854773 */, 18 },
4854 /* 4542 */ { MAD_F(0x04974d5a) /* 0.286939003 */, 18 },
4855 /* 4543 */ { MAD_F(0x0497a5ae) /* 0.287023239 */, 18 },
4856
4857 /* 4544 */ { MAD_F(0x0497fe03) /* 0.287107481 */, 18 },
4858 /* 4545 */ { MAD_F(0x0498565a) /* 0.287191729 */, 18 },
4859 /* 4546 */ { MAD_F(0x0498aeb3) /* 0.287275983 */, 18 },
4860 /* 4547 */ { MAD_F(0x0499070e) /* 0.287360244 */, 18 },
4861 /* 4548 */ { MAD_F(0x04995f6a) /* 0.287444511 */, 18 },
4862 /* 4549 */ { MAD_F(0x0499b7c8) /* 0.287528784 */, 18 },
4863 /* 4550 */ { MAD_F(0x049a1027) /* 0.287613063 */, 18 },
4864 /* 4551 */ { MAD_F(0x049a6889) /* 0.287697348 */, 18 },
4865 /* 4552 */ { MAD_F(0x049ac0eb) /* 0.287781640 */, 18 },
4866 /* 4553 */ { MAD_F(0x049b1950) /* 0.287865937 */, 18 },
4867 /* 4554 */ { MAD_F(0x049b71b6) /* 0.287950241 */, 18 },
4868 /* 4555 */ { MAD_F(0x049bca1e) /* 0.288034551 */, 18 },
4869 /* 4556 */ { MAD_F(0x049c2287) /* 0.288118867 */, 18 },
4870 /* 4557 */ { MAD_F(0x049c7af2) /* 0.288203190 */, 18 },
4871 /* 4558 */ { MAD_F(0x049cd35f) /* 0.288287518 */, 18 },
4872 /* 4559 */ { MAD_F(0x049d2bce) /* 0.288371853 */, 18 },
4873
4874 /* 4560 */ { MAD_F(0x049d843e) /* 0.288456194 */, 18 },
4875 /* 4561 */ { MAD_F(0x049ddcaf) /* 0.288540541 */, 18 },
4876 /* 4562 */ { MAD_F(0x049e3523) /* 0.288624894 */, 18 },
4877 /* 4563 */ { MAD_F(0x049e8d98) /* 0.288709253 */, 18 },
4878 /* 4564 */ { MAD_F(0x049ee60e) /* 0.288793619 */, 18 },
4879 /* 4565 */ { MAD_F(0x049f3e87) /* 0.288877990 */, 18 },
4880 /* 4566 */ { MAD_F(0x049f9701) /* 0.288962368 */, 18 },
4881 /* 4567 */ { MAD_F(0x049fef7c) /* 0.289046752 */, 18 },
4882 /* 4568 */ { MAD_F(0x04a047fa) /* 0.289131142 */, 18 },
4883 /* 4569 */ { MAD_F(0x04a0a079) /* 0.289215538 */, 18 },
4884 /* 4570 */ { MAD_F(0x04a0f8f9) /* 0.289299941 */, 18 },
4885 /* 4571 */ { MAD_F(0x04a1517c) /* 0.289384349 */, 18 },
4886 /* 4572 */ { MAD_F(0x04a1a9ff) /* 0.289468764 */, 18 },
4887 /* 4573 */ { MAD_F(0x04a20285) /* 0.289553185 */, 18 },
4888 /* 4574 */ { MAD_F(0x04a25b0c) /* 0.289637612 */, 18 },
4889 /* 4575 */ { MAD_F(0x04a2b395) /* 0.289722045 */, 18 },
4890
4891 /* 4576 */ { MAD_F(0x04a30c20) /* 0.289806485 */, 18 },
4892 /* 4577 */ { MAD_F(0x04a364ac) /* 0.289890930 */, 18 },
4893 /* 4578 */ { MAD_F(0x04a3bd3a) /* 0.289975382 */, 18 },
4894 /* 4579 */ { MAD_F(0x04a415c9) /* 0.290059840 */, 18 },
4895 /* 4580 */ { MAD_F(0x04a46e5a) /* 0.290144304 */, 18 },
4896 /* 4581 */ { MAD_F(0x04a4c6ed) /* 0.290228774 */, 18 },
4897 /* 4582 */ { MAD_F(0x04a51f81) /* 0.290313250 */, 18 },
4898 /* 4583 */ { MAD_F(0x04a57818) /* 0.290397733 */, 18 },
4899 /* 4584 */ { MAD_F(0x04a5d0af) /* 0.290482221 */, 18 },
4900 /* 4585 */ { MAD_F(0x04a62949) /* 0.290566716 */, 18 },
4901 /* 4586 */ { MAD_F(0x04a681e4) /* 0.290651217 */, 18 },
4902 /* 4587 */ { MAD_F(0x04a6da80) /* 0.290735724 */, 18 },
4903 /* 4588 */ { MAD_F(0x04a7331f) /* 0.290820237 */, 18 },
4904 /* 4589 */ { MAD_F(0x04a78bbf) /* 0.290904756 */, 18 },
4905 /* 4590 */ { MAD_F(0x04a7e460) /* 0.290989281 */, 18 },
4906 /* 4591 */ { MAD_F(0x04a83d03) /* 0.291073813 */, 18 },
4907
4908 /* 4592 */ { MAD_F(0x04a895a8) /* 0.291158351 */, 18 },
4909 /* 4593 */ { MAD_F(0x04a8ee4f) /* 0.291242894 */, 18 },
4910 /* 4594 */ { MAD_F(0x04a946f7) /* 0.291327444 */, 18 },
4911 /* 4595 */ { MAD_F(0x04a99fa1) /* 0.291412001 */, 18 },
4912 /* 4596 */ { MAD_F(0x04a9f84c) /* 0.291496563 */, 18 },
4913 /* 4597 */ { MAD_F(0x04aa50fa) /* 0.291581131 */, 18 },
4914 /* 4598 */ { MAD_F(0x04aaa9a8) /* 0.291665706 */, 18 },
4915 /* 4599 */ { MAD_F(0x04ab0259) /* 0.291750286 */, 18 },
4916 /* 4600 */ { MAD_F(0x04ab5b0b) /* 0.291834873 */, 18 },
4917 /* 4601 */ { MAD_F(0x04abb3bf) /* 0.291919466 */, 18 },
4918 /* 4602 */ { MAD_F(0x04ac0c74) /* 0.292004065 */, 18 },
4919 /* 4603 */ { MAD_F(0x04ac652b) /* 0.292088670 */, 18 },
4920 /* 4604 */ { MAD_F(0x04acbde4) /* 0.292173281 */, 18 },
4921 /* 4605 */ { MAD_F(0x04ad169e) /* 0.292257899 */, 18 },
4922 /* 4606 */ { MAD_F(0x04ad6f5a) /* 0.292342522 */, 18 },
4923 /* 4607 */ { MAD_F(0x04adc818) /* 0.292427152 */, 18 },
4924
4925 /* 4608 */ { MAD_F(0x04ae20d7) /* 0.292511788 */, 18 },
4926 /* 4609 */ { MAD_F(0x04ae7998) /* 0.292596430 */, 18 },
4927 /* 4610 */ { MAD_F(0x04aed25a) /* 0.292681078 */, 18 },
4928 /* 4611 */ { MAD_F(0x04af2b1e) /* 0.292765732 */, 18 },
4929 /* 4612 */ { MAD_F(0x04af83e4) /* 0.292850392 */, 18 },
4930 /* 4613 */ { MAD_F(0x04afdcac) /* 0.292935058 */, 18 },
4931 /* 4614 */ { MAD_F(0x04b03575) /* 0.293019731 */, 18 },
4932 /* 4615 */ { MAD_F(0x04b08e40) /* 0.293104409 */, 18 },
4933 /* 4616 */ { MAD_F(0x04b0e70c) /* 0.293189094 */, 18 },
4934 /* 4617 */ { MAD_F(0x04b13fda) /* 0.293273785 */, 18 },
4935 /* 4618 */ { MAD_F(0x04b198aa) /* 0.293358482 */, 18 },
4936 /* 4619 */ { MAD_F(0x04b1f17b) /* 0.293443185 */, 18 },
4937 /* 4620 */ { MAD_F(0x04b24a4e) /* 0.293527894 */, 18 },
4938 /* 4621 */ { MAD_F(0x04b2a322) /* 0.293612609 */, 18 },
4939 /* 4622 */ { MAD_F(0x04b2fbf9) /* 0.293697331 */, 18 },
4940 /* 4623 */ { MAD_F(0x04b354d1) /* 0.293782058 */, 18 },
4941
4942 /* 4624 */ { MAD_F(0x04b3adaa) /* 0.293866792 */, 18 },
4943 /* 4625 */ { MAD_F(0x04b40685) /* 0.293951532 */, 18 },
4944 /* 4626 */ { MAD_F(0x04b45f62) /* 0.294036278 */, 18 },
4945 /* 4627 */ { MAD_F(0x04b4b840) /* 0.294121029 */, 18 },
4946 /* 4628 */ { MAD_F(0x04b51120) /* 0.294205788 */, 18 },
4947 /* 4629 */ { MAD_F(0x04b56a02) /* 0.294290552 */, 18 },
4948 /* 4630 */ { MAD_F(0x04b5c2e6) /* 0.294375322 */, 18 },
4949 /* 4631 */ { MAD_F(0x04b61bcb) /* 0.294460098 */, 18 },
4950 /* 4632 */ { MAD_F(0x04b674b1) /* 0.294544881 */, 18 },
4951 /* 4633 */ { MAD_F(0x04b6cd99) /* 0.294629669 */, 18 },
4952 /* 4634 */ { MAD_F(0x04b72683) /* 0.294714464 */, 18 },
4953 /* 4635 */ { MAD_F(0x04b77f6f) /* 0.294799265 */, 18 },
4954 /* 4636 */ { MAD_F(0x04b7d85c) /* 0.294884072 */, 18 },
4955 /* 4637 */ { MAD_F(0x04b8314b) /* 0.294968885 */, 18 },
4956 /* 4638 */ { MAD_F(0x04b88a3b) /* 0.295053704 */, 18 },
4957 /* 4639 */ { MAD_F(0x04b8e32d) /* 0.295138529 */, 18 },
4958
4959 /* 4640 */ { MAD_F(0x04b93c21) /* 0.295223360 */, 18 },
4960 /* 4641 */ { MAD_F(0x04b99516) /* 0.295308197 */, 18 },
4961 /* 4642 */ { MAD_F(0x04b9ee0d) /* 0.295393041 */, 18 },
4962 /* 4643 */ { MAD_F(0x04ba4706) /* 0.295477890 */, 18 },
4963 /* 4644 */ { MAD_F(0x04baa000) /* 0.295562746 */, 18 },
4964 /* 4645 */ { MAD_F(0x04baf8fc) /* 0.295647608 */, 18 },
4965 /* 4646 */ { MAD_F(0x04bb51fa) /* 0.295732476 */, 18 },
4966 /* 4647 */ { MAD_F(0x04bbaaf9) /* 0.295817349 */, 18 },
4967 /* 4648 */ { MAD_F(0x04bc03fa) /* 0.295902229 */, 18 },
4968 /* 4649 */ { MAD_F(0x04bc5cfc) /* 0.295987115 */, 18 },
4969 /* 4650 */ { MAD_F(0x04bcb600) /* 0.296072008 */, 18 },
4970 /* 4651 */ { MAD_F(0x04bd0f06) /* 0.296156906 */, 18 },
4971 /* 4652 */ { MAD_F(0x04bd680d) /* 0.296241810 */, 18 },
4972 /* 4653 */ { MAD_F(0x04bdc116) /* 0.296326721 */, 18 },
4973 /* 4654 */ { MAD_F(0x04be1a21) /* 0.296411637 */, 18 },
4974 /* 4655 */ { MAD_F(0x04be732d) /* 0.296496560 */, 18 },
4975
4976 /* 4656 */ { MAD_F(0x04becc3b) /* 0.296581488 */, 18 },
4977 /* 4657 */ { MAD_F(0x04bf254a) /* 0.296666423 */, 18 },
4978 /* 4658 */ { MAD_F(0x04bf7e5b) /* 0.296751364 */, 18 },
4979 /* 4659 */ { MAD_F(0x04bfd76e) /* 0.296836311 */, 18 },
4980 /* 4660 */ { MAD_F(0x04c03083) /* 0.296921264 */, 18 },
4981 /* 4661 */ { MAD_F(0x04c08999) /* 0.297006223 */, 18 },
4982 /* 4662 */ { MAD_F(0x04c0e2b0) /* 0.297091188 */, 18 },
4983 /* 4663 */ { MAD_F(0x04c13bca) /* 0.297176159 */, 18 },
4984 /* 4664 */ { MAD_F(0x04c194e4) /* 0.297261136 */, 18 },
4985 /* 4665 */ { MAD_F(0x04c1ee01) /* 0.297346120 */, 18 },
4986 /* 4666 */ { MAD_F(0x04c2471f) /* 0.297431109 */, 18 },
4987 /* 4667 */ { MAD_F(0x04c2a03f) /* 0.297516105 */, 18 },
4988 /* 4668 */ { MAD_F(0x04c2f960) /* 0.297601106 */, 18 },
4989 /* 4669 */ { MAD_F(0x04c35283) /* 0.297686114 */, 18 },
4990 /* 4670 */ { MAD_F(0x04c3aba8) /* 0.297771128 */, 18 },
4991 /* 4671 */ { MAD_F(0x04c404ce) /* 0.297856147 */, 18 },
4992
4993 /* 4672 */ { MAD_F(0x04c45df6) /* 0.297941173 */, 18 },
4994 /* 4673 */ { MAD_F(0x04c4b720) /* 0.298026205 */, 18 },
4995 /* 4674 */ { MAD_F(0x04c5104b) /* 0.298111243 */, 18 },
4996 /* 4675 */ { MAD_F(0x04c56978) /* 0.298196287 */, 18 },
4997 /* 4676 */ { MAD_F(0x04c5c2a7) /* 0.298281337 */, 18 },
4998 /* 4677 */ { MAD_F(0x04c61bd7) /* 0.298366393 */, 18 },
4999 /* 4678 */ { MAD_F(0x04c67508) /* 0.298451456 */, 18 },
5000 /* 4679 */ { MAD_F(0x04c6ce3c) /* 0.298536524 */, 18 },
5001 /* 4680 */ { MAD_F(0x04c72771) /* 0.298621598 */, 18 },
5002 /* 4681 */ { MAD_F(0x04c780a7) /* 0.298706679 */, 18 },
5003 /* 4682 */ { MAD_F(0x04c7d9df) /* 0.298791765 */, 18 },
5004 /* 4683 */ { MAD_F(0x04c83319) /* 0.298876858 */, 18 },
5005 /* 4684 */ { MAD_F(0x04c88c55) /* 0.298961956 */, 18 },
5006 /* 4685 */ { MAD_F(0x04c8e592) /* 0.299047061 */, 18 },
5007 /* 4686 */ { MAD_F(0x04c93ed1) /* 0.299132172 */, 18 },
5008 /* 4687 */ { MAD_F(0x04c99811) /* 0.299217288 */, 18 },
5009
5010 /* 4688 */ { MAD_F(0x04c9f153) /* 0.299302411 */, 18 },
5011 /* 4689 */ { MAD_F(0x04ca4a97) /* 0.299387540 */, 18 },
5012 /* 4690 */ { MAD_F(0x04caa3dc) /* 0.299472675 */, 18 },
5013 /* 4691 */ { MAD_F(0x04cafd23) /* 0.299557816 */, 18 },
5014 /* 4692 */ { MAD_F(0x04cb566b) /* 0.299642963 */, 18 },
5015 /* 4693 */ { MAD_F(0x04cbafb5) /* 0.299728116 */, 18 },
5016 /* 4694 */ { MAD_F(0x04cc0901) /* 0.299813275 */, 18 },
5017 /* 4695 */ { MAD_F(0x04cc624e) /* 0.299898440 */, 18 },
5018 /* 4696 */ { MAD_F(0x04ccbb9d) /* 0.299983611 */, 18 },
5019 /* 4697 */ { MAD_F(0x04cd14ee) /* 0.300068789 */, 18 },
5020 /* 4698 */ { MAD_F(0x04cd6e40) /* 0.300153972 */, 18 },
5021 /* 4699 */ { MAD_F(0x04cdc794) /* 0.300239161 */, 18 },
5022 /* 4700 */ { MAD_F(0x04ce20e9) /* 0.300324357 */, 18 },
5023 /* 4701 */ { MAD_F(0x04ce7a40) /* 0.300409558 */, 18 },
5024 /* 4702 */ { MAD_F(0x04ced399) /* 0.300494765 */, 18 },
5025 /* 4703 */ { MAD_F(0x04cf2cf3) /* 0.300579979 */, 18 },
5026
5027 /* 4704 */ { MAD_F(0x04cf864f) /* 0.300665198 */, 18 },
5028 /* 4705 */ { MAD_F(0x04cfdfad) /* 0.300750424 */, 18 },
5029 /* 4706 */ { MAD_F(0x04d0390c) /* 0.300835656 */, 18 },
5030 /* 4707 */ { MAD_F(0x04d0926d) /* 0.300920893 */, 18 },
5031 /* 4708 */ { MAD_F(0x04d0ebcf) /* 0.301006137 */, 18 },
5032 /* 4709 */ { MAD_F(0x04d14533) /* 0.301091387 */, 18 },
5033 /* 4710 */ { MAD_F(0x04d19e99) /* 0.301176643 */, 18 },
5034 /* 4711 */ { MAD_F(0x04d1f800) /* 0.301261904 */, 18 },
5035 /* 4712 */ { MAD_F(0x04d25169) /* 0.301347172 */, 18 },
5036 /* 4713 */ { MAD_F(0x04d2aad4) /* 0.301432446 */, 18 },
5037 /* 4714 */ { MAD_F(0x04d30440) /* 0.301517726 */, 18 },
5038 /* 4715 */ { MAD_F(0x04d35dae) /* 0.301603012 */, 18 },
5039 /* 4716 */ { MAD_F(0x04d3b71d) /* 0.301688304 */, 18 },
5040 /* 4717 */ { MAD_F(0x04d4108e) /* 0.301773602 */, 18 },
5041 /* 4718 */ { MAD_F(0x04d46a01) /* 0.301858906 */, 18 },
5042 /* 4719 */ { MAD_F(0x04d4c375) /* 0.301944216 */, 18 },
5043
5044 /* 4720 */ { MAD_F(0x04d51ceb) /* 0.302029532 */, 18 },
5045 /* 4721 */ { MAD_F(0x04d57662) /* 0.302114854 */, 18 },
5046 /* 4722 */ { MAD_F(0x04d5cfdb) /* 0.302200182 */, 18 },
5047 /* 4723 */ { MAD_F(0x04d62956) /* 0.302285516 */, 18 },
5048 /* 4724 */ { MAD_F(0x04d682d2) /* 0.302370856 */, 18 },
5049 /* 4725 */ { MAD_F(0x04d6dc50) /* 0.302456203 */, 18 },
5050 /* 4726 */ { MAD_F(0x04d735d0) /* 0.302541555 */, 18 },
5051 /* 4727 */ { MAD_F(0x04d78f51) /* 0.302626913 */, 18 },
5052 /* 4728 */ { MAD_F(0x04d7e8d4) /* 0.302712277 */, 18 },
5053 /* 4729 */ { MAD_F(0x04d84258) /* 0.302797648 */, 18 },
5054 /* 4730 */ { MAD_F(0x04d89bde) /* 0.302883024 */, 18 },
5055 /* 4731 */ { MAD_F(0x04d8f566) /* 0.302968406 */, 18 },
5056 /* 4732 */ { MAD_F(0x04d94eef) /* 0.303053794 */, 18 },
5057 /* 4733 */ { MAD_F(0x04d9a87a) /* 0.303139189 */, 18 },
5058 /* 4734 */ { MAD_F(0x04da0207) /* 0.303224589 */, 18 },
5059 /* 4735 */ { MAD_F(0x04da5b95) /* 0.303309995 */, 18 },
5060
5061 /* 4736 */ { MAD_F(0x04dab524) /* 0.303395408 */, 18 },
5062 /* 4737 */ { MAD_F(0x04db0eb6) /* 0.303480826 */, 18 },
5063 /* 4738 */ { MAD_F(0x04db6849) /* 0.303566251 */, 18 },
5064 /* 4739 */ { MAD_F(0x04dbc1dd) /* 0.303651681 */, 18 },
5065 /* 4740 */ { MAD_F(0x04dc1b73) /* 0.303737117 */, 18 },
5066 /* 4741 */ { MAD_F(0x04dc750b) /* 0.303822560 */, 18 },
5067 /* 4742 */ { MAD_F(0x04dccea5) /* 0.303908008 */, 18 },
5068 /* 4743 */ { MAD_F(0x04dd2840) /* 0.303993463 */, 18 },
5069 /* 4744 */ { MAD_F(0x04dd81dc) /* 0.304078923 */, 18 },
5070 /* 4745 */ { MAD_F(0x04dddb7a) /* 0.304164390 */, 18 },
5071 /* 4746 */ { MAD_F(0x04de351a) /* 0.304249862 */, 18 },
5072 /* 4747 */ { MAD_F(0x04de8ebc) /* 0.304335340 */, 18 },
5073 /* 4748 */ { MAD_F(0x04dee85f) /* 0.304420825 */, 18 },
5074 /* 4749 */ { MAD_F(0x04df4203) /* 0.304506315 */, 18 },
5075 /* 4750 */ { MAD_F(0x04df9baa) /* 0.304591812 */, 18 },
5076 /* 4751 */ { MAD_F(0x04dff552) /* 0.304677314 */, 18 },
5077
5078 /* 4752 */ { MAD_F(0x04e04efb) /* 0.304762823 */, 18 },
5079 /* 4753 */ { MAD_F(0x04e0a8a6) /* 0.304848337 */, 18 },
5080 /* 4754 */ { MAD_F(0x04e10253) /* 0.304933858 */, 18 },
5081 /* 4755 */ { MAD_F(0x04e15c01) /* 0.305019384 */, 18 },
5082 /* 4756 */ { MAD_F(0x04e1b5b1) /* 0.305104917 */, 18 },
5083 /* 4757 */ { MAD_F(0x04e20f63) /* 0.305190455 */, 18 },
5084 /* 4758 */ { MAD_F(0x04e26916) /* 0.305275999 */, 18 },
5085 /* 4759 */ { MAD_F(0x04e2c2cb) /* 0.305361550 */, 18 },
5086 /* 4760 */ { MAD_F(0x04e31c81) /* 0.305447106 */, 18 },
5087 /* 4761 */ { MAD_F(0x04e37639) /* 0.305532669 */, 18 },
5088 /* 4762 */ { MAD_F(0x04e3cff3) /* 0.305618237 */, 18 },
5089 /* 4763 */ { MAD_F(0x04e429ae) /* 0.305703811 */, 18 },
5090 /* 4764 */ { MAD_F(0x04e4836b) /* 0.305789392 */, 18 },
5091 /* 4765 */ { MAD_F(0x04e4dd29) /* 0.305874978 */, 18 },
5092 /* 4766 */ { MAD_F(0x04e536e9) /* 0.305960571 */, 18 },
5093 /* 4767 */ { MAD_F(0x04e590ab) /* 0.306046169 */, 18 },
5094
5095 /* 4768 */ { MAD_F(0x04e5ea6e) /* 0.306131773 */, 18 },
5096 /* 4769 */ { MAD_F(0x04e64433) /* 0.306217383 */, 18 },
5097 /* 4770 */ { MAD_F(0x04e69df9) /* 0.306303000 */, 18 },
5098 /* 4771 */ { MAD_F(0x04e6f7c1) /* 0.306388622 */, 18 },
5099 /* 4772 */ { MAD_F(0x04e7518b) /* 0.306474250 */, 18 },
5100 /* 4773 */ { MAD_F(0x04e7ab56) /* 0.306559885 */, 18 },
5101 /* 4774 */ { MAD_F(0x04e80523) /* 0.306645525 */, 18 },
5102 /* 4775 */ { MAD_F(0x04e85ef2) /* 0.306731171 */, 18 },
5103 /* 4776 */ { MAD_F(0x04e8b8c2) /* 0.306816823 */, 18 },
5104 /* 4777 */ { MAD_F(0x04e91293) /* 0.306902481 */, 18 },
5105 /* 4778 */ { MAD_F(0x04e96c67) /* 0.306988145 */, 18 },
5106 /* 4779 */ { MAD_F(0x04e9c63b) /* 0.307073816 */, 18 },
5107 /* 4780 */ { MAD_F(0x04ea2012) /* 0.307159492 */, 18 },
5108 /* 4781 */ { MAD_F(0x04ea79ea) /* 0.307245174 */, 18 },
5109 /* 4782 */ { MAD_F(0x04ead3c4) /* 0.307330862 */, 18 },
5110 /* 4783 */ { MAD_F(0x04eb2d9f) /* 0.307416556 */, 18 },
5111
5112 /* 4784 */ { MAD_F(0x04eb877c) /* 0.307502256 */, 18 },
5113 /* 4785 */ { MAD_F(0x04ebe15b) /* 0.307587962 */, 18 },
5114 /* 4786 */ { MAD_F(0x04ec3b3b) /* 0.307673674 */, 18 },
5115 /* 4787 */ { MAD_F(0x04ec951c) /* 0.307759392 */, 18 },
5116 /* 4788 */ { MAD_F(0x04ecef00) /* 0.307845115 */, 18 },
5117 /* 4789 */ { MAD_F(0x04ed48e5) /* 0.307930845 */, 18 },
5118 /* 4790 */ { MAD_F(0x04eda2cb) /* 0.308016581 */, 18 },
5119 /* 4791 */ { MAD_F(0x04edfcb3) /* 0.308102323 */, 18 },
5120 /* 4792 */ { MAD_F(0x04ee569d) /* 0.308188071 */, 18 },
5121 /* 4793 */ { MAD_F(0x04eeb088) /* 0.308273824 */, 18 },
5122 /* 4794 */ { MAD_F(0x04ef0a75) /* 0.308359584 */, 18 },
5123 /* 4795 */ { MAD_F(0x04ef6464) /* 0.308445350 */, 18 },
5124 /* 4796 */ { MAD_F(0x04efbe54) /* 0.308531121 */, 18 },
5125 /* 4797 */ { MAD_F(0x04f01846) /* 0.308616899 */, 18 },
5126 /* 4798 */ { MAD_F(0x04f07239) /* 0.308702682 */, 18 },
5127 /* 4799 */ { MAD_F(0x04f0cc2e) /* 0.308788472 */, 18 },
5128
5129 /* 4800 */ { MAD_F(0x04f12624) /* 0.308874267 */, 18 },
5130 /* 4801 */ { MAD_F(0x04f1801d) /* 0.308960068 */, 18 },
5131 /* 4802 */ { MAD_F(0x04f1da16) /* 0.309045876 */, 18 },
5132 /* 4803 */ { MAD_F(0x04f23412) /* 0.309131689 */, 18 },
5133 /* 4804 */ { MAD_F(0x04f28e0f) /* 0.309217508 */, 18 },
5134 /* 4805 */ { MAD_F(0x04f2e80d) /* 0.309303334 */, 18 },
5135 /* 4806 */ { MAD_F(0x04f3420d) /* 0.309389165 */, 18 },
5136 /* 4807 */ { MAD_F(0x04f39c0f) /* 0.309475002 */, 18 },
5137 /* 4808 */ { MAD_F(0x04f3f612) /* 0.309560845 */, 18 },
5138 /* 4809 */ { MAD_F(0x04f45017) /* 0.309646694 */, 18 },
5139 /* 4810 */ { MAD_F(0x04f4aa1e) /* 0.309732549 */, 18 },
5140 /* 4811 */ { MAD_F(0x04f50426) /* 0.309818410 */, 18 },
5141 /* 4812 */ { MAD_F(0x04f55e30) /* 0.309904277 */, 18 },
5142 /* 4813 */ { MAD_F(0x04f5b83b) /* 0.309990150 */, 18 },
5143 /* 4814 */ { MAD_F(0x04f61248) /* 0.310076028 */, 18 },
5144 /* 4815 */ { MAD_F(0x04f66c56) /* 0.310161913 */, 18 },
5145
5146 /* 4816 */ { MAD_F(0x04f6c666) /* 0.310247804 */, 18 },
5147 /* 4817 */ { MAD_F(0x04f72078) /* 0.310333700 */, 18 },
5148 /* 4818 */ { MAD_F(0x04f77a8b) /* 0.310419603 */, 18 },
5149 /* 4819 */ { MAD_F(0x04f7d4a0) /* 0.310505511 */, 18 },
5150 /* 4820 */ { MAD_F(0x04f82eb7) /* 0.310591426 */, 18 },
5151 /* 4821 */ { MAD_F(0x04f888cf) /* 0.310677346 */, 18 },
5152 /* 4822 */ { MAD_F(0x04f8e2e9) /* 0.310763272 */, 18 },
5153 /* 4823 */ { MAD_F(0x04f93d04) /* 0.310849205 */, 18 },
5154 /* 4824 */ { MAD_F(0x04f99721) /* 0.310935143 */, 18 },
5155 /* 4825 */ { MAD_F(0x04f9f13f) /* 0.311021087 */, 18 },
5156 /* 4826 */ { MAD_F(0x04fa4b5f) /* 0.311107037 */, 18 },
5157 /* 4827 */ { MAD_F(0x04faa581) /* 0.311192993 */, 18 },
5158 /* 4828 */ { MAD_F(0x04faffa4) /* 0.311278955 */, 18 },
5159 /* 4829 */ { MAD_F(0x04fb59c9) /* 0.311364923 */, 18 },
5160 /* 4830 */ { MAD_F(0x04fbb3ef) /* 0.311450897 */, 18 },
5161 /* 4831 */ { MAD_F(0x04fc0e17) /* 0.311536877 */, 18 },
5162
5163 /* 4832 */ { MAD_F(0x04fc6841) /* 0.311622862 */, 18 },
5164 /* 4833 */ { MAD_F(0x04fcc26c) /* 0.311708854 */, 18 },
5165 /* 4834 */ { MAD_F(0x04fd1c99) /* 0.311794851 */, 18 },
5166 /* 4835 */ { MAD_F(0x04fd76c7) /* 0.311880855 */, 18 },
5167 /* 4836 */ { MAD_F(0x04fdd0f7) /* 0.311966864 */, 18 },
5168 /* 4837 */ { MAD_F(0x04fe2b29) /* 0.312052880 */, 18 },
5169 /* 4838 */ { MAD_F(0x04fe855c) /* 0.312138901 */, 18 },
5170 /* 4839 */ { MAD_F(0x04fedf91) /* 0.312224928 */, 18 },
5171 /* 4840 */ { MAD_F(0x04ff39c7) /* 0.312310961 */, 18 },
5172 /* 4841 */ { MAD_F(0x04ff93ff) /* 0.312397000 */, 18 },
5173 /* 4842 */ { MAD_F(0x04ffee38) /* 0.312483045 */, 18 },
5174 /* 4843 */ { MAD_F(0x05004874) /* 0.312569096 */, 18 },
5175 /* 4844 */ { MAD_F(0x0500a2b0) /* 0.312655153 */, 18 },
5176 /* 4845 */ { MAD_F(0x0500fcef) /* 0.312741216 */, 18 },
5177 /* 4846 */ { MAD_F(0x0501572e) /* 0.312827284 */, 18 },
5178 /* 4847 */ { MAD_F(0x0501b170) /* 0.312913359 */, 18 },
5179
5180 /* 4848 */ { MAD_F(0x05020bb3) /* 0.312999439 */, 18 },
5181 /* 4849 */ { MAD_F(0x050265f8) /* 0.313085526 */, 18 },
5182 /* 4850 */ { MAD_F(0x0502c03e) /* 0.313171618 */, 18 },
5183 /* 4851 */ { MAD_F(0x05031a86) /* 0.313257716 */, 18 },
5184 /* 4852 */ { MAD_F(0x050374cf) /* 0.313343820 */, 18 },
5185 /* 4853 */ { MAD_F(0x0503cf1a) /* 0.313429931 */, 18 },
5186 /* 4854 */ { MAD_F(0x05042967) /* 0.313516047 */, 18 },
5187 /* 4855 */ { MAD_F(0x050483b5) /* 0.313602168 */, 18 },
5188 /* 4856 */ { MAD_F(0x0504de05) /* 0.313688296 */, 18 },
5189 /* 4857 */ { MAD_F(0x05053856) /* 0.313774430 */, 18 },
5190 /* 4858 */ { MAD_F(0x050592a9) /* 0.313860570 */, 18 },
5191 /* 4859 */ { MAD_F(0x0505ecfd) /* 0.313946715 */, 18 },
5192 /* 4860 */ { MAD_F(0x05064754) /* 0.314032867 */, 18 },
5193 /* 4861 */ { MAD_F(0x0506a1ab) /* 0.314119024 */, 18 },
5194 /* 4862 */ { MAD_F(0x0506fc04) /* 0.314205187 */, 18 },
5195 /* 4863 */ { MAD_F(0x0507565f) /* 0.314291357 */, 18 },
5196
5197 /* 4864 */ { MAD_F(0x0507b0bc) /* 0.314377532 */, 18 },
5198 /* 4865 */ { MAD_F(0x05080b1a) /* 0.314463713 */, 18 },
5199 /* 4866 */ { MAD_F(0x05086579) /* 0.314549900 */, 18 },
5200 /* 4867 */ { MAD_F(0x0508bfdb) /* 0.314636092 */, 18 },
5201 /* 4868 */ { MAD_F(0x05091a3d) /* 0.314722291 */, 18 },
5202 /* 4869 */ { MAD_F(0x050974a2) /* 0.314808496 */, 18 },
5203 /* 4870 */ { MAD_F(0x0509cf08) /* 0.314894706 */, 18 },
5204 /* 4871 */ { MAD_F(0x050a296f) /* 0.314980923 */, 18 },
5205 /* 4872 */ { MAD_F(0x050a83d8) /* 0.315067145 */, 18 },
5206 /* 4873 */ { MAD_F(0x050ade43) /* 0.315153373 */, 18 },
5207 /* 4874 */ { MAD_F(0x050b38af) /* 0.315239607 */, 18 },
5208 /* 4875 */ { MAD_F(0x050b931d) /* 0.315325847 */, 18 },
5209 /* 4876 */ { MAD_F(0x050bed8d) /* 0.315412093 */, 18 },
5210 /* 4877 */ { MAD_F(0x050c47fe) /* 0.315498345 */, 18 },
5211 /* 4878 */ { MAD_F(0x050ca271) /* 0.315584603 */, 18 },
5212 /* 4879 */ { MAD_F(0x050cfce5) /* 0.315670866 */, 18 },
5213
5214 /* 4880 */ { MAD_F(0x050d575b) /* 0.315757136 */, 18 },
5215 /* 4881 */ { MAD_F(0x050db1d2) /* 0.315843411 */, 18 },
5216 /* 4882 */ { MAD_F(0x050e0c4b) /* 0.315929693 */, 18 },
5217 /* 4883 */ { MAD_F(0x050e66c5) /* 0.316015980 */, 18 },
5218 /* 4884 */ { MAD_F(0x050ec141) /* 0.316102273 */, 18 },
5219 /* 4885 */ { MAD_F(0x050f1bbf) /* 0.316188572 */, 18 },
5220 /* 4886 */ { MAD_F(0x050f763e) /* 0.316274877 */, 18 },
5221 /* 4887 */ { MAD_F(0x050fd0bf) /* 0.316361187 */, 18 },
5222 /* 4888 */ { MAD_F(0x05102b42) /* 0.316447504 */, 18 },
5223 /* 4889 */ { MAD_F(0x051085c6) /* 0.316533826 */, 18 },
5224 /* 4890 */ { MAD_F(0x0510e04b) /* 0.316620155 */, 18 },
5225 /* 4891 */ { MAD_F(0x05113ad3) /* 0.316706489 */, 18 },
5226 /* 4892 */ { MAD_F(0x0511955b) /* 0.316792829 */, 18 },
5227 /* 4893 */ { MAD_F(0x0511efe6) /* 0.316879175 */, 18 },
5228 /* 4894 */ { MAD_F(0x05124a72) /* 0.316965527 */, 18 },
5229 /* 4895 */ { MAD_F(0x0512a4ff) /* 0.317051885 */, 18 },
5230
5231 /* 4896 */ { MAD_F(0x0512ff8e) /* 0.317138249 */, 18 },
5232 /* 4897 */ { MAD_F(0x05135a1f) /* 0.317224618 */, 18 },
5233 /* 4898 */ { MAD_F(0x0513b4b1) /* 0.317310994 */, 18 },
5234 /* 4899 */ { MAD_F(0x05140f45) /* 0.317397375 */, 18 },
5235 /* 4900 */ { MAD_F(0x051469da) /* 0.317483762 */, 18 },
5236 /* 4901 */ { MAD_F(0x0514c471) /* 0.317570155 */, 18 },
5237 /* 4902 */ { MAD_F(0x05151f0a) /* 0.317656554 */, 18 },
5238 /* 4903 */ { MAD_F(0x051579a4) /* 0.317742959 */, 18 },
5239 /* 4904 */ { MAD_F(0x0515d440) /* 0.317829370 */, 18 },
5240 /* 4905 */ { MAD_F(0x05162edd) /* 0.317915786 */, 18 },
5241 /* 4906 */ { MAD_F(0x0516897c) /* 0.318002209 */, 18 },
5242 /* 4907 */ { MAD_F(0x0516e41c) /* 0.318088637 */, 18 },
5243 /* 4908 */ { MAD_F(0x05173ebe) /* 0.318175071 */, 18 },
5244 /* 4909 */ { MAD_F(0x05179962) /* 0.318261511 */, 18 },
5245 /* 4910 */ { MAD_F(0x0517f407) /* 0.318347957 */, 18 },
5246 /* 4911 */ { MAD_F(0x05184eae) /* 0.318434409 */, 18 },
5247
5248 /* 4912 */ { MAD_F(0x0518a956) /* 0.318520867 */, 18 },
5249 /* 4913 */ { MAD_F(0x05190400) /* 0.318607330 */, 18 },
5250 /* 4914 */ { MAD_F(0x05195eab) /* 0.318693800 */, 18 },
5251 /* 4915 */ { MAD_F(0x0519b958) /* 0.318780275 */, 18 },
5252 /* 4916 */ { MAD_F(0x051a1407) /* 0.318866756 */, 18 },
5253 /* 4917 */ { MAD_F(0x051a6eb7) /* 0.318953243 */, 18 },
5254 /* 4918 */ { MAD_F(0x051ac969) /* 0.319039736 */, 18 },
5255 /* 4919 */ { MAD_F(0x051b241c) /* 0.319126235 */, 18 },
5256 /* 4920 */ { MAD_F(0x051b7ed1) /* 0.319212739 */, 18 },
5257 /* 4921 */ { MAD_F(0x051bd987) /* 0.319299250 */, 18 },
5258 /* 4922 */ { MAD_F(0x051c3440) /* 0.319385766 */, 18 },
5259 /* 4923 */ { MAD_F(0x051c8ef9) /* 0.319472288 */, 18 },
5260 /* 4924 */ { MAD_F(0x051ce9b4) /* 0.319558816 */, 18 },
5261 /* 4925 */ { MAD_F(0x051d4471) /* 0.319645350 */, 18 },
5262 /* 4926 */ { MAD_F(0x051d9f2f) /* 0.319731890 */, 18 },
5263 /* 4927 */ { MAD_F(0x051df9ef) /* 0.319818435 */, 18 },
5264
5265 /* 4928 */ { MAD_F(0x051e54b1) /* 0.319904987 */, 18 },
5266 /* 4929 */ { MAD_F(0x051eaf74) /* 0.319991544 */, 18 },
5267 /* 4930 */ { MAD_F(0x051f0a38) /* 0.320078107 */, 18 },
5268 /* 4931 */ { MAD_F(0x051f64ff) /* 0.320164676 */, 18 },
5269 /* 4932 */ { MAD_F(0x051fbfc6) /* 0.320251251 */, 18 },
5270 /* 4933 */ { MAD_F(0x05201a90) /* 0.320337832 */, 18 },
5271 /* 4934 */ { MAD_F(0x0520755b) /* 0.320424419 */, 18 },
5272 /* 4935 */ { MAD_F(0x0520d027) /* 0.320511011 */, 18 },
5273 /* 4936 */ { MAD_F(0x05212af5) /* 0.320597609 */, 18 },
5274 /* 4937 */ { MAD_F(0x052185c5) /* 0.320684213 */, 18 },
5275 /* 4938 */ { MAD_F(0x0521e096) /* 0.320770823 */, 18 },
5276 /* 4939 */ { MAD_F(0x05223b69) /* 0.320857439 */, 18 },
5277 /* 4940 */ { MAD_F(0x0522963d) /* 0.320944061 */, 18 },
5278 /* 4941 */ { MAD_F(0x0522f113) /* 0.321030688 */, 18 },
5279 /* 4942 */ { MAD_F(0x05234bea) /* 0.321117322 */, 18 },
5280 /* 4943 */ { MAD_F(0x0523a6c3) /* 0.321203961 */, 18 },
5281
5282 /* 4944 */ { MAD_F(0x0524019e) /* 0.321290606 */, 18 },
5283 /* 4945 */ { MAD_F(0x05245c7a) /* 0.321377257 */, 18 },
5284 /* 4946 */ { MAD_F(0x0524b758) /* 0.321463913 */, 18 },
5285 /* 4947 */ { MAD_F(0x05251237) /* 0.321550576 */, 18 },
5286 /* 4948 */ { MAD_F(0x05256d18) /* 0.321637244 */, 18 },
5287 /* 4949 */ { MAD_F(0x0525c7fb) /* 0.321723919 */, 18 },
5288 /* 4950 */ { MAD_F(0x052622df) /* 0.321810599 */, 18 },
5289 /* 4951 */ { MAD_F(0x05267dc4) /* 0.321897285 */, 18 },
5290 /* 4952 */ { MAD_F(0x0526d8ab) /* 0.321983976 */, 18 },
5291 /* 4953 */ { MAD_F(0x05273394) /* 0.322070674 */, 18 },
5292 /* 4954 */ { MAD_F(0x05278e7e) /* 0.322157377 */, 18 },
5293 /* 4955 */ { MAD_F(0x0527e96a) /* 0.322244087 */, 18 },
5294 /* 4956 */ { MAD_F(0x05284457) /* 0.322330802 */, 18 },
5295 /* 4957 */ { MAD_F(0x05289f46) /* 0.322417523 */, 18 },
5296 /* 4958 */ { MAD_F(0x0528fa37) /* 0.322504249 */, 18 },
5297 /* 4959 */ { MAD_F(0x05295529) /* 0.322590982 */, 18 },
5298
5299 /* 4960 */ { MAD_F(0x0529b01d) /* 0.322677720 */, 18 },
5300 /* 4961 */ { MAD_F(0x052a0b12) /* 0.322764465 */, 18 },
5301 /* 4962 */ { MAD_F(0x052a6609) /* 0.322851215 */, 18 },
5302 /* 4963 */ { MAD_F(0x052ac101) /* 0.322937971 */, 18 },
5303 /* 4964 */ { MAD_F(0x052b1bfb) /* 0.323024732 */, 18 },
5304 /* 4965 */ { MAD_F(0x052b76f7) /* 0.323111500 */, 18 },
5305 /* 4966 */ { MAD_F(0x052bd1f4) /* 0.323198273 */, 18 },
5306 /* 4967 */ { MAD_F(0x052c2cf2) /* 0.323285052 */, 18 },
5307 /* 4968 */ { MAD_F(0x052c87f2) /* 0.323371837 */, 18 },
5308 /* 4969 */ { MAD_F(0x052ce2f4) /* 0.323458628 */, 18 },
5309 /* 4970 */ { MAD_F(0x052d3df7) /* 0.323545425 */, 18 },
5310 /* 4971 */ { MAD_F(0x052d98fc) /* 0.323632227 */, 18 },
5311 /* 4972 */ { MAD_F(0x052df403) /* 0.323719036 */, 18 },
5312 /* 4973 */ { MAD_F(0x052e4f0b) /* 0.323805850 */, 18 },
5313 /* 4974 */ { MAD_F(0x052eaa14) /* 0.323892670 */, 18 },
5314 /* 4975 */ { MAD_F(0x052f051f) /* 0.323979496 */, 18 },
5315
5316 /* 4976 */ { MAD_F(0x052f602c) /* 0.324066327 */, 18 },
5317 /* 4977 */ { MAD_F(0x052fbb3a) /* 0.324153165 */, 18 },
5318 /* 4978 */ { MAD_F(0x0530164a) /* 0.324240008 */, 18 },
5319 /* 4979 */ { MAD_F(0x0530715b) /* 0.324326857 */, 18 },
5320 /* 4980 */ { MAD_F(0x0530cc6e) /* 0.324413712 */, 18 },
5321 /* 4981 */ { MAD_F(0x05312783) /* 0.324500572 */, 18 },
5322 /* 4982 */ { MAD_F(0x05318299) /* 0.324587439 */, 18 },
5323 /* 4983 */ { MAD_F(0x0531ddb0) /* 0.324674311 */, 18 },
5324 /* 4984 */ { MAD_F(0x053238ca) /* 0.324761189 */, 18 },
5325 /* 4985 */ { MAD_F(0x053293e4) /* 0.324848073 */, 18 },
5326 /* 4986 */ { MAD_F(0x0532ef01) /* 0.324934963 */, 18 },
5327 /* 4987 */ { MAD_F(0x05334a1e) /* 0.325021858 */, 18 },
5328 /* 4988 */ { MAD_F(0x0533a53e) /* 0.325108760 */, 18 },
5329 /* 4989 */ { MAD_F(0x0534005f) /* 0.325195667 */, 18 },
5330 /* 4990 */ { MAD_F(0x05345b81) /* 0.325282580 */, 18 },
5331 /* 4991 */ { MAD_F(0x0534b6a5) /* 0.325369498 */, 18 },
5332
5333 /* 4992 */ { MAD_F(0x053511cb) /* 0.325456423 */, 18 },
5334 /* 4993 */ { MAD_F(0x05356cf2) /* 0.325543353 */, 18 },
5335 /* 4994 */ { MAD_F(0x0535c81b) /* 0.325630290 */, 18 },
5336 /* 4995 */ { MAD_F(0x05362345) /* 0.325717232 */, 18 },
5337 /* 4996 */ { MAD_F(0x05367e71) /* 0.325804179 */, 18 },
5338 /* 4997 */ { MAD_F(0x0536d99f) /* 0.325891133 */, 18 },
5339 /* 4998 */ { MAD_F(0x053734ce) /* 0.325978092 */, 18 },
5340 /* 4999 */ { MAD_F(0x05378ffe) /* 0.326065057 */, 18 },
5341 /* 5000 */ { MAD_F(0x0537eb30) /* 0.326152028 */, 18 },
5342 /* 5001 */ { MAD_F(0x05384664) /* 0.326239005 */, 18 },
5343 /* 5002 */ { MAD_F(0x0538a199) /* 0.326325988 */, 18 },
5344 /* 5003 */ { MAD_F(0x0538fcd0) /* 0.326412976 */, 18 },
5345 /* 5004 */ { MAD_F(0x05395808) /* 0.326499970 */, 18 },
5346 /* 5005 */ { MAD_F(0x0539b342) /* 0.326586970 */, 18 },
5347 /* 5006 */ { MAD_F(0x053a0e7d) /* 0.326673976 */, 18 },
5348 /* 5007 */ { MAD_F(0x053a69ba) /* 0.326760988 */, 18 },
5349
5350 /* 5008 */ { MAD_F(0x053ac4f9) /* 0.326848005 */, 18 },
5351 /* 5009 */ { MAD_F(0x053b2039) /* 0.326935028 */, 18 },
5352 /* 5010 */ { MAD_F(0x053b7b7b) /* 0.327022057 */, 18 },
5353 /* 5011 */ { MAD_F(0x053bd6be) /* 0.327109092 */, 18 },
5354 /* 5012 */ { MAD_F(0x053c3203) /* 0.327196132 */, 18 },
5355 /* 5013 */ { MAD_F(0x053c8d49) /* 0.327283178 */, 18 },
5356 /* 5014 */ { MAD_F(0x053ce891) /* 0.327370231 */, 18 },
5357 /* 5015 */ { MAD_F(0x053d43da) /* 0.327457288 */, 18 },
5358 /* 5016 */ { MAD_F(0x053d9f25) /* 0.327544352 */, 18 },
5359 /* 5017 */ { MAD_F(0x053dfa72) /* 0.327631421 */, 18 },
5360 /* 5018 */ { MAD_F(0x053e55c0) /* 0.327718497 */, 18 },
5361 /* 5019 */ { MAD_F(0x053eb10f) /* 0.327805578 */, 18 },
5362 /* 5020 */ { MAD_F(0x053f0c61) /* 0.327892665 */, 18 },
5363 /* 5021 */ { MAD_F(0x053f67b3) /* 0.327979757 */, 18 },
5364 /* 5022 */ { MAD_F(0x053fc308) /* 0.328066855 */, 18 },
5365 /* 5023 */ { MAD_F(0x05401e5e) /* 0.328153960 */, 18 },
5366
5367 /* 5024 */ { MAD_F(0x054079b5) /* 0.328241070 */, 18 },
5368 /* 5025 */ { MAD_F(0x0540d50e) /* 0.328328185 */, 18 },
5369 /* 5026 */ { MAD_F(0x05413068) /* 0.328415307 */, 18 },
5370 /* 5027 */ { MAD_F(0x05418bc4) /* 0.328502434 */, 18 },
5371 /* 5028 */ { MAD_F(0x0541e722) /* 0.328589567 */, 18 },
5372 /* 5029 */ { MAD_F(0x05424281) /* 0.328676706 */, 18 },
5373 /* 5030 */ { MAD_F(0x05429de2) /* 0.328763850 */, 18 },
5374 /* 5031 */ { MAD_F(0x0542f944) /* 0.328851001 */, 18 },
5375 /* 5032 */ { MAD_F(0x054354a8) /* 0.328938157 */, 18 },
5376 /* 5033 */ { MAD_F(0x0543b00d) /* 0.329025319 */, 18 },
5377 /* 5034 */ { MAD_F(0x05440b74) /* 0.329112486 */, 18 },
5378 /* 5035 */ { MAD_F(0x054466dd) /* 0.329199660 */, 18 },
5379 /* 5036 */ { MAD_F(0x0544c247) /* 0.329286839 */, 18 },
5380 /* 5037 */ { MAD_F(0x05451db2) /* 0.329374024 */, 18 },
5381 /* 5038 */ { MAD_F(0x0545791f) /* 0.329461215 */, 18 },
5382 /* 5039 */ { MAD_F(0x0545d48e) /* 0.329548411 */, 18 },
5383
5384 /* 5040 */ { MAD_F(0x05462ffe) /* 0.329635614 */, 18 },
5385 /* 5041 */ { MAD_F(0x05468b70) /* 0.329722822 */, 18 },
5386 /* 5042 */ { MAD_F(0x0546e6e3) /* 0.329810036 */, 18 },
5387 /* 5043 */ { MAD_F(0x05474258) /* 0.329897255 */, 18 },
5388 /* 5044 */ { MAD_F(0x05479dce) /* 0.329984481 */, 18 },
5389 /* 5045 */ { MAD_F(0x0547f946) /* 0.330071712 */, 18 },
5390 /* 5046 */ { MAD_F(0x054854c0) /* 0.330158949 */, 18 },
5391 /* 5047 */ { MAD_F(0x0548b03b) /* 0.330246191 */, 18 },
5392 /* 5048 */ { MAD_F(0x05490bb7) /* 0.330333440 */, 18 },
5393 /* 5049 */ { MAD_F(0x05496735) /* 0.330420694 */, 18 },
5394 /* 5050 */ { MAD_F(0x0549c2b5) /* 0.330507954 */, 18 },
5395 /* 5051 */ { MAD_F(0x054a1e36) /* 0.330595220 */, 18 },
5396 /* 5052 */ { MAD_F(0x054a79b9) /* 0.330682491 */, 18 },
5397 /* 5053 */ { MAD_F(0x054ad53d) /* 0.330769768 */, 18 },
5398 /* 5054 */ { MAD_F(0x054b30c3) /* 0.330857051 */, 18 },
5399 /* 5055 */ { MAD_F(0x054b8c4b) /* 0.330944340 */, 18 },
5400
5401 /* 5056 */ { MAD_F(0x054be7d4) /* 0.331031635 */, 18 },
5402 /* 5057 */ { MAD_F(0x054c435e) /* 0.331118935 */, 18 },
5403 /* 5058 */ { MAD_F(0x054c9eea) /* 0.331206241 */, 18 },
5404 /* 5059 */ { MAD_F(0x054cfa78) /* 0.331293553 */, 18 },
5405 /* 5060 */ { MAD_F(0x054d5607) /* 0.331380870 */, 18 },
5406 /* 5061 */ { MAD_F(0x054db197) /* 0.331468193 */, 18 },
5407 /* 5062 */ { MAD_F(0x054e0d2a) /* 0.331555522 */, 18 },
5408 /* 5063 */ { MAD_F(0x054e68bd) /* 0.331642857 */, 18 },
5409 /* 5064 */ { MAD_F(0x054ec453) /* 0.331730198 */, 18 },
5410 /* 5065 */ { MAD_F(0x054f1fe9) /* 0.331817544 */, 18 },
5411 /* 5066 */ { MAD_F(0x054f7b82) /* 0.331904896 */, 18 },
5412 /* 5067 */ { MAD_F(0x054fd71c) /* 0.331992254 */, 18 },
5413 /* 5068 */ { MAD_F(0x055032b7) /* 0.332079617 */, 18 },
5414 /* 5069 */ { MAD_F(0x05508e54) /* 0.332166986 */, 18 },
5415 /* 5070 */ { MAD_F(0x0550e9f3) /* 0.332254361 */, 18 },
5416 /* 5071 */ { MAD_F(0x05514593) /* 0.332341742 */, 18 },
5417
5418 /* 5072 */ { MAD_F(0x0551a134) /* 0.332429129 */, 18 },
5419 /* 5073 */ { MAD_F(0x0551fcd8) /* 0.332516521 */, 18 },
5420 /* 5074 */ { MAD_F(0x0552587c) /* 0.332603919 */, 18 },
5421 /* 5075 */ { MAD_F(0x0552b423) /* 0.332691323 */, 18 },
5422 /* 5076 */ { MAD_F(0x05530fca) /* 0.332778732 */, 18 },
5423 /* 5077 */ { MAD_F(0x05536b74) /* 0.332866147 */, 18 },
5424 /* 5078 */ { MAD_F(0x0553c71f) /* 0.332953568 */, 18 },
5425 /* 5079 */ { MAD_F(0x055422cb) /* 0.333040995 */, 18 },
5426 /* 5080 */ { MAD_F(0x05547e79) /* 0.333128427 */, 18 },
5427 /* 5081 */ { MAD_F(0x0554da29) /* 0.333215865 */, 18 },
5428 /* 5082 */ { MAD_F(0x055535da) /* 0.333303309 */, 18 },
5429 /* 5083 */ { MAD_F(0x0555918c) /* 0.333390759 */, 18 },
5430 /* 5084 */ { MAD_F(0x0555ed40) /* 0.333478214 */, 18 },
5431 /* 5085 */ { MAD_F(0x055648f6) /* 0.333565675 */, 18 },
5432 /* 5086 */ { MAD_F(0x0556a4ad) /* 0.333653142 */, 18 },
5433 /* 5087 */ { MAD_F(0x05570066) /* 0.333740615 */, 18 },
5434
5435 /* 5088 */ { MAD_F(0x05575c20) /* 0.333828093 */, 18 },
5436 /* 5089 */ { MAD_F(0x0557b7dc) /* 0.333915577 */, 18 },
5437 /* 5090 */ { MAD_F(0x05581399) /* 0.334003067 */, 18 },
5438 /* 5091 */ { MAD_F(0x05586f58) /* 0.334090562 */, 18 },
5439 /* 5092 */ { MAD_F(0x0558cb19) /* 0.334178063 */, 18 },
5440 /* 5093 */ { MAD_F(0x055926db) /* 0.334265570 */, 18 },
5441 /* 5094 */ { MAD_F(0x0559829e) /* 0.334353083 */, 18 },
5442 /* 5095 */ { MAD_F(0x0559de63) /* 0.334440601 */, 18 },
5443 /* 5096 */ { MAD_F(0x055a3a2a) /* 0.334528126 */, 18 },
5444 /* 5097 */ { MAD_F(0x055a95f2) /* 0.334615655 */, 18 },
5445 /* 5098 */ { MAD_F(0x055af1bb) /* 0.334703191 */, 18 },
5446 /* 5099 */ { MAD_F(0x055b4d87) /* 0.334790732 */, 18 },
5447 /* 5100 */ { MAD_F(0x055ba953) /* 0.334878279 */, 18 },
5448 /* 5101 */ { MAD_F(0x055c0522) /* 0.334965832 */, 18 },
5449 /* 5102 */ { MAD_F(0x055c60f1) /* 0.335053391 */, 18 },
5450 /* 5103 */ { MAD_F(0x055cbcc3) /* 0.335140955 */, 18 },
5451
5452 /* 5104 */ { MAD_F(0x055d1896) /* 0.335228525 */, 18 },
5453 /* 5105 */ { MAD_F(0x055d746a) /* 0.335316100 */, 18 },
5454 /* 5106 */ { MAD_F(0x055dd040) /* 0.335403682 */, 18 },
5455 /* 5107 */ { MAD_F(0x055e2c17) /* 0.335491269 */, 18 },
5456 /* 5108 */ { MAD_F(0x055e87f0) /* 0.335578861 */, 18 },
5457 /* 5109 */ { MAD_F(0x055ee3cb) /* 0.335666460 */, 18 },
5458 /* 5110 */ { MAD_F(0x055f3fa7) /* 0.335754064 */, 18 },
5459 /* 5111 */ { MAD_F(0x055f9b85) /* 0.335841674 */, 18 },
5460 /* 5112 */ { MAD_F(0x055ff764) /* 0.335929290 */, 18 },
5461 /* 5113 */ { MAD_F(0x05605344) /* 0.336016911 */, 18 },
5462 /* 5114 */ { MAD_F(0x0560af27) /* 0.336104538 */, 18 },
5463 /* 5115 */ { MAD_F(0x05610b0a) /* 0.336192171 */, 18 },
5464 /* 5116 */ { MAD_F(0x056166f0) /* 0.336279809 */, 18 },
5465 /* 5117 */ { MAD_F(0x0561c2d7) /* 0.336367453 */, 18 },
5466 /* 5118 */ { MAD_F(0x05621ebf) /* 0.336455103 */, 18 },
5467 /* 5119 */ { MAD_F(0x05627aa9) /* 0.336542759 */, 18 },
5468
5469 /* 5120 */ { MAD_F(0x0562d694) /* 0.336630420 */, 18 },
5470 /* 5121 */ { MAD_F(0x05633281) /* 0.336718087 */, 18 },
5471 /* 5122 */ { MAD_F(0x05638e70) /* 0.336805760 */, 18 },
5472 /* 5123 */ { MAD_F(0x0563ea60) /* 0.336893439 */, 18 },
5473 /* 5124 */ { MAD_F(0x05644651) /* 0.336981123 */, 18 },
5474 /* 5125 */ { MAD_F(0x0564a244) /* 0.337068813 */, 18 },
5475 /* 5126 */ { MAD_F(0x0564fe39) /* 0.337156508 */, 18 },
5476 /* 5127 */ { MAD_F(0x05655a2f) /* 0.337244209 */, 18 },
5477 /* 5128 */ { MAD_F(0x0565b627) /* 0.337331916 */, 18 },
5478 /* 5129 */ { MAD_F(0x05661220) /* 0.337419629 */, 18 },
5479 /* 5130 */ { MAD_F(0x05666e1a) /* 0.337507347 */, 18 },
5480 /* 5131 */ { MAD_F(0x0566ca17) /* 0.337595071 */, 18 },
5481 /* 5132 */ { MAD_F(0x05672614) /* 0.337682801 */, 18 },
5482 /* 5133 */ { MAD_F(0x05678214) /* 0.337770537 */, 18 },
5483 /* 5134 */ { MAD_F(0x0567de15) /* 0.337858278 */, 18 },
5484 /* 5135 */ { MAD_F(0x05683a17) /* 0.337946025 */, 18 },
5485
5486 /* 5136 */ { MAD_F(0x0568961b) /* 0.338033777 */, 18 },
5487 /* 5137 */ { MAD_F(0x0568f220) /* 0.338121535 */, 18 },
5488 /* 5138 */ { MAD_F(0x05694e27) /* 0.338209299 */, 18 },
5489 /* 5139 */ { MAD_F(0x0569aa30) /* 0.338297069 */, 18 },
5490 /* 5140 */ { MAD_F(0x056a063a) /* 0.338384844 */, 18 },
5491 /* 5141 */ { MAD_F(0x056a6245) /* 0.338472625 */, 18 },
5492 /* 5142 */ { MAD_F(0x056abe52) /* 0.338560412 */, 18 },
5493 /* 5143 */ { MAD_F(0x056b1a61) /* 0.338648204 */, 18 },
5494 /* 5144 */ { MAD_F(0x056b7671) /* 0.338736002 */, 18 },
5495 /* 5145 */ { MAD_F(0x056bd283) /* 0.338823806 */, 18 },
5496 /* 5146 */ { MAD_F(0x056c2e96) /* 0.338911616 */, 18 },
5497 /* 5147 */ { MAD_F(0x056c8aab) /* 0.338999431 */, 18 },
5498 /* 5148 */ { MAD_F(0x056ce6c1) /* 0.339087252 */, 18 },
5499 /* 5149 */ { MAD_F(0x056d42d9) /* 0.339175078 */, 18 },
5500 /* 5150 */ { MAD_F(0x056d9ef2) /* 0.339262910 */, 18 },
5501 /* 5151 */ { MAD_F(0x056dfb0d) /* 0.339350748 */, 18 },
5502
5503 /* 5152 */ { MAD_F(0x056e5729) /* 0.339438592 */, 18 },
5504 /* 5153 */ { MAD_F(0x056eb347) /* 0.339526441 */, 18 },
5505 /* 5154 */ { MAD_F(0x056f0f66) /* 0.339614296 */, 18 },
5506 /* 5155 */ { MAD_F(0x056f6b87) /* 0.339702157 */, 18 },
5507 /* 5156 */ { MAD_F(0x056fc7aa) /* 0.339790023 */, 18 },
5508 /* 5157 */ { MAD_F(0x057023cd) /* 0.339877895 */, 18 },
5509 /* 5158 */ { MAD_F(0x05707ff3) /* 0.339965773 */, 18 },
5510 /* 5159 */ { MAD_F(0x0570dc1a) /* 0.340053656 */, 18 },
5511 /* 5160 */ { MAD_F(0x05713843) /* 0.340141545 */, 18 },
5512 /* 5161 */ { MAD_F(0x0571946d) /* 0.340229440 */, 18 },
5513 /* 5162 */ { MAD_F(0x0571f098) /* 0.340317340 */, 18 },
5514 /* 5163 */ { MAD_F(0x05724cc5) /* 0.340405246 */, 18 },
5515 /* 5164 */ { MAD_F(0x0572a8f4) /* 0.340493158 */, 18 },
5516 /* 5165 */ { MAD_F(0x05730524) /* 0.340581075 */, 18 },
5517 /* 5166 */ { MAD_F(0x05736156) /* 0.340668999 */, 18 },
5518 /* 5167 */ { MAD_F(0x0573bd89) /* 0.340756927 */, 18 },
5519
5520 /* 5168 */ { MAD_F(0x057419be) /* 0.340844862 */, 18 },
5521 /* 5169 */ { MAD_F(0x057475f4) /* 0.340932802 */, 18 },
5522 /* 5170 */ { MAD_F(0x0574d22c) /* 0.341020748 */, 18 },
5523 /* 5171 */ { MAD_F(0x05752e65) /* 0.341108699 */, 18 },
5524 /* 5172 */ { MAD_F(0x05758aa0) /* 0.341196656 */, 18 },
5525 /* 5173 */ { MAD_F(0x0575e6dc) /* 0.341284619 */, 18 },
5526 /* 5174 */ { MAD_F(0x0576431a) /* 0.341372587 */, 18 },
5527 /* 5175 */ { MAD_F(0x05769f59) /* 0.341460562 */, 18 },
5528 /* 5176 */ { MAD_F(0x0576fb9a) /* 0.341548541 */, 18 },
5529 /* 5177 */ { MAD_F(0x057757dd) /* 0.341636527 */, 18 },
5530 /* 5178 */ { MAD_F(0x0577b421) /* 0.341724518 */, 18 },
5531 /* 5179 */ { MAD_F(0x05781066) /* 0.341812515 */, 18 },
5532 /* 5180 */ { MAD_F(0x05786cad) /* 0.341900517 */, 18 },
5533 /* 5181 */ { MAD_F(0x0578c8f5) /* 0.341988525 */, 18 },
5534 /* 5182 */ { MAD_F(0x0579253f) /* 0.342076539 */, 18 },
5535 /* 5183 */ { MAD_F(0x0579818b) /* 0.342164558 */, 18 },
5536
5537 /* 5184 */ { MAD_F(0x0579ddd8) /* 0.342252584 */, 18 },
5538 /* 5185 */ { MAD_F(0x057a3a27) /* 0.342340614 */, 18 },
5539 /* 5186 */ { MAD_F(0x057a9677) /* 0.342428651 */, 18 },
5540 /* 5187 */ { MAD_F(0x057af2c8) /* 0.342516693 */, 18 },
5541 /* 5188 */ { MAD_F(0x057b4f1c) /* 0.342604741 */, 18 },
5542 /* 5189 */ { MAD_F(0x057bab70) /* 0.342692794 */, 18 },
5543 /* 5190 */ { MAD_F(0x057c07c6) /* 0.342780853 */, 18 },
5544 /* 5191 */ { MAD_F(0x057c641e) /* 0.342868918 */, 18 },
5545 /* 5192 */ { MAD_F(0x057cc077) /* 0.342956988 */, 18 },
5546 /* 5193 */ { MAD_F(0x057d1cd2) /* 0.343045064 */, 18 },
5547 /* 5194 */ { MAD_F(0x057d792e) /* 0.343133146 */, 18 },
5548 /* 5195 */ { MAD_F(0x057dd58c) /* 0.343221233 */, 18 },
5549 /* 5196 */ { MAD_F(0x057e31eb) /* 0.343309326 */, 18 },
5550 /* 5197 */ { MAD_F(0x057e8e4c) /* 0.343397425 */, 18 },
5551 /* 5198 */ { MAD_F(0x057eeaae) /* 0.343485529 */, 18 },
5552 /* 5199 */ { MAD_F(0x057f4712) /* 0.343573639 */, 18 },
5553
5554 /* 5200 */ { MAD_F(0x057fa378) /* 0.343661754 */, 18 },
5555 /* 5201 */ { MAD_F(0x057fffde) /* 0.343749876 */, 18 },
5556 /* 5202 */ { MAD_F(0x05805c47) /* 0.343838003 */, 18 },
5557 /* 5203 */ { MAD_F(0x0580b8b1) /* 0.343926135 */, 18 },
5558 /* 5204 */ { MAD_F(0x0581151c) /* 0.344014273 */, 18 },
5559 /* 5205 */ { MAD_F(0x05817189) /* 0.344102417 */, 18 },
5560 /* 5206 */ { MAD_F(0x0581cdf7) /* 0.344190566 */, 18 },
5561 /* 5207 */ { MAD_F(0x05822a67) /* 0.344278722 */, 18 },
5562 /* 5208 */ { MAD_F(0x058286d9) /* 0.344366882 */, 18 },
5563 /* 5209 */ { MAD_F(0x0582e34c) /* 0.344455049 */, 18 },
5564 /* 5210 */ { MAD_F(0x05833fc0) /* 0.344543221 */, 18 },
5565 /* 5211 */ { MAD_F(0x05839c36) /* 0.344631398 */, 18 },
5566 /* 5212 */ { MAD_F(0x0583f8ae) /* 0.344719582 */, 18 },
5567 /* 5213 */ { MAD_F(0x05845527) /* 0.344807771 */, 18 },
5568 /* 5214 */ { MAD_F(0x0584b1a1) /* 0.344895965 */, 18 },
5569 /* 5215 */ { MAD_F(0x05850e1e) /* 0.344984165 */, 18 },
5570
5571 /* 5216 */ { MAD_F(0x05856a9b) /* 0.345072371 */, 18 },
5572 /* 5217 */ { MAD_F(0x0585c71a) /* 0.345160583 */, 18 },
5573 /* 5218 */ { MAD_F(0x0586239b) /* 0.345248800 */, 18 },
5574 /* 5219 */ { MAD_F(0x0586801d) /* 0.345337023 */, 18 },
5575 /* 5220 */ { MAD_F(0x0586dca1) /* 0.345425251 */, 18 },
5576 /* 5221 */ { MAD_F(0x05873926) /* 0.345513485 */, 18 },
5577 /* 5222 */ { MAD_F(0x058795ac) /* 0.345601725 */, 18 },
5578 /* 5223 */ { MAD_F(0x0587f235) /* 0.345689970 */, 18 },
5579 /* 5224 */ { MAD_F(0x05884ebe) /* 0.345778221 */, 18 },
5580 /* 5225 */ { MAD_F(0x0588ab49) /* 0.345866478 */, 18 },
5581 /* 5226 */ { MAD_F(0x058907d6) /* 0.345954740 */, 18 },
5582 /* 5227 */ { MAD_F(0x05896464) /* 0.346043008 */, 18 },
5583 /* 5228 */ { MAD_F(0x0589c0f4) /* 0.346131281 */, 18 },
5584 /* 5229 */ { MAD_F(0x058a1d85) /* 0.346219560 */, 18 },
5585 /* 5230 */ { MAD_F(0x058a7a18) /* 0.346307845 */, 18 },
5586 /* 5231 */ { MAD_F(0x058ad6ac) /* 0.346396135 */, 18 },
5587
5588 /* 5232 */ { MAD_F(0x058b3342) /* 0.346484431 */, 18 },
5589 /* 5233 */ { MAD_F(0x058b8fd9) /* 0.346572733 */, 18 },
5590 /* 5234 */ { MAD_F(0x058bec72) /* 0.346661040 */, 18 },
5591 /* 5235 */ { MAD_F(0x058c490c) /* 0.346749353 */, 18 },
5592 /* 5236 */ { MAD_F(0x058ca5a8) /* 0.346837671 */, 18 },
5593 /* 5237 */ { MAD_F(0x058d0246) /* 0.346925996 */, 18 },
5594 /* 5238 */ { MAD_F(0x058d5ee4) /* 0.347014325 */, 18 },
5595 /* 5239 */ { MAD_F(0x058dbb85) /* 0.347102661 */, 18 },
5596 /* 5240 */ { MAD_F(0x058e1827) /* 0.347191002 */, 18 },
5597 /* 5241 */ { MAD_F(0x058e74ca) /* 0.347279348 */, 18 },
5598 /* 5242 */ { MAD_F(0x058ed16f) /* 0.347367700 */, 18 },
5599 /* 5243 */ { MAD_F(0x058f2e15) /* 0.347456058 */, 18 },
5600 /* 5244 */ { MAD_F(0x058f8abd) /* 0.347544422 */, 18 },
5601 /* 5245 */ { MAD_F(0x058fe766) /* 0.347632791 */, 18 },
5602 /* 5246 */ { MAD_F(0x05904411) /* 0.347721165 */, 18 },
5603 /* 5247 */ { MAD_F(0x0590a0be) /* 0.347809546 */, 18 },
5604
5605 /* 5248 */ { MAD_F(0x0590fd6c) /* 0.347897931 */, 18 },
5606 /* 5249 */ { MAD_F(0x05915a1b) /* 0.347986323 */, 18 },
5607 /* 5250 */ { MAD_F(0x0591b6cc) /* 0.348074720 */, 18 },
5608 /* 5251 */ { MAD_F(0x0592137e) /* 0.348163123 */, 18 },
5609 /* 5252 */ { MAD_F(0x05927032) /* 0.348251531 */, 18 },
5610 /* 5253 */ { MAD_F(0x0592cce8) /* 0.348339945 */, 18 },
5611 /* 5254 */ { MAD_F(0x0593299f) /* 0.348428365 */, 18 },
5612 /* 5255 */ { MAD_F(0x05938657) /* 0.348516790 */, 18 },
5613 /* 5256 */ { MAD_F(0x0593e311) /* 0.348605221 */, 18 },
5614 /* 5257 */ { MAD_F(0x05943fcd) /* 0.348693657 */, 18 },
5615 /* 5258 */ { MAD_F(0x05949c8a) /* 0.348782099 */, 18 },
5616 /* 5259 */ { MAD_F(0x0594f948) /* 0.348870547 */, 18 },
5617 /* 5260 */ { MAD_F(0x05955608) /* 0.348959000 */, 18 },
5618 /* 5261 */ { MAD_F(0x0595b2ca) /* 0.349047459 */, 18 },
5619 /* 5262 */ { MAD_F(0x05960f8c) /* 0.349135923 */, 18 },
5620 /* 5263 */ { MAD_F(0x05966c51) /* 0.349224393 */, 18 },
5621
5622 /* 5264 */ { MAD_F(0x0596c917) /* 0.349312869 */, 18 },
5623 /* 5265 */ { MAD_F(0x059725de) /* 0.349401350 */, 18 },
5624 /* 5266 */ { MAD_F(0x059782a7) /* 0.349489837 */, 18 },
5625 /* 5267 */ { MAD_F(0x0597df72) /* 0.349578329 */, 18 },
5626 /* 5268 */ { MAD_F(0x05983c3e) /* 0.349666827 */, 18 },
5627 /* 5269 */ { MAD_F(0x0598990c) /* 0.349755331 */, 18 },
5628 /* 5270 */ { MAD_F(0x0598f5db) /* 0.349843840 */, 18 },
5629 /* 5271 */ { MAD_F(0x059952ab) /* 0.349932355 */, 18 },
5630 /* 5272 */ { MAD_F(0x0599af7d) /* 0.350020876 */, 18 },
5631 /* 5273 */ { MAD_F(0x059a0c51) /* 0.350109402 */, 18 },
5632 /* 5274 */ { MAD_F(0x059a6926) /* 0.350197933 */, 18 },
5633 /* 5275 */ { MAD_F(0x059ac5fc) /* 0.350286470 */, 18 },
5634 /* 5276 */ { MAD_F(0x059b22d4) /* 0.350375013 */, 18 },
5635 /* 5277 */ { MAD_F(0x059b7fae) /* 0.350463562 */, 18 },
5636 /* 5278 */ { MAD_F(0x059bdc89) /* 0.350552116 */, 18 },
5637 /* 5279 */ { MAD_F(0x059c3965) /* 0.350640675 */, 18 },
5638
5639 /* 5280 */ { MAD_F(0x059c9643) /* 0.350729240 */, 18 },
5640 /* 5281 */ { MAD_F(0x059cf323) /* 0.350817811 */, 18 },
5641 /* 5282 */ { MAD_F(0x059d5004) /* 0.350906388 */, 18 },
5642 /* 5283 */ { MAD_F(0x059dace6) /* 0.350994970 */, 18 },
5643 /* 5284 */ { MAD_F(0x059e09cb) /* 0.351083557 */, 18 },
5644 /* 5285 */ { MAD_F(0x059e66b0) /* 0.351172150 */, 18 },
5645 /* 5286 */ { MAD_F(0x059ec397) /* 0.351260749 */, 18 },
5646 /* 5287 */ { MAD_F(0x059f2080) /* 0.351349353 */, 18 },
5647 /* 5288 */ { MAD_F(0x059f7d6a) /* 0.351437963 */, 18 },
5648 /* 5289 */ { MAD_F(0x059fda55) /* 0.351526579 */, 18 },
5649 /* 5290 */ { MAD_F(0x05a03742) /* 0.351615200 */, 18 },
5650 /* 5291 */ { MAD_F(0x05a09431) /* 0.351703827 */, 18 },
5651 /* 5292 */ { MAD_F(0x05a0f121) /* 0.351792459 */, 18 },
5652 /* 5293 */ { MAD_F(0x05a14e12) /* 0.351881097 */, 18 },
5653 /* 5294 */ { MAD_F(0x05a1ab05) /* 0.351969740 */, 18 },
5654 /* 5295 */ { MAD_F(0x05a207fa) /* 0.352058389 */, 18 },
5655
5656 /* 5296 */ { MAD_F(0x05a264f0) /* 0.352147044 */, 18 },
5657 /* 5297 */ { MAD_F(0x05a2c1e7) /* 0.352235704 */, 18 },
5658 /* 5298 */ { MAD_F(0x05a31ee1) /* 0.352324369 */, 18 },
5659 /* 5299 */ { MAD_F(0x05a37bdb) /* 0.352413041 */, 18 },
5660 /* 5300 */ { MAD_F(0x05a3d8d7) /* 0.352501718 */, 18 },
5661 /* 5301 */ { MAD_F(0x05a435d5) /* 0.352590400 */, 18 },
5662 /* 5302 */ { MAD_F(0x05a492d4) /* 0.352679088 */, 18 },
5663 /* 5303 */ { MAD_F(0x05a4efd4) /* 0.352767782 */, 18 },
5664 /* 5304 */ { MAD_F(0x05a54cd6) /* 0.352856481 */, 18 },
5665 /* 5305 */ { MAD_F(0x05a5a9da) /* 0.352945186 */, 18 },
5666 /* 5306 */ { MAD_F(0x05a606df) /* 0.353033896 */, 18 },
5667 /* 5307 */ { MAD_F(0x05a663e5) /* 0.353122612 */, 18 },
5668 /* 5308 */ { MAD_F(0x05a6c0ed) /* 0.353211333 */, 18 },
5669 /* 5309 */ { MAD_F(0x05a71df7) /* 0.353300061 */, 18 },
5670 /* 5310 */ { MAD_F(0x05a77b02) /* 0.353388793 */, 18 },
5671 /* 5311 */ { MAD_F(0x05a7d80e) /* 0.353477531 */, 18 },
5672
5673 /* 5312 */ { MAD_F(0x05a8351c) /* 0.353566275 */, 18 },
5674 /* 5313 */ { MAD_F(0x05a8922c) /* 0.353655024 */, 18 },
5675 /* 5314 */ { MAD_F(0x05a8ef3c) /* 0.353743779 */, 18 },
5676 /* 5315 */ { MAD_F(0x05a94c4f) /* 0.353832540 */, 18 },
5677 /* 5316 */ { MAD_F(0x05a9a963) /* 0.353921306 */, 18 },
5678 /* 5317 */ { MAD_F(0x05aa0678) /* 0.354010077 */, 18 },
5679 /* 5318 */ { MAD_F(0x05aa638f) /* 0.354098855 */, 18 },
5680 /* 5319 */ { MAD_F(0x05aac0a8) /* 0.354187637 */, 18 },
5681 /* 5320 */ { MAD_F(0x05ab1dc2) /* 0.354276426 */, 18 },
5682 /* 5321 */ { MAD_F(0x05ab7add) /* 0.354365220 */, 18 },
5683 /* 5322 */ { MAD_F(0x05abd7fa) /* 0.354454019 */, 18 },
5684 /* 5323 */ { MAD_F(0x05ac3518) /* 0.354542824 */, 18 },
5685 /* 5324 */ { MAD_F(0x05ac9238) /* 0.354631635 */, 18 },
5686 /* 5325 */ { MAD_F(0x05acef5a) /* 0.354720451 */, 18 },
5687 /* 5326 */ { MAD_F(0x05ad4c7d) /* 0.354809272 */, 18 },
5688 /* 5327 */ { MAD_F(0x05ada9a1) /* 0.354898100 */, 18 },
5689
5690 /* 5328 */ { MAD_F(0x05ae06c7) /* 0.354986932 */, 18 },
5691 /* 5329 */ { MAD_F(0x05ae63ee) /* 0.355075771 */, 18 },
5692 /* 5330 */ { MAD_F(0x05aec117) /* 0.355164615 */, 18 },
5693 /* 5331 */ { MAD_F(0x05af1e41) /* 0.355253464 */, 18 },
5694 /* 5332 */ { MAD_F(0x05af7b6d) /* 0.355342319 */, 18 },
5695 /* 5333 */ { MAD_F(0x05afd89b) /* 0.355431180 */, 18 },
5696 /* 5334 */ { MAD_F(0x05b035c9) /* 0.355520046 */, 18 },
5697 /* 5335 */ { MAD_F(0x05b092fa) /* 0.355608917 */, 18 },
5698 /* 5336 */ { MAD_F(0x05b0f02b) /* 0.355697795 */, 18 },
5699 /* 5337 */ { MAD_F(0x05b14d5f) /* 0.355786677 */, 18 },
5700 /* 5338 */ { MAD_F(0x05b1aa94) /* 0.355875566 */, 18 },
5701 /* 5339 */ { MAD_F(0x05b207ca) /* 0.355964460 */, 18 },
5702 /* 5340 */ { MAD_F(0x05b26502) /* 0.356053359 */, 18 },
5703 /* 5341 */ { MAD_F(0x05b2c23b) /* 0.356142264 */, 18 },
5704 /* 5342 */ { MAD_F(0x05b31f76) /* 0.356231175 */, 18 },
5705 /* 5343 */ { MAD_F(0x05b37cb2) /* 0.356320091 */, 18 },
5706
5707 /* 5344 */ { MAD_F(0x05b3d9f0) /* 0.356409012 */, 18 },
5708 /* 5345 */ { MAD_F(0x05b4372f) /* 0.356497940 */, 18 },
5709 /* 5346 */ { MAD_F(0x05b4946f) /* 0.356586872 */, 18 },
5710 /* 5347 */ { MAD_F(0x05b4f1b2) /* 0.356675811 */, 18 },
5711 /* 5348 */ { MAD_F(0x05b54ef5) /* 0.356764754 */, 18 },
5712 /* 5349 */ { MAD_F(0x05b5ac3a) /* 0.356853704 */, 18 },
5713 /* 5350 */ { MAD_F(0x05b60981) /* 0.356942659 */, 18 },
5714 /* 5351 */ { MAD_F(0x05b666c9) /* 0.357031619 */, 18 },
5715 /* 5352 */ { MAD_F(0x05b6c413) /* 0.357120585 */, 18 },
5716 /* 5353 */ { MAD_F(0x05b7215e) /* 0.357209557 */, 18 },
5717 /* 5354 */ { MAD_F(0x05b77eab) /* 0.357298534 */, 18 },
5718 /* 5355 */ { MAD_F(0x05b7dbf9) /* 0.357387516 */, 18 },
5719 /* 5356 */ { MAD_F(0x05b83948) /* 0.357476504 */, 18 },
5720 /* 5357 */ { MAD_F(0x05b89699) /* 0.357565498 */, 18 },
5721 /* 5358 */ { MAD_F(0x05b8f3ec) /* 0.357654497 */, 18 },
5722 /* 5359 */ { MAD_F(0x05b95140) /* 0.357743502 */, 18 },
5723
5724 /* 5360 */ { MAD_F(0x05b9ae95) /* 0.357832512 */, 18 },
5725 /* 5361 */ { MAD_F(0x05ba0bec) /* 0.357921528 */, 18 },
5726 /* 5362 */ { MAD_F(0x05ba6945) /* 0.358010550 */, 18 },
5727 /* 5363 */ { MAD_F(0x05bac69f) /* 0.358099576 */, 18 },
5728 /* 5364 */ { MAD_F(0x05bb23fa) /* 0.358188609 */, 18 },
5729 /* 5365 */ { MAD_F(0x05bb8157) /* 0.358277647 */, 18 },
5730 /* 5366 */ { MAD_F(0x05bbdeb6) /* 0.358366690 */, 18 },
5731 /* 5367 */ { MAD_F(0x05bc3c16) /* 0.358455739 */, 18 },
5732 /* 5368 */ { MAD_F(0x05bc9977) /* 0.358544794 */, 18 },
5733 /* 5369 */ { MAD_F(0x05bcf6da) /* 0.358633854 */, 18 },
5734 /* 5370 */ { MAD_F(0x05bd543e) /* 0.358722920 */, 18 },
5735 /* 5371 */ { MAD_F(0x05bdb1a4) /* 0.358811991 */, 18 },
5736 /* 5372 */ { MAD_F(0x05be0f0b) /* 0.358901067 */, 18 },
5737 /* 5373 */ { MAD_F(0x05be6c74) /* 0.358990150 */, 18 },
5738 /* 5374 */ { MAD_F(0x05bec9df) /* 0.359079237 */, 18 },
5739 /* 5375 */ { MAD_F(0x05bf274a) /* 0.359168331 */, 18 },
5740
5741 /* 5376 */ { MAD_F(0x05bf84b8) /* 0.359257429 */, 18 },
5742 /* 5377 */ { MAD_F(0x05bfe226) /* 0.359346534 */, 18 },
5743 /* 5378 */ { MAD_F(0x05c03f97) /* 0.359435644 */, 18 },
5744 /* 5379 */ { MAD_F(0x05c09d08) /* 0.359524759 */, 18 },
5745 /* 5380 */ { MAD_F(0x05c0fa7c) /* 0.359613880 */, 18 },
5746 /* 5381 */ { MAD_F(0x05c157f0) /* 0.359703006 */, 18 },
5747 /* 5382 */ { MAD_F(0x05c1b566) /* 0.359792138 */, 18 },
5748 /* 5383 */ { MAD_F(0x05c212de) /* 0.359881276 */, 18 },
5749 /* 5384 */ { MAD_F(0x05c27057) /* 0.359970419 */, 18 },
5750 /* 5385 */ { MAD_F(0x05c2cdd2) /* 0.360059567 */, 18 },
5751 /* 5386 */ { MAD_F(0x05c32b4e) /* 0.360148721 */, 18 },
5752 /* 5387 */ { MAD_F(0x05c388cb) /* 0.360237881 */, 18 },
5753 /* 5388 */ { MAD_F(0x05c3e64b) /* 0.360327046 */, 18 },
5754 /* 5389 */ { MAD_F(0x05c443cb) /* 0.360416216 */, 18 },
5755 /* 5390 */ { MAD_F(0x05c4a14d) /* 0.360505392 */, 18 },
5756 /* 5391 */ { MAD_F(0x05c4fed1) /* 0.360594574 */, 18 },
5757
5758 /* 5392 */ { MAD_F(0x05c55c56) /* 0.360683761 */, 18 },
5759 /* 5393 */ { MAD_F(0x05c5b9dc) /* 0.360772953 */, 18 },
5760 /* 5394 */ { MAD_F(0x05c61764) /* 0.360862152 */, 18 },
5761 /* 5395 */ { MAD_F(0x05c674ed) /* 0.360951355 */, 18 },
5762 /* 5396 */ { MAD_F(0x05c6d278) /* 0.361040564 */, 18 },
5763 /* 5397 */ { MAD_F(0x05c73005) /* 0.361129779 */, 18 },
5764 /* 5398 */ { MAD_F(0x05c78d93) /* 0.361218999 */, 18 },
5765 /* 5399 */ { MAD_F(0x05c7eb22) /* 0.361308225 */, 18 },
5766 /* 5400 */ { MAD_F(0x05c848b3) /* 0.361397456 */, 18 },
5767 /* 5401 */ { MAD_F(0x05c8a645) /* 0.361486693 */, 18 },
5768 /* 5402 */ { MAD_F(0x05c903d9) /* 0.361575935 */, 18 },
5769 /* 5403 */ { MAD_F(0x05c9616e) /* 0.361665183 */, 18 },
5770 /* 5404 */ { MAD_F(0x05c9bf05) /* 0.361754436 */, 18 },
5771 /* 5405 */ { MAD_F(0x05ca1c9d) /* 0.361843695 */, 18 },
5772 /* 5406 */ { MAD_F(0x05ca7a37) /* 0.361932959 */, 18 },
5773 /* 5407 */ { MAD_F(0x05cad7d2) /* 0.362022229 */, 18 },
5774
5775 /* 5408 */ { MAD_F(0x05cb356e) /* 0.362111504 */, 18 },
5776 /* 5409 */ { MAD_F(0x05cb930d) /* 0.362200785 */, 18 },
5777 /* 5410 */ { MAD_F(0x05cbf0ac) /* 0.362290071 */, 18 },
5778 /* 5411 */ { MAD_F(0x05cc4e4d) /* 0.362379362 */, 18 },
5779 /* 5412 */ { MAD_F(0x05ccabf0) /* 0.362468660 */, 18 },
5780 /* 5413 */ { MAD_F(0x05cd0994) /* 0.362557962 */, 18 },
5781 /* 5414 */ { MAD_F(0x05cd6739) /* 0.362647271 */, 18 },
5782 /* 5415 */ { MAD_F(0x05cdc4e0) /* 0.362736584 */, 18 },
5783 /* 5416 */ { MAD_F(0x05ce2289) /* 0.362825904 */, 18 },
5784 /* 5417 */ { MAD_F(0x05ce8033) /* 0.362915228 */, 18 },
5785 /* 5418 */ { MAD_F(0x05ceddde) /* 0.363004559 */, 18 },
5786 /* 5419 */ { MAD_F(0x05cf3b8b) /* 0.363093894 */, 18 },
5787 /* 5420 */ { MAD_F(0x05cf9939) /* 0.363183236 */, 18 },
5788 /* 5421 */ { MAD_F(0x05cff6e9) /* 0.363272582 */, 18 },
5789 /* 5422 */ { MAD_F(0x05d0549a) /* 0.363361935 */, 18 },
5790 /* 5423 */ { MAD_F(0x05d0b24d) /* 0.363451292 */, 18 },
5791
5792 /* 5424 */ { MAD_F(0x05d11001) /* 0.363540655 */, 18 },
5793 /* 5425 */ { MAD_F(0x05d16db7) /* 0.363630024 */, 18 },
5794 /* 5426 */ { MAD_F(0x05d1cb6e) /* 0.363719398 */, 18 },
5795 /* 5427 */ { MAD_F(0x05d22927) /* 0.363808778 */, 18 },
5796 /* 5428 */ { MAD_F(0x05d286e1) /* 0.363898163 */, 18 },
5797 /* 5429 */ { MAD_F(0x05d2e49d) /* 0.363987554 */, 18 },
5798 /* 5430 */ { MAD_F(0x05d3425a) /* 0.364076950 */, 18 },
5799 /* 5431 */ { MAD_F(0x05d3a018) /* 0.364166352 */, 18 },
5800 /* 5432 */ { MAD_F(0x05d3fdd8) /* 0.364255759 */, 18 },
5801 /* 5433 */ { MAD_F(0x05d45b9a) /* 0.364345171 */, 18 },
5802 /* 5434 */ { MAD_F(0x05d4b95d) /* 0.364434589 */, 18 },
5803 /* 5435 */ { MAD_F(0x05d51721) /* 0.364524013 */, 18 },
5804 /* 5436 */ { MAD_F(0x05d574e7) /* 0.364613442 */, 18 },
5805 /* 5437 */ { MAD_F(0x05d5d2af) /* 0.364702877 */, 18 },
5806 /* 5438 */ { MAD_F(0x05d63078) /* 0.364792317 */, 18 },
5807 /* 5439 */ { MAD_F(0x05d68e42) /* 0.364881762 */, 18 },
5808
5809 /* 5440 */ { MAD_F(0x05d6ec0e) /* 0.364971213 */, 18 },
5810 /* 5441 */ { MAD_F(0x05d749db) /* 0.365060669 */, 18 },
5811 /* 5442 */ { MAD_F(0x05d7a7aa) /* 0.365150131 */, 18 },
5812 /* 5443 */ { MAD_F(0x05d8057a) /* 0.365239599 */, 18 },
5813 /* 5444 */ { MAD_F(0x05d8634c) /* 0.365329072 */, 18 },
5814 /* 5445 */ { MAD_F(0x05d8c11f) /* 0.365418550 */, 18 },
5815 /* 5446 */ { MAD_F(0x05d91ef4) /* 0.365508034 */, 18 },
5816 /* 5447 */ { MAD_F(0x05d97cca) /* 0.365597523 */, 18 },
5817 /* 5448 */ { MAD_F(0x05d9daa1) /* 0.365687018 */, 18 },
5818 /* 5449 */ { MAD_F(0x05da387a) /* 0.365776518 */, 18 },
5819 /* 5450 */ { MAD_F(0x05da9655) /* 0.365866024 */, 18 },
5820 /* 5451 */ { MAD_F(0x05daf431) /* 0.365955536 */, 18 },
5821 /* 5452 */ { MAD_F(0x05db520e) /* 0.366045052 */, 18 },
5822 /* 5453 */ { MAD_F(0x05dbafed) /* 0.366134574 */, 18 },
5823 /* 5454 */ { MAD_F(0x05dc0dce) /* 0.366224102 */, 18 },
5824 /* 5455 */ { MAD_F(0x05dc6baf) /* 0.366313635 */, 18 },
5825
5826 /* 5456 */ { MAD_F(0x05dcc993) /* 0.366403174 */, 18 },
5827 /* 5457 */ { MAD_F(0x05dd2778) /* 0.366492718 */, 18 },
5828 /* 5458 */ { MAD_F(0x05dd855e) /* 0.366582267 */, 18 },
5829 /* 5459 */ { MAD_F(0x05dde346) /* 0.366671822 */, 18 },
5830 /* 5460 */ { MAD_F(0x05de412f) /* 0.366761383 */, 18 },
5831 /* 5461 */ { MAD_F(0x05de9f1a) /* 0.366850949 */, 18 },
5832 /* 5462 */ { MAD_F(0x05defd06) /* 0.366940520 */, 18 },
5833 /* 5463 */ { MAD_F(0x05df5af3) /* 0.367030097 */, 18 },
5834 /* 5464 */ { MAD_F(0x05dfb8e2) /* 0.367119680 */, 18 },
5835 /* 5465 */ { MAD_F(0x05e016d3) /* 0.367209267 */, 18 },
5836 /* 5466 */ { MAD_F(0x05e074c5) /* 0.367298861 */, 18 },
5837 /* 5467 */ { MAD_F(0x05e0d2b8) /* 0.367388459 */, 18 },
5838 /* 5468 */ { MAD_F(0x05e130ad) /* 0.367478064 */, 18 },
5839 /* 5469 */ { MAD_F(0x05e18ea4) /* 0.367567673 */, 18 },
5840 /* 5470 */ { MAD_F(0x05e1ec9c) /* 0.367657288 */, 18 },
5841 /* 5471 */ { MAD_F(0x05e24a95) /* 0.367746909 */, 18 },
5842
5843 /* 5472 */ { MAD_F(0x05e2a890) /* 0.367836535 */, 18 },
5844 /* 5473 */ { MAD_F(0x05e3068c) /* 0.367926167 */, 18 },
5845 /* 5474 */ { MAD_F(0x05e3648a) /* 0.368015804 */, 18 },
5846 /* 5475 */ { MAD_F(0x05e3c289) /* 0.368105446 */, 18 },
5847 /* 5476 */ { MAD_F(0x05e4208a) /* 0.368195094 */, 18 },
5848 /* 5477 */ { MAD_F(0x05e47e8c) /* 0.368284747 */, 18 },
5849 /* 5478 */ { MAD_F(0x05e4dc8f) /* 0.368374406 */, 18 },
5850 /* 5479 */ { MAD_F(0x05e53a94) /* 0.368464070 */, 18 },
5851 /* 5480 */ { MAD_F(0x05e5989b) /* 0.368553740 */, 18 },
5852 /* 5481 */ { MAD_F(0x05e5f6a3) /* 0.368643415 */, 18 },
5853 /* 5482 */ { MAD_F(0x05e654ac) /* 0.368733096 */, 18 },
5854 /* 5483 */ { MAD_F(0x05e6b2b7) /* 0.368822782 */, 18 },
5855 /* 5484 */ { MAD_F(0x05e710c4) /* 0.368912473 */, 18 },
5856 /* 5485 */ { MAD_F(0x05e76ed2) /* 0.369002170 */, 18 },
5857 /* 5486 */ { MAD_F(0x05e7cce1) /* 0.369091873 */, 18 },
5858 /* 5487 */ { MAD_F(0x05e82af2) /* 0.369181581 */, 18 },
5859
5860 /* 5488 */ { MAD_F(0x05e88904) /* 0.369271294 */, 18 },
5861 /* 5489 */ { MAD_F(0x05e8e718) /* 0.369361013 */, 18 },
5862 /* 5490 */ { MAD_F(0x05e9452d) /* 0.369450737 */, 18 },
5863 /* 5491 */ { MAD_F(0x05e9a343) /* 0.369540467 */, 18 },
5864 /* 5492 */ { MAD_F(0x05ea015c) /* 0.369630202 */, 18 },
5865 /* 5493 */ { MAD_F(0x05ea5f75) /* 0.369719942 */, 18 },
5866 /* 5494 */ { MAD_F(0x05eabd90) /* 0.369809688 */, 18 },
5867 /* 5495 */ { MAD_F(0x05eb1bad) /* 0.369899440 */, 18 },
5868 /* 5496 */ { MAD_F(0x05eb79cb) /* 0.369989197 */, 18 },
5869 /* 5497 */ { MAD_F(0x05ebd7ea) /* 0.370078959 */, 18 },
5870 /* 5498 */ { MAD_F(0x05ec360b) /* 0.370168727 */, 18 },
5871 /* 5499 */ { MAD_F(0x05ec942d) /* 0.370258500 */, 18 },
5872 /* 5500 */ { MAD_F(0x05ecf251) /* 0.370348279 */, 18 },
5873 /* 5501 */ { MAD_F(0x05ed5076) /* 0.370438063 */, 18 },
5874 /* 5502 */ { MAD_F(0x05edae9d) /* 0.370527853 */, 18 },
5875 /* 5503 */ { MAD_F(0x05ee0cc5) /* 0.370617648 */, 18 },
5876
5877 /* 5504 */ { MAD_F(0x05ee6aef) /* 0.370707448 */, 18 },
5878 /* 5505 */ { MAD_F(0x05eec91a) /* 0.370797254 */, 18 },
5879 /* 5506 */ { MAD_F(0x05ef2746) /* 0.370887065 */, 18 },
5880 /* 5507 */ { MAD_F(0x05ef8574) /* 0.370976882 */, 18 },
5881 /* 5508 */ { MAD_F(0x05efe3a4) /* 0.371066704 */, 18 },
5882 /* 5509 */ { MAD_F(0x05f041d5) /* 0.371156532 */, 18 },
5883 /* 5510 */ { MAD_F(0x05f0a007) /* 0.371246365 */, 18 },
5884 /* 5511 */ { MAD_F(0x05f0fe3b) /* 0.371336203 */, 18 },
5885 /* 5512 */ { MAD_F(0x05f15c70) /* 0.371426047 */, 18 },
5886 /* 5513 */ { MAD_F(0x05f1baa7) /* 0.371515897 */, 18 },
5887 /* 5514 */ { MAD_F(0x05f218df) /* 0.371605751 */, 18 },
5888 /* 5515 */ { MAD_F(0x05f27719) /* 0.371695612 */, 18 },
5889 /* 5516 */ { MAD_F(0x05f2d554) /* 0.371785477 */, 18 },
5890 /* 5517 */ { MAD_F(0x05f33390) /* 0.371875348 */, 18 },
5891 /* 5518 */ { MAD_F(0x05f391cf) /* 0.371965225 */, 18 },
5892 /* 5519 */ { MAD_F(0x05f3f00e) /* 0.372055107 */, 18 },
5893
5894 /* 5520 */ { MAD_F(0x05f44e4f) /* 0.372144994 */, 18 },
5895 /* 5521 */ { MAD_F(0x05f4ac91) /* 0.372234887 */, 18 },
5896 /* 5522 */ { MAD_F(0x05f50ad5) /* 0.372324785 */, 18 },
5897 /* 5523 */ { MAD_F(0x05f5691b) /* 0.372414689 */, 18 },
5898 /* 5524 */ { MAD_F(0x05f5c761) /* 0.372504598 */, 18 },
5899 /* 5525 */ { MAD_F(0x05f625aa) /* 0.372594513 */, 18 },
5900 /* 5526 */ { MAD_F(0x05f683f3) /* 0.372684433 */, 18 },
5901 /* 5527 */ { MAD_F(0x05f6e23f) /* 0.372774358 */, 18 },
5902 /* 5528 */ { MAD_F(0x05f7408b) /* 0.372864289 */, 18 },
5903 /* 5529 */ { MAD_F(0x05f79ed9) /* 0.372954225 */, 18 },
5904 /* 5530 */ { MAD_F(0x05f7fd29) /* 0.373044167 */, 18 },
5905 /* 5531 */ { MAD_F(0x05f85b7a) /* 0.373134114 */, 18 },
5906 /* 5532 */ { MAD_F(0x05f8b9cc) /* 0.373224066 */, 18 },
5907 /* 5533 */ { MAD_F(0x05f91820) /* 0.373314024 */, 18 },
5908 /* 5534 */ { MAD_F(0x05f97675) /* 0.373403987 */, 18 },
5909 /* 5535 */ { MAD_F(0x05f9d4cc) /* 0.373493956 */, 18 },
5910
5911 /* 5536 */ { MAD_F(0x05fa3324) /* 0.373583930 */, 18 },
5912 /* 5537 */ { MAD_F(0x05fa917e) /* 0.373673910 */, 18 },
5913 /* 5538 */ { MAD_F(0x05faefd9) /* 0.373763895 */, 18 },
5914 /* 5539 */ { MAD_F(0x05fb4e36) /* 0.373853885 */, 18 },
5915 /* 5540 */ { MAD_F(0x05fbac94) /* 0.373943881 */, 18 },
5916 /* 5541 */ { MAD_F(0x05fc0af3) /* 0.374033882 */, 18 },
5917 /* 5542 */ { MAD_F(0x05fc6954) /* 0.374123889 */, 18 },
5918 /* 5543 */ { MAD_F(0x05fcc7b7) /* 0.374213901 */, 18 },
5919 /* 5544 */ { MAD_F(0x05fd261b) /* 0.374303918 */, 18 },
5920 /* 5545 */ { MAD_F(0x05fd8480) /* 0.374393941 */, 18 },
5921 /* 5546 */ { MAD_F(0x05fde2e7) /* 0.374483970 */, 18 },
5922 /* 5547 */ { MAD_F(0x05fe414f) /* 0.374574003 */, 18 },
5923 /* 5548 */ { MAD_F(0x05fe9fb9) /* 0.374664042 */, 18 },
5924 /* 5549 */ { MAD_F(0x05fefe24) /* 0.374754087 */, 18 },
5925 /* 5550 */ { MAD_F(0x05ff5c91) /* 0.374844137 */, 18 },
5926 /* 5551 */ { MAD_F(0x05ffbaff) /* 0.374934192 */, 18 },
5927
5928 /* 5552 */ { MAD_F(0x0600196e) /* 0.375024253 */, 18 },
5929 /* 5553 */ { MAD_F(0x060077df) /* 0.375114319 */, 18 },
5930 /* 5554 */ { MAD_F(0x0600d651) /* 0.375204391 */, 18 },
5931 /* 5555 */ { MAD_F(0x060134c5) /* 0.375294468 */, 18 },
5932 /* 5556 */ { MAD_F(0x0601933b) /* 0.375384550 */, 18 },
5933 /* 5557 */ { MAD_F(0x0601f1b1) /* 0.375474638 */, 18 },
5934 /* 5558 */ { MAD_F(0x0602502a) /* 0.375564731 */, 18 },
5935 /* 5559 */ { MAD_F(0x0602aea3) /* 0.375654830 */, 18 },
5936 /* 5560 */ { MAD_F(0x06030d1e) /* 0.375744934 */, 18 },
5937 /* 5561 */ { MAD_F(0x06036b9b) /* 0.375835043 */, 18 },
5938 /* 5562 */ { MAD_F(0x0603ca19) /* 0.375925158 */, 18 },
5939 /* 5563 */ { MAD_F(0x06042898) /* 0.376015278 */, 18 },
5940 /* 5564 */ { MAD_F(0x06048719) /* 0.376105404 */, 18 },
5941 /* 5565 */ { MAD_F(0x0604e59c) /* 0.376195535 */, 18 },
5942 /* 5566 */ { MAD_F(0x0605441f) /* 0.376285671 */, 18 },
5943 /* 5567 */ { MAD_F(0x0605a2a5) /* 0.376375813 */, 18 },
5944
5945 /* 5568 */ { MAD_F(0x0606012b) /* 0.376465960 */, 18 },
5946 /* 5569 */ { MAD_F(0x06065fb4) /* 0.376556113 */, 18 },
5947 /* 5570 */ { MAD_F(0x0606be3d) /* 0.376646271 */, 18 },
5948 /* 5571 */ { MAD_F(0x06071cc8) /* 0.376736434 */, 18 },
5949 /* 5572 */ { MAD_F(0x06077b55) /* 0.376826603 */, 18 },
5950 /* 5573 */ { MAD_F(0x0607d9e3) /* 0.376916777 */, 18 },
5951 /* 5574 */ { MAD_F(0x06083872) /* 0.377006957 */, 18 },
5952 /* 5575 */ { MAD_F(0x06089703) /* 0.377097141 */, 18 },
5953 /* 5576 */ { MAD_F(0x0608f595) /* 0.377187332 */, 18 },
5954 /* 5577 */ { MAD_F(0x06095429) /* 0.377277528 */, 18 },
5955 /* 5578 */ { MAD_F(0x0609b2be) /* 0.377367729 */, 18 },
5956 /* 5579 */ { MAD_F(0x060a1155) /* 0.377457935 */, 18 },
5957 /* 5580 */ { MAD_F(0x060a6fed) /* 0.377548147 */, 18 },
5958 /* 5581 */ { MAD_F(0x060ace86) /* 0.377638364 */, 18 },
5959 /* 5582 */ { MAD_F(0x060b2d21) /* 0.377728587 */, 18 },
5960 /* 5583 */ { MAD_F(0x060b8bbe) /* 0.377818815 */, 18 },
5961
5962 /* 5584 */ { MAD_F(0x060bea5c) /* 0.377909049 */, 18 },
5963 /* 5585 */ { MAD_F(0x060c48fb) /* 0.377999288 */, 18 },
5964 /* 5586 */ { MAD_F(0x060ca79c) /* 0.378089532 */, 18 },
5965 /* 5587 */ { MAD_F(0x060d063e) /* 0.378179781 */, 18 },
5966 /* 5588 */ { MAD_F(0x060d64e1) /* 0.378270036 */, 18 },
5967 /* 5589 */ { MAD_F(0x060dc387) /* 0.378360297 */, 18 },
5968 /* 5590 */ { MAD_F(0x060e222d) /* 0.378450563 */, 18 },
5969 /* 5591 */ { MAD_F(0x060e80d5) /* 0.378540834 */, 18 },
5970 /* 5592 */ { MAD_F(0x060edf7f) /* 0.378631110 */, 18 },
5971 /* 5593 */ { MAD_F(0x060f3e29) /* 0.378721392 */, 18 },
5972 /* 5594 */ { MAD_F(0x060f9cd6) /* 0.378811680 */, 18 },
5973 /* 5595 */ { MAD_F(0x060ffb83) /* 0.378901972 */, 18 },
5974 /* 5596 */ { MAD_F(0x06105a33) /* 0.378992270 */, 18 },
5975 /* 5597 */ { MAD_F(0x0610b8e3) /* 0.379082574 */, 18 },
5976 /* 5598 */ { MAD_F(0x06111795) /* 0.379172883 */, 18 },
5977 /* 5599 */ { MAD_F(0x06117649) /* 0.379263197 */, 18 },
5978
5979 /* 5600 */ { MAD_F(0x0611d4fe) /* 0.379353516 */, 18 },
5980 /* 5601 */ { MAD_F(0x061233b4) /* 0.379443841 */, 18 },
5981 /* 5602 */ { MAD_F(0x0612926c) /* 0.379534172 */, 18 },
5982 /* 5603 */ { MAD_F(0x0612f125) /* 0.379624507 */, 18 },
5983 /* 5604 */ { MAD_F(0x06134fe0) /* 0.379714848 */, 18 },
5984 /* 5605 */ { MAD_F(0x0613ae9c) /* 0.379805195 */, 18 },
5985 /* 5606 */ { MAD_F(0x06140d5a) /* 0.379895547 */, 18 },
5986 /* 5607 */ { MAD_F(0x06146c19) /* 0.379985904 */, 18 },
5987 /* 5608 */ { MAD_F(0x0614cada) /* 0.380076266 */, 18 },
5988 /* 5609 */ { MAD_F(0x0615299c) /* 0.380166634 */, 18 },
5989 /* 5610 */ { MAD_F(0x0615885f) /* 0.380257008 */, 18 },
5990 /* 5611 */ { MAD_F(0x0615e724) /* 0.380347386 */, 18 },
5991 /* 5612 */ { MAD_F(0x061645ea) /* 0.380437770 */, 18 },
5992 /* 5613 */ { MAD_F(0x0616a4b2) /* 0.380528160 */, 18 },
5993 /* 5614 */ { MAD_F(0x0617037b) /* 0.380618555 */, 18 },
5994 /* 5615 */ { MAD_F(0x06176246) /* 0.380708955 */, 18 },
5995
5996 /* 5616 */ { MAD_F(0x0617c112) /* 0.380799360 */, 18 },
5997 /* 5617 */ { MAD_F(0x06181fdf) /* 0.380889771 */, 18 },
5998 /* 5618 */ { MAD_F(0x06187eae) /* 0.380980187 */, 18 },
5999 /* 5619 */ { MAD_F(0x0618dd7e) /* 0.381070609 */, 18 },
6000 /* 5620 */ { MAD_F(0x06193c50) /* 0.381161036 */, 18 },
6001 /* 5621 */ { MAD_F(0x06199b24) /* 0.381251468 */, 18 },
6002 /* 5622 */ { MAD_F(0x0619f9f8) /* 0.381341906 */, 18 },
6003 /* 5623 */ { MAD_F(0x061a58ce) /* 0.381432349 */, 18 },
6004 /* 5624 */ { MAD_F(0x061ab7a6) /* 0.381522798 */, 18 },
6005 /* 5625 */ { MAD_F(0x061b167f) /* 0.381613251 */, 18 },
6006 /* 5626 */ { MAD_F(0x061b7559) /* 0.381703711 */, 18 },
6007 /* 5627 */ { MAD_F(0x061bd435) /* 0.381794175 */, 18 },
6008 /* 5628 */ { MAD_F(0x061c3313) /* 0.381884645 */, 18 },
6009 /* 5629 */ { MAD_F(0x061c91f1) /* 0.381975120 */, 18 },
6010 /* 5630 */ { MAD_F(0x061cf0d2) /* 0.382065601 */, 18 },
6011 /* 5631 */ { MAD_F(0x061d4fb3) /* 0.382156087 */, 18 },
6012
6013 /* 5632 */ { MAD_F(0x061dae96) /* 0.382246578 */, 18 },
6014 /* 5633 */ { MAD_F(0x061e0d7b) /* 0.382337075 */, 18 },
6015 /* 5634 */ { MAD_F(0x061e6c61) /* 0.382427577 */, 18 },
6016 /* 5635 */ { MAD_F(0x061ecb48) /* 0.382518084 */, 18 },
6017 /* 5636 */ { MAD_F(0x061f2a31) /* 0.382608597 */, 18 },
6018 /* 5637 */ { MAD_F(0x061f891b) /* 0.382699115 */, 18 },
6019 /* 5638 */ { MAD_F(0x061fe807) /* 0.382789638 */, 18 },
6020 /* 5639 */ { MAD_F(0x062046f4) /* 0.382880167 */, 18 },
6021 /* 5640 */ { MAD_F(0x0620a5e3) /* 0.382970701 */, 18 },
6022 /* 5641 */ { MAD_F(0x062104d3) /* 0.383061241 */, 18 },
6023 /* 5642 */ { MAD_F(0x062163c4) /* 0.383151786 */, 18 },
6024 /* 5643 */ { MAD_F(0x0621c2b7) /* 0.383242336 */, 18 },
6025 /* 5644 */ { MAD_F(0x062221ab) /* 0.383332891 */, 18 },
6026 /* 5645 */ { MAD_F(0x062280a1) /* 0.383423452 */, 18 },
6027 /* 5646 */ { MAD_F(0x0622df98) /* 0.383514018 */, 18 },
6028 /* 5647 */ { MAD_F(0x06233e91) /* 0.383604590 */, 18 },
6029
6030 /* 5648 */ { MAD_F(0x06239d8b) /* 0.383695167 */, 18 },
6031 /* 5649 */ { MAD_F(0x0623fc86) /* 0.383785749 */, 18 },
6032 /* 5650 */ { MAD_F(0x06245b83) /* 0.383876337 */, 18 },
6033 /* 5651 */ { MAD_F(0x0624ba82) /* 0.383966930 */, 18 },
6034 /* 5652 */ { MAD_F(0x06251981) /* 0.384057528 */, 18 },
6035 /* 5653 */ { MAD_F(0x06257883) /* 0.384148132 */, 18 },
6036 /* 5654 */ { MAD_F(0x0625d785) /* 0.384238741 */, 18 },
6037 /* 5655 */ { MAD_F(0x06263689) /* 0.384329355 */, 18 },
6038 /* 5656 */ { MAD_F(0x0626958f) /* 0.384419975 */, 18 },
6039 /* 5657 */ { MAD_F(0x0626f496) /* 0.384510600 */, 18 },
6040 /* 5658 */ { MAD_F(0x0627539e) /* 0.384601230 */, 18 },
6041 /* 5659 */ { MAD_F(0x0627b2a8) /* 0.384691866 */, 18 },
6042 /* 5660 */ { MAD_F(0x062811b3) /* 0.384782507 */, 18 },
6043 /* 5661 */ { MAD_F(0x062870c0) /* 0.384873153 */, 18 },
6044 /* 5662 */ { MAD_F(0x0628cfce) /* 0.384963805 */, 18 },
6045 /* 5663 */ { MAD_F(0x06292ede) /* 0.385054462 */, 18 },
6046
6047 /* 5664 */ { MAD_F(0x06298def) /* 0.385145124 */, 18 },
6048 /* 5665 */ { MAD_F(0x0629ed01) /* 0.385235792 */, 18 },
6049 /* 5666 */ { MAD_F(0x062a4c15) /* 0.385326465 */, 18 },
6050 /* 5667 */ { MAD_F(0x062aab2a) /* 0.385417143 */, 18 },
6051 /* 5668 */ { MAD_F(0x062b0a41) /* 0.385507827 */, 18 },
6052 /* 5669 */ { MAD_F(0x062b6959) /* 0.385598516 */, 18 },
6053 /* 5670 */ { MAD_F(0x062bc873) /* 0.385689211 */, 18 },
6054 /* 5671 */ { MAD_F(0x062c278e) /* 0.385779910 */, 18 },
6055 /* 5672 */ { MAD_F(0x062c86aa) /* 0.385870615 */, 18 },
6056 /* 5673 */ { MAD_F(0x062ce5c8) /* 0.385961326 */, 18 },
6057 /* 5674 */ { MAD_F(0x062d44e8) /* 0.386052041 */, 18 },
6058 /* 5675 */ { MAD_F(0x062da408) /* 0.386142762 */, 18 },
6059 /* 5676 */ { MAD_F(0x062e032a) /* 0.386233489 */, 18 },
6060 /* 5677 */ { MAD_F(0x062e624e) /* 0.386324221 */, 18 },
6061 /* 5678 */ { MAD_F(0x062ec173) /* 0.386414958 */, 18 },
6062 /* 5679 */ { MAD_F(0x062f209a) /* 0.386505700 */, 18 },
6063
6064 /* 5680 */ { MAD_F(0x062f7fc1) /* 0.386596448 */, 18 },
6065 /* 5681 */ { MAD_F(0x062fdeeb) /* 0.386687201 */, 18 },
6066 /* 5682 */ { MAD_F(0x06303e16) /* 0.386777959 */, 18 },
6067 /* 5683 */ { MAD_F(0x06309d42) /* 0.386868723 */, 18 },
6068 /* 5684 */ { MAD_F(0x0630fc6f) /* 0.386959492 */, 18 },
6069 /* 5685 */ { MAD_F(0x06315b9e) /* 0.387050266 */, 18 },
6070 /* 5686 */ { MAD_F(0x0631bacf) /* 0.387141045 */, 18 },
6071 /* 5687 */ { MAD_F(0x06321a01) /* 0.387231830 */, 18 },
6072 /* 5688 */ { MAD_F(0x06327934) /* 0.387322621 */, 18 },
6073 /* 5689 */ { MAD_F(0x0632d869) /* 0.387413416 */, 18 },
6074 /* 5690 */ { MAD_F(0x0633379f) /* 0.387504217 */, 18 },
6075 /* 5691 */ { MAD_F(0x063396d7) /* 0.387595023 */, 18 },
6076 /* 5692 */ { MAD_F(0x0633f610) /* 0.387685835 */, 18 },
6077 /* 5693 */ { MAD_F(0x0634554a) /* 0.387776652 */, 18 },
6078 /* 5694 */ { MAD_F(0x0634b486) /* 0.387867474 */, 18 },
6079 /* 5695 */ { MAD_F(0x063513c3) /* 0.387958301 */, 18 },
6080
6081 /* 5696 */ { MAD_F(0x06357302) /* 0.388049134 */, 18 },
6082 /* 5697 */ { MAD_F(0x0635d242) /* 0.388139972 */, 18 },
6083 /* 5698 */ { MAD_F(0x06363184) /* 0.388230816 */, 18 },
6084 /* 5699 */ { MAD_F(0x063690c7) /* 0.388321665 */, 18 },
6085 /* 5700 */ { MAD_F(0x0636f00b) /* 0.388412519 */, 18 },
6086 /* 5701 */ { MAD_F(0x06374f51) /* 0.388503378 */, 18 },
6087 /* 5702 */ { MAD_F(0x0637ae99) /* 0.388594243 */, 18 },
6088 /* 5703 */ { MAD_F(0x06380de1) /* 0.388685113 */, 18 },
6089 /* 5704 */ { MAD_F(0x06386d2b) /* 0.388775988 */, 18 },
6090 /* 5705 */ { MAD_F(0x0638cc77) /* 0.388866869 */, 18 },
6091 /* 5706 */ { MAD_F(0x06392bc4) /* 0.388957755 */, 18 },
6092 /* 5707 */ { MAD_F(0x06398b12) /* 0.389048646 */, 18 },
6093 /* 5708 */ { MAD_F(0x0639ea62) /* 0.389139542 */, 18 },
6094 /* 5709 */ { MAD_F(0x063a49b4) /* 0.389230444 */, 18 },
6095 /* 5710 */ { MAD_F(0x063aa906) /* 0.389321352 */, 18 },
6096 /* 5711 */ { MAD_F(0x063b085a) /* 0.389412264 */, 18 },
6097
6098 /* 5712 */ { MAD_F(0x063b67b0) /* 0.389503182 */, 18 },
6099 /* 5713 */ { MAD_F(0x063bc707) /* 0.389594105 */, 18 },
6100 /* 5714 */ { MAD_F(0x063c265f) /* 0.389685033 */, 18 },
6101 /* 5715 */ { MAD_F(0x063c85b9) /* 0.389775967 */, 18 },
6102 /* 5716 */ { MAD_F(0x063ce514) /* 0.389866906 */, 18 },
6103 /* 5717 */ { MAD_F(0x063d4471) /* 0.389957850 */, 18 },
6104 /* 5718 */ { MAD_F(0x063da3cf) /* 0.390048800 */, 18 },
6105 /* 5719 */ { MAD_F(0x063e032f) /* 0.390139755 */, 18 },
6106 /* 5720 */ { MAD_F(0x063e6290) /* 0.390230715 */, 18 },
6107 /* 5721 */ { MAD_F(0x063ec1f2) /* 0.390321681 */, 18 },
6108 /* 5722 */ { MAD_F(0x063f2156) /* 0.390412651 */, 18 },
6109 /* 5723 */ { MAD_F(0x063f80bb) /* 0.390503628 */, 18 },
6110 /* 5724 */ { MAD_F(0x063fe022) /* 0.390594609 */, 18 },
6111 /* 5725 */ { MAD_F(0x06403f8a) /* 0.390685596 */, 18 },
6112 /* 5726 */ { MAD_F(0x06409ef3) /* 0.390776588 */, 18 },
6113 /* 5727 */ { MAD_F(0x0640fe5e) /* 0.390867585 */, 18 },
6114
6115 /* 5728 */ { MAD_F(0x06415dcb) /* 0.390958588 */, 18 },
6116 /* 5729 */ { MAD_F(0x0641bd38) /* 0.391049596 */, 18 },
6117 /* 5730 */ { MAD_F(0x06421ca7) /* 0.391140609 */, 18 },
6118 /* 5731 */ { MAD_F(0x06427c18) /* 0.391231627 */, 18 },
6119 /* 5732 */ { MAD_F(0x0642db8a) /* 0.391322651 */, 18 },
6120 /* 5733 */ { MAD_F(0x06433afd) /* 0.391413680 */, 18 },
6121 /* 5734 */ { MAD_F(0x06439a72) /* 0.391504714 */, 18 },
6122 /* 5735 */ { MAD_F(0x0643f9e9) /* 0.391595754 */, 18 },
6123 /* 5736 */ { MAD_F(0x06445960) /* 0.391686799 */, 18 },
6124 /* 5737 */ { MAD_F(0x0644b8d9) /* 0.391777849 */, 18 },
6125 /* 5738 */ { MAD_F(0x06451854) /* 0.391868905 */, 18 },
6126 /* 5739 */ { MAD_F(0x064577d0) /* 0.391959966 */, 18 },
6127 /* 5740 */ { MAD_F(0x0645d74d) /* 0.392051032 */, 18 },
6128 /* 5741 */ { MAD_F(0x064636cc) /* 0.392142103 */, 18 },
6129 /* 5742 */ { MAD_F(0x0646964c) /* 0.392233180 */, 18 },
6130 /* 5743 */ { MAD_F(0x0646f5ce) /* 0.392324262 */, 18 },
6131
6132 /* 5744 */ { MAD_F(0x06475551) /* 0.392415349 */, 18 },
6133 /* 5745 */ { MAD_F(0x0647b4d5) /* 0.392506442 */, 18 },
6134 /* 5746 */ { MAD_F(0x0648145b) /* 0.392597540 */, 18 },
6135 /* 5747 */ { MAD_F(0x064873e3) /* 0.392688643 */, 18 },
6136 /* 5748 */ { MAD_F(0x0648d36b) /* 0.392779751 */, 18 },
6137 /* 5749 */ { MAD_F(0x064932f6) /* 0.392870865 */, 18 },
6138 /* 5750 */ { MAD_F(0x06499281) /* 0.392961984 */, 18 },
6139 /* 5751 */ { MAD_F(0x0649f20e) /* 0.393053108 */, 18 },
6140 /* 5752 */ { MAD_F(0x064a519c) /* 0.393144238 */, 18 },
6141 /* 5753 */ { MAD_F(0x064ab12c) /* 0.393235372 */, 18 },
6142 /* 5754 */ { MAD_F(0x064b10be) /* 0.393326513 */, 18 },
6143 /* 5755 */ { MAD_F(0x064b7050) /* 0.393417658 */, 18 },
6144 /* 5756 */ { MAD_F(0x064bcfe4) /* 0.393508809 */, 18 },
6145 /* 5757 */ { MAD_F(0x064c2f7a) /* 0.393599965 */, 18 },
6146 /* 5758 */ { MAD_F(0x064c8f11) /* 0.393691126 */, 18 },
6147 /* 5759 */ { MAD_F(0x064ceea9) /* 0.393782292 */, 18 },
6148
6149 /* 5760 */ { MAD_F(0x064d4e43) /* 0.393873464 */, 18 },
6150 /* 5761 */ { MAD_F(0x064dadde) /* 0.393964641 */, 18 },
6151 /* 5762 */ { MAD_F(0x064e0d7a) /* 0.394055823 */, 18 },
6152 /* 5763 */ { MAD_F(0x064e6d18) /* 0.394147011 */, 18 },
6153 /* 5764 */ { MAD_F(0x064eccb8) /* 0.394238204 */, 18 },
6154 /* 5765 */ { MAD_F(0x064f2c59) /* 0.394329402 */, 18 },
6155 /* 5766 */ { MAD_F(0x064f8bfb) /* 0.394420605 */, 18 },
6156 /* 5767 */ { MAD_F(0x064feb9e) /* 0.394511814 */, 18 },
6157 /* 5768 */ { MAD_F(0x06504b44) /* 0.394603028 */, 18 },
6158 /* 5769 */ { MAD_F(0x0650aaea) /* 0.394694247 */, 18 },
6159 /* 5770 */ { MAD_F(0x06510a92) /* 0.394785472 */, 18 },
6160 /* 5771 */ { MAD_F(0x06516a3b) /* 0.394876702 */, 18 },
6161 /* 5772 */ { MAD_F(0x0651c9e6) /* 0.394967937 */, 18 },
6162 /* 5773 */ { MAD_F(0x06522992) /* 0.395059177 */, 18 },
6163 /* 5774 */ { MAD_F(0x06528940) /* 0.395150423 */, 18 },
6164 /* 5775 */ { MAD_F(0x0652e8ef) /* 0.395241673 */, 18 },
6165
6166 /* 5776 */ { MAD_F(0x0653489f) /* 0.395332930 */, 18 },
6167 /* 5777 */ { MAD_F(0x0653a851) /* 0.395424191 */, 18 },
6168 /* 5778 */ { MAD_F(0x06540804) /* 0.395515458 */, 18 },
6169 /* 5779 */ { MAD_F(0x065467b9) /* 0.395606730 */, 18 },
6170 /* 5780 */ { MAD_F(0x0654c76f) /* 0.395698007 */, 18 },
6171 /* 5781 */ { MAD_F(0x06552726) /* 0.395789289 */, 18 },
6172 /* 5782 */ { MAD_F(0x065586df) /* 0.395880577 */, 18 },
6173 /* 5783 */ { MAD_F(0x0655e699) /* 0.395971870 */, 18 },
6174 /* 5784 */ { MAD_F(0x06564655) /* 0.396063168 */, 18 },
6175 /* 5785 */ { MAD_F(0x0656a612) /* 0.396154472 */, 18 },
6176 /* 5786 */ { MAD_F(0x065705d0) /* 0.396245780 */, 18 },
6177 /* 5787 */ { MAD_F(0x06576590) /* 0.396337094 */, 18 },
6178 /* 5788 */ { MAD_F(0x0657c552) /* 0.396428414 */, 18 },
6179 /* 5789 */ { MAD_F(0x06582514) /* 0.396519738 */, 18 },
6180 /* 5790 */ { MAD_F(0x065884d9) /* 0.396611068 */, 18 },
6181 /* 5791 */ { MAD_F(0x0658e49e) /* 0.396702403 */, 18 },
6182
6183 /* 5792 */ { MAD_F(0x06594465) /* 0.396793743 */, 18 },
6184 /* 5793 */ { MAD_F(0x0659a42e) /* 0.396885089 */, 18 },
6185 /* 5794 */ { MAD_F(0x065a03f7) /* 0.396976440 */, 18 },
6186 /* 5795 */ { MAD_F(0x065a63c3) /* 0.397067796 */, 18 },
6187 /* 5796 */ { MAD_F(0x065ac38f) /* 0.397159157 */, 18 },
6188 /* 5797 */ { MAD_F(0x065b235d) /* 0.397250524 */, 18 },
6189 /* 5798 */ { MAD_F(0x065b832d) /* 0.397341896 */, 18 },
6190 /* 5799 */ { MAD_F(0x065be2fe) /* 0.397433273 */, 18 },
6191 /* 5800 */ { MAD_F(0x065c42d0) /* 0.397524655 */, 18 },
6192 /* 5801 */ { MAD_F(0x065ca2a3) /* 0.397616043 */, 18 },
6193 /* 5802 */ { MAD_F(0x065d0279) /* 0.397707436 */, 18 },
6194 /* 5803 */ { MAD_F(0x065d624f) /* 0.397798834 */, 18 },
6195 /* 5804 */ { MAD_F(0x065dc227) /* 0.397890237 */, 18 },
6196 /* 5805 */ { MAD_F(0x065e2200) /* 0.397981646 */, 18 },
6197 /* 5806 */ { MAD_F(0x065e81db) /* 0.398073059 */, 18 },
6198 /* 5807 */ { MAD_F(0x065ee1b7) /* 0.398164479 */, 18 },
6199
6200 /* 5808 */ { MAD_F(0x065f4195) /* 0.398255903 */, 18 },
6201 /* 5809 */ { MAD_F(0x065fa174) /* 0.398347333 */, 18 },
6202 /* 5810 */ { MAD_F(0x06600154) /* 0.398438767 */, 18 },
6203 /* 5811 */ { MAD_F(0x06606136) /* 0.398530207 */, 18 },
6204 /* 5812 */ { MAD_F(0x0660c119) /* 0.398621653 */, 18 },
6205 /* 5813 */ { MAD_F(0x066120fd) /* 0.398713103 */, 18 },
6206 /* 5814 */ { MAD_F(0x066180e3) /* 0.398804559 */, 18 },
6207 /* 5815 */ { MAD_F(0x0661e0cb) /* 0.398896020 */, 18 },
6208 /* 5816 */ { MAD_F(0x066240b4) /* 0.398987487 */, 18 },
6209 /* 5817 */ { MAD_F(0x0662a09e) /* 0.399078958 */, 18 },
6210 /* 5818 */ { MAD_F(0x06630089) /* 0.399170435 */, 18 },
6211 /* 5819 */ { MAD_F(0x06636077) /* 0.399261917 */, 18 },
6212 /* 5820 */ { MAD_F(0x0663c065) /* 0.399353404 */, 18 },
6213 /* 5821 */ { MAD_F(0x06642055) /* 0.399444897 */, 18 },
6214 /* 5822 */ { MAD_F(0x06648046) /* 0.399536395 */, 18 },
6215 /* 5823 */ { MAD_F(0x0664e039) /* 0.399627898 */, 18 },
6216
6217 /* 5824 */ { MAD_F(0x0665402d) /* 0.399719406 */, 18 },
6218 /* 5825 */ { MAD_F(0x0665a022) /* 0.399810919 */, 18 },
6219 /* 5826 */ { MAD_F(0x06660019) /* 0.399902438 */, 18 },
6220 /* 5827 */ { MAD_F(0x06666011) /* 0.399993962 */, 18 },
6221 /* 5828 */ { MAD_F(0x0666c00b) /* 0.400085491 */, 18 },
6222 /* 5829 */ { MAD_F(0x06672006) /* 0.400177026 */, 18 },
6223 /* 5830 */ { MAD_F(0x06678003) /* 0.400268565 */, 18 },
6224 /* 5831 */ { MAD_F(0x0667e000) /* 0.400360110 */, 18 },
6225 /* 5832 */ { MAD_F(0x06684000) /* 0.400451660 */, 18 },
6226 /* 5833 */ { MAD_F(0x0668a000) /* 0.400543216 */, 18 },
6227 /* 5834 */ { MAD_F(0x06690003) /* 0.400634776 */, 18 },
6228 /* 5835 */ { MAD_F(0x06696006) /* 0.400726342 */, 18 },
6229 /* 5836 */ { MAD_F(0x0669c00b) /* 0.400817913 */, 18 },
6230 /* 5837 */ { MAD_F(0x066a2011) /* 0.400909489 */, 18 },
6231 /* 5838 */ { MAD_F(0x066a8019) /* 0.401001071 */, 18 },
6232 /* 5839 */ { MAD_F(0x066ae022) /* 0.401092657 */, 18 },
6233
6234 /* 5840 */ { MAD_F(0x066b402d) /* 0.401184249 */, 18 },
6235 /* 5841 */ { MAD_F(0x066ba039) /* 0.401275847 */, 18 },
6236 /* 5842 */ { MAD_F(0x066c0046) /* 0.401367449 */, 18 },
6237 /* 5843 */ { MAD_F(0x066c6055) /* 0.401459057 */, 18 },
6238 /* 5844 */ { MAD_F(0x066cc065) /* 0.401550670 */, 18 },
6239 /* 5845 */ { MAD_F(0x066d2076) /* 0.401642288 */, 18 },
6240 /* 5846 */ { MAD_F(0x066d8089) /* 0.401733911 */, 18 },
6241 /* 5847 */ { MAD_F(0x066de09e) /* 0.401825540 */, 18 },
6242 /* 5848 */ { MAD_F(0x066e40b3) /* 0.401917173 */, 18 },
6243 /* 5849 */ { MAD_F(0x066ea0cb) /* 0.402008812 */, 18 },
6244 /* 5850 */ { MAD_F(0x066f00e3) /* 0.402100457 */, 18 },
6245 /* 5851 */ { MAD_F(0x066f60fd) /* 0.402192106 */, 18 },
6246 /* 5852 */ { MAD_F(0x066fc118) /* 0.402283761 */, 18 },
6247 /* 5853 */ { MAD_F(0x06702135) /* 0.402375420 */, 18 },
6248 /* 5854 */ { MAD_F(0x06708153) /* 0.402467086 */, 18 },
6249 /* 5855 */ { MAD_F(0x0670e173) /* 0.402558756 */, 18 },
6250
6251 /* 5856 */ { MAD_F(0x06714194) /* 0.402650431 */, 18 },
6252 /* 5857 */ { MAD_F(0x0671a1b6) /* 0.402742112 */, 18 },
6253 /* 5858 */ { MAD_F(0x067201da) /* 0.402833798 */, 18 },
6254 /* 5859 */ { MAD_F(0x067261ff) /* 0.402925489 */, 18 },
6255 /* 5860 */ { MAD_F(0x0672c226) /* 0.403017186 */, 18 },
6256 /* 5861 */ { MAD_F(0x0673224e) /* 0.403108887 */, 18 },
6257 /* 5862 */ { MAD_F(0x06738277) /* 0.403200594 */, 18 },
6258 /* 5863 */ { MAD_F(0x0673e2a2) /* 0.403292306 */, 18 },
6259 /* 5864 */ { MAD_F(0x067442ce) /* 0.403384024 */, 18 },
6260 /* 5865 */ { MAD_F(0x0674a2fc) /* 0.403475746 */, 18 },
6261 /* 5866 */ { MAD_F(0x0675032b) /* 0.403567474 */, 18 },
6262 /* 5867 */ { MAD_F(0x0675635b) /* 0.403659207 */, 18 },
6263 /* 5868 */ { MAD_F(0x0675c38d) /* 0.403750945 */, 18 },
6264 /* 5869 */ { MAD_F(0x067623c0) /* 0.403842688 */, 18 },
6265 /* 5870 */ { MAD_F(0x067683f4) /* 0.403934437 */, 18 },
6266 /* 5871 */ { MAD_F(0x0676e42a) /* 0.404026190 */, 18 },
6267
6268 /* 5872 */ { MAD_F(0x06774462) /* 0.404117949 */, 18 },
6269 /* 5873 */ { MAD_F(0x0677a49b) /* 0.404209714 */, 18 },
6270 /* 5874 */ { MAD_F(0x067804d5) /* 0.404301483 */, 18 },
6271 /* 5875 */ { MAD_F(0x06786510) /* 0.404393258 */, 18 },
6272 /* 5876 */ { MAD_F(0x0678c54d) /* 0.404485037 */, 18 },
6273 /* 5877 */ { MAD_F(0x0679258c) /* 0.404576822 */, 18 },
6274 /* 5878 */ { MAD_F(0x067985cb) /* 0.404668613 */, 18 },
6275 /* 5879 */ { MAD_F(0x0679e60c) /* 0.404760408 */, 18 },
6276 /* 5880 */ { MAD_F(0x067a464f) /* 0.404852209 */, 18 },
6277 /* 5881 */ { MAD_F(0x067aa693) /* 0.404944014 */, 18 },
6278 /* 5882 */ { MAD_F(0x067b06d8) /* 0.405035825 */, 18 },
6279 /* 5883 */ { MAD_F(0x067b671f) /* 0.405127642 */, 18 },
6280 /* 5884 */ { MAD_F(0x067bc767) /* 0.405219463 */, 18 },
6281 /* 5885 */ { MAD_F(0x067c27b1) /* 0.405311290 */, 18 },
6282 /* 5886 */ { MAD_F(0x067c87fc) /* 0.405403122 */, 18 },
6283 /* 5887 */ { MAD_F(0x067ce848) /* 0.405494959 */, 18 },
6284
6285 /* 5888 */ { MAD_F(0x067d4896) /* 0.405586801 */, 18 },
6286 /* 5889 */ { MAD_F(0x067da8e5) /* 0.405678648 */, 18 },
6287 /* 5890 */ { MAD_F(0x067e0935) /* 0.405770501 */, 18 },
6288 /* 5891 */ { MAD_F(0x067e6987) /* 0.405862359 */, 18 },
6289 /* 5892 */ { MAD_F(0x067ec9da) /* 0.405954222 */, 18 },
6290 /* 5893 */ { MAD_F(0x067f2a2f) /* 0.406046090 */, 18 },
6291 /* 5894 */ { MAD_F(0x067f8a85) /* 0.406137963 */, 18 },
6292 /* 5895 */ { MAD_F(0x067feadd) /* 0.406229842 */, 18 },
6293 /* 5896 */ { MAD_F(0x06804b36) /* 0.406321726 */, 18 },
6294 /* 5897 */ { MAD_F(0x0680ab90) /* 0.406413615 */, 18 },
6295 /* 5898 */ { MAD_F(0x06810beb) /* 0.406505509 */, 18 },
6296 /* 5899 */ { MAD_F(0x06816c49) /* 0.406597408 */, 18 },
6297 /* 5900 */ { MAD_F(0x0681cca7) /* 0.406689313 */, 18 },
6298 /* 5901 */ { MAD_F(0x06822d07) /* 0.406781223 */, 18 },
6299 /* 5902 */ { MAD_F(0x06828d68) /* 0.406873138 */, 18 },
6300 /* 5903 */ { MAD_F(0x0682edcb) /* 0.406965058 */, 18 },
6301
6302 /* 5904 */ { MAD_F(0x06834e2f) /* 0.407056983 */, 18 },
6303 /* 5905 */ { MAD_F(0x0683ae94) /* 0.407148914 */, 18 },
6304 /* 5906 */ { MAD_F(0x06840efb) /* 0.407240850 */, 18 },
6305 /* 5907 */ { MAD_F(0x06846f63) /* 0.407332791 */, 18 },
6306 /* 5908 */ { MAD_F(0x0684cfcd) /* 0.407424737 */, 18 },
6307 /* 5909 */ { MAD_F(0x06853038) /* 0.407516688 */, 18 },
6308 /* 5910 */ { MAD_F(0x068590a4) /* 0.407608645 */, 18 },
6309 /* 5911 */ { MAD_F(0x0685f112) /* 0.407700606 */, 18 },
6310 /* 5912 */ { MAD_F(0x06865181) /* 0.407792573 */, 18 },
6311 /* 5913 */ { MAD_F(0x0686b1f2) /* 0.407884545 */, 18 },
6312 /* 5914 */ { MAD_F(0x06871264) /* 0.407976522 */, 18 },
6313 /* 5915 */ { MAD_F(0x068772d7) /* 0.408068505 */, 18 },
6314 /* 5916 */ { MAD_F(0x0687d34c) /* 0.408160492 */, 18 },
6315 /* 5917 */ { MAD_F(0x068833c2) /* 0.408252485 */, 18 },
6316 /* 5918 */ { MAD_F(0x06889439) /* 0.408344483 */, 18 },
6317 /* 5919 */ { MAD_F(0x0688f4b2) /* 0.408436486 */, 18 },
6318
6319 /* 5920 */ { MAD_F(0x0689552c) /* 0.408528495 */, 18 },
6320 /* 5921 */ { MAD_F(0x0689b5a8) /* 0.408620508 */, 18 },
6321 /* 5922 */ { MAD_F(0x068a1625) /* 0.408712527 */, 18 },
6322 /* 5923 */ { MAD_F(0x068a76a4) /* 0.408804551 */, 18 },
6323 /* 5924 */ { MAD_F(0x068ad724) /* 0.408896580 */, 18 },
6324 /* 5925 */ { MAD_F(0x068b37a5) /* 0.408988614 */, 18 },
6325 /* 5926 */ { MAD_F(0x068b9827) /* 0.409080653 */, 18 },
6326 /* 5927 */ { MAD_F(0x068bf8ac) /* 0.409172698 */, 18 },
6327 /* 5928 */ { MAD_F(0x068c5931) /* 0.409264748 */, 18 },
6328 /* 5929 */ { MAD_F(0x068cb9b8) /* 0.409356803 */, 18 },
6329 /* 5930 */ { MAD_F(0x068d1a40) /* 0.409448863 */, 18 },
6330 /* 5931 */ { MAD_F(0x068d7aca) /* 0.409540928 */, 18 },
6331 /* 5932 */ { MAD_F(0x068ddb54) /* 0.409632999 */, 18 },
6332 /* 5933 */ { MAD_F(0x068e3be1) /* 0.409725074 */, 18 },
6333 /* 5934 */ { MAD_F(0x068e9c6f) /* 0.409817155 */, 18 },
6334 /* 5935 */ { MAD_F(0x068efcfe) /* 0.409909241 */, 18 },
6335
6336 /* 5936 */ { MAD_F(0x068f5d8e) /* 0.410001332 */, 18 },
6337 /* 5937 */ { MAD_F(0x068fbe20) /* 0.410093428 */, 18 },
6338 /* 5938 */ { MAD_F(0x06901eb4) /* 0.410185530 */, 18 },
6339 /* 5939 */ { MAD_F(0x06907f48) /* 0.410277637 */, 18 },
6340 /* 5940 */ { MAD_F(0x0690dfde) /* 0.410369748 */, 18 },
6341 /* 5941 */ { MAD_F(0x06914076) /* 0.410461865 */, 18 },
6342 /* 5942 */ { MAD_F(0x0691a10f) /* 0.410553988 */, 18 },
6343 /* 5943 */ { MAD_F(0x069201a9) /* 0.410646115 */, 18 },
6344 /* 5944 */ { MAD_F(0x06926245) /* 0.410738247 */, 18 },
6345 /* 5945 */ { MAD_F(0x0692c2e2) /* 0.410830385 */, 18 },
6346 /* 5946 */ { MAD_F(0x06932380) /* 0.410922528 */, 18 },
6347 /* 5947 */ { MAD_F(0x06938420) /* 0.411014676 */, 18 },
6348 /* 5948 */ { MAD_F(0x0693e4c1) /* 0.411106829 */, 18 },
6349 /* 5949 */ { MAD_F(0x06944563) /* 0.411198987 */, 18 },
6350 /* 5950 */ { MAD_F(0x0694a607) /* 0.411291151 */, 18 },
6351 /* 5951 */ { MAD_F(0x069506ad) /* 0.411383320 */, 18 },
6352
6353 /* 5952 */ { MAD_F(0x06956753) /* 0.411475493 */, 18 },
6354 /* 5953 */ { MAD_F(0x0695c7fc) /* 0.411567672 */, 18 },
6355 /* 5954 */ { MAD_F(0x069628a5) /* 0.411659857 */, 18 },
6356 /* 5955 */ { MAD_F(0x06968950) /* 0.411752046 */, 18 },
6357 /* 5956 */ { MAD_F(0x0696e9fc) /* 0.411844240 */, 18 },
6358 /* 5957 */ { MAD_F(0x06974aaa) /* 0.411936440 */, 18 },
6359 /* 5958 */ { MAD_F(0x0697ab59) /* 0.412028645 */, 18 },
6360 /* 5959 */ { MAD_F(0x06980c09) /* 0.412120855 */, 18 },
6361 /* 5960 */ { MAD_F(0x06986cbb) /* 0.412213070 */, 18 },
6362 /* 5961 */ { MAD_F(0x0698cd6e) /* 0.412305290 */, 18 },
6363 /* 5962 */ { MAD_F(0x06992e23) /* 0.412397516 */, 18 },
6364 /* 5963 */ { MAD_F(0x06998ed9) /* 0.412489746 */, 18 },
6365 /* 5964 */ { MAD_F(0x0699ef90) /* 0.412581982 */, 18 },
6366 /* 5965 */ { MAD_F(0x069a5049) /* 0.412674223 */, 18 },
6367 /* 5966 */ { MAD_F(0x069ab103) /* 0.412766469 */, 18 },
6368 /* 5967 */ { MAD_F(0x069b11bf) /* 0.412858720 */, 18 },
6369
6370 /* 5968 */ { MAD_F(0x069b727b) /* 0.412950976 */, 18 },
6371 /* 5969 */ { MAD_F(0x069bd33a) /* 0.413043238 */, 18 },
6372 /* 5970 */ { MAD_F(0x069c33f9) /* 0.413135505 */, 18 },
6373 /* 5971 */ { MAD_F(0x069c94ba) /* 0.413227776 */, 18 },
6374 /* 5972 */ { MAD_F(0x069cf57d) /* 0.413320053 */, 18 },
6375 /* 5973 */ { MAD_F(0x069d5641) /* 0.413412335 */, 18 },
6376 /* 5974 */ { MAD_F(0x069db706) /* 0.413504623 */, 18 },
6377 /* 5975 */ { MAD_F(0x069e17cc) /* 0.413596915 */, 18 },
6378 /* 5976 */ { MAD_F(0x069e7894) /* 0.413689213 */, 18 },
6379 /* 5977 */ { MAD_F(0x069ed95e) /* 0.413781515 */, 18 },
6380 /* 5978 */ { MAD_F(0x069f3a28) /* 0.413873823 */, 18 },
6381 /* 5979 */ { MAD_F(0x069f9af4) /* 0.413966136 */, 18 },
6382 /* 5980 */ { MAD_F(0x069ffbc2) /* 0.414058454 */, 18 },
6383 /* 5981 */ { MAD_F(0x06a05c91) /* 0.414150778 */, 18 },
6384 /* 5982 */ { MAD_F(0x06a0bd61) /* 0.414243106 */, 18 },
6385 /* 5983 */ { MAD_F(0x06a11e32) /* 0.414335440 */, 18 },
6386
6387 /* 5984 */ { MAD_F(0x06a17f05) /* 0.414427779 */, 18 },
6388 /* 5985 */ { MAD_F(0x06a1dfda) /* 0.414520122 */, 18 },
6389 /* 5986 */ { MAD_F(0x06a240b0) /* 0.414612471 */, 18 },
6390 /* 5987 */ { MAD_F(0x06a2a187) /* 0.414704826 */, 18 },
6391 /* 5988 */ { MAD_F(0x06a3025f) /* 0.414797185 */, 18 },
6392 /* 5989 */ { MAD_F(0x06a36339) /* 0.414889549 */, 18 },
6393 /* 5990 */ { MAD_F(0x06a3c414) /* 0.414981919 */, 18 },
6394 /* 5991 */ { MAD_F(0x06a424f1) /* 0.415074294 */, 18 },
6395 /* 5992 */ { MAD_F(0x06a485cf) /* 0.415166674 */, 18 },
6396 /* 5993 */ { MAD_F(0x06a4e6ae) /* 0.415259059 */, 18 },
6397 /* 5994 */ { MAD_F(0x06a5478f) /* 0.415351449 */, 18 },
6398 /* 5995 */ { MAD_F(0x06a5a871) /* 0.415443844 */, 18 },
6399 /* 5996 */ { MAD_F(0x06a60955) /* 0.415536244 */, 18 },
6400 /* 5997 */ { MAD_F(0x06a66a3a) /* 0.415628650 */, 18 },
6401 /* 5998 */ { MAD_F(0x06a6cb20) /* 0.415721061 */, 18 },
6402 /* 5999 */ { MAD_F(0x06a72c08) /* 0.415813476 */, 18 },
6403
6404 /* 6000 */ { MAD_F(0x06a78cf1) /* 0.415905897 */, 18 },
6405 /* 6001 */ { MAD_F(0x06a7eddb) /* 0.415998324 */, 18 },
6406 /* 6002 */ { MAD_F(0x06a84ec7) /* 0.416090755 */, 18 },
6407 /* 6003 */ { MAD_F(0x06a8afb4) /* 0.416183191 */, 18 },
6408 /* 6004 */ { MAD_F(0x06a910a3) /* 0.416275633 */, 18 },
6409 /* 6005 */ { MAD_F(0x06a97193) /* 0.416368079 */, 18 },
6410 /* 6006 */ { MAD_F(0x06a9d284) /* 0.416460531 */, 18 },
6411 /* 6007 */ { MAD_F(0x06aa3377) /* 0.416552988 */, 18 },
6412 /* 6008 */ { MAD_F(0x06aa946b) /* 0.416645450 */, 18 },
6413 /* 6009 */ { MAD_F(0x06aaf561) /* 0.416737917 */, 18 },
6414 /* 6010 */ { MAD_F(0x06ab5657) /* 0.416830389 */, 18 },
6415 /* 6011 */ { MAD_F(0x06abb750) /* 0.416922867 */, 18 },
6416 /* 6012 */ { MAD_F(0x06ac1849) /* 0.417015349 */, 18 },
6417 /* 6013 */ { MAD_F(0x06ac7944) /* 0.417107837 */, 18 },
6418 /* 6014 */ { MAD_F(0x06acda41) /* 0.417200330 */, 18 },
6419 /* 6015 */ { MAD_F(0x06ad3b3e) /* 0.417292828 */, 18 },
6420
6421 /* 6016 */ { MAD_F(0x06ad9c3d) /* 0.417385331 */, 18 },
6422 /* 6017 */ { MAD_F(0x06adfd3e) /* 0.417477839 */, 18 },
6423 /* 6018 */ { MAD_F(0x06ae5e40) /* 0.417570352 */, 18 },
6424 /* 6019 */ { MAD_F(0x06aebf43) /* 0.417662871 */, 18 },
6425 /* 6020 */ { MAD_F(0x06af2047) /* 0.417755394 */, 18 },
6426 /* 6021 */ { MAD_F(0x06af814d) /* 0.417847923 */, 18 },
6427 /* 6022 */ { MAD_F(0x06afe255) /* 0.417940457 */, 18 },
6428 /* 6023 */ { MAD_F(0x06b0435e) /* 0.418032996 */, 18 },
6429 /* 6024 */ { MAD_F(0x06b0a468) /* 0.418125540 */, 18 },
6430 /* 6025 */ { MAD_F(0x06b10573) /* 0.418218089 */, 18 },
6431 /* 6026 */ { MAD_F(0x06b16680) /* 0.418310643 */, 18 },
6432 /* 6027 */ { MAD_F(0x06b1c78e) /* 0.418403203 */, 18 },
6433 /* 6028 */ { MAD_F(0x06b2289e) /* 0.418495767 */, 18 },
6434 /* 6029 */ { MAD_F(0x06b289af) /* 0.418588337 */, 18 },
6435 /* 6030 */ { MAD_F(0x06b2eac1) /* 0.418680911 */, 18 },
6436 /* 6031 */ { MAD_F(0x06b34bd5) /* 0.418773491 */, 18 },
6437
6438 /* 6032 */ { MAD_F(0x06b3acea) /* 0.418866076 */, 18 },
6439 /* 6033 */ { MAD_F(0x06b40e00) /* 0.418958666 */, 18 },
6440 /* 6034 */ { MAD_F(0x06b46f18) /* 0.419051262 */, 18 },
6441 /* 6035 */ { MAD_F(0x06b4d031) /* 0.419143862 */, 18 },
6442 /* 6036 */ { MAD_F(0x06b5314c) /* 0.419236467 */, 18 },
6443 /* 6037 */ { MAD_F(0x06b59268) /* 0.419329078 */, 18 },
6444 /* 6038 */ { MAD_F(0x06b5f385) /* 0.419421694 */, 18 },
6445 /* 6039 */ { MAD_F(0x06b654a4) /* 0.419514314 */, 18 },
6446 /* 6040 */ { MAD_F(0x06b6b5c4) /* 0.419606940 */, 18 },
6447 /* 6041 */ { MAD_F(0x06b716e6) /* 0.419699571 */, 18 },
6448 /* 6042 */ { MAD_F(0x06b77808) /* 0.419792208 */, 18 },
6449 /* 6043 */ { MAD_F(0x06b7d92d) /* 0.419884849 */, 18 },
6450 /* 6044 */ { MAD_F(0x06b83a52) /* 0.419977495 */, 18 },
6451 /* 6045 */ { MAD_F(0x06b89b79) /* 0.420070147 */, 18 },
6452 /* 6046 */ { MAD_F(0x06b8fca1) /* 0.420162803 */, 18 },
6453 /* 6047 */ { MAD_F(0x06b95dcb) /* 0.420255465 */, 18 },
6454
6455 /* 6048 */ { MAD_F(0x06b9bef6) /* 0.420348132 */, 18 },
6456 /* 6049 */ { MAD_F(0x06ba2023) /* 0.420440803 */, 18 },
6457 /* 6050 */ { MAD_F(0x06ba8150) /* 0.420533481 */, 18 },
6458 /* 6051 */ { MAD_F(0x06bae280) /* 0.420626163 */, 18 },
6459 /* 6052 */ { MAD_F(0x06bb43b0) /* 0.420718850 */, 18 },
6460 /* 6053 */ { MAD_F(0x06bba4e2) /* 0.420811542 */, 18 },
6461 /* 6054 */ { MAD_F(0x06bc0615) /* 0.420904240 */, 18 },
6462 /* 6055 */ { MAD_F(0x06bc674a) /* 0.420996942 */, 18 },
6463 /* 6056 */ { MAD_F(0x06bcc880) /* 0.421089650 */, 18 },
6464 /* 6057 */ { MAD_F(0x06bd29b7) /* 0.421182362 */, 18 },
6465 /* 6058 */ { MAD_F(0x06bd8af0) /* 0.421275080 */, 18 },
6466 /* 6059 */ { MAD_F(0x06bdec2a) /* 0.421367803 */, 18 },
6467 /* 6060 */ { MAD_F(0x06be4d66) /* 0.421460531 */, 18 },
6468 /* 6061 */ { MAD_F(0x06beaea3) /* 0.421553264 */, 18 },
6469 /* 6062 */ { MAD_F(0x06bf0fe1) /* 0.421646003 */, 18 },
6470 /* 6063 */ { MAD_F(0x06bf7120) /* 0.421738746 */, 18 },
6471
6472 /* 6064 */ { MAD_F(0x06bfd261) /* 0.421831494 */, 18 },
6473 /* 6065 */ { MAD_F(0x06c033a4) /* 0.421924248 */, 18 },
6474 /* 6066 */ { MAD_F(0x06c094e7) /* 0.422017007 */, 18 },
6475 /* 6067 */ { MAD_F(0x06c0f62c) /* 0.422109770 */, 18 },
6476 /* 6068 */ { MAD_F(0x06c15773) /* 0.422202539 */, 18 },
6477 /* 6069 */ { MAD_F(0x06c1b8bb) /* 0.422295313 */, 18 },
6478 /* 6070 */ { MAD_F(0x06c21a04) /* 0.422388092 */, 18 },
6479 /* 6071 */ { MAD_F(0x06c27b4e) /* 0.422480876 */, 18 },
6480 /* 6072 */ { MAD_F(0x06c2dc9a) /* 0.422573665 */, 18 },
6481 /* 6073 */ { MAD_F(0x06c33de8) /* 0.422666460 */, 18 },
6482 /* 6074 */ { MAD_F(0x06c39f36) /* 0.422759259 */, 18 },
6483 /* 6075 */ { MAD_F(0x06c40086) /* 0.422852064 */, 18 },
6484 /* 6076 */ { MAD_F(0x06c461d8) /* 0.422944873 */, 18 },
6485 /* 6077 */ { MAD_F(0x06c4c32a) /* 0.423037688 */, 18 },
6486 /* 6078 */ { MAD_F(0x06c5247f) /* 0.423130508 */, 18 },
6487 /* 6079 */ { MAD_F(0x06c585d4) /* 0.423223333 */, 18 },
6488
6489 /* 6080 */ { MAD_F(0x06c5e72b) /* 0.423316162 */, 18 },
6490 /* 6081 */ { MAD_F(0x06c64883) /* 0.423408997 */, 18 },
6491 /* 6082 */ { MAD_F(0x06c6a9dd) /* 0.423501838 */, 18 },
6492 /* 6083 */ { MAD_F(0x06c70b38) /* 0.423594683 */, 18 },
6493 /* 6084 */ { MAD_F(0x06c76c94) /* 0.423687533 */, 18 },
6494 /* 6085 */ { MAD_F(0x06c7cdf2) /* 0.423780389 */, 18 },
6495 /* 6086 */ { MAD_F(0x06c82f51) /* 0.423873249 */, 18 },
6496 /* 6087 */ { MAD_F(0x06c890b1) /* 0.423966115 */, 18 },
6497 /* 6088 */ { MAD_F(0x06c8f213) /* 0.424058985 */, 18 },
6498 /* 6089 */ { MAD_F(0x06c95376) /* 0.424151861 */, 18 },
6499 /* 6090 */ { MAD_F(0x06c9b4da) /* 0.424244742 */, 18 },
6500 /* 6091 */ { MAD_F(0x06ca1640) /* 0.424337628 */, 18 },
6501 /* 6092 */ { MAD_F(0x06ca77a8) /* 0.424430519 */, 18 },
6502 /* 6093 */ { MAD_F(0x06cad910) /* 0.424523415 */, 18 },
6503 /* 6094 */ { MAD_F(0x06cb3a7a) /* 0.424616316 */, 18 },
6504 /* 6095 */ { MAD_F(0x06cb9be5) /* 0.424709222 */, 18 },
6505
6506 /* 6096 */ { MAD_F(0x06cbfd52) /* 0.424802133 */, 18 },
6507 /* 6097 */ { MAD_F(0x06cc5ec0) /* 0.424895050 */, 18 },
6508 /* 6098 */ { MAD_F(0x06ccc030) /* 0.424987971 */, 18 },
6509 /* 6099 */ { MAD_F(0x06cd21a0) /* 0.425080898 */, 18 },
6510 /* 6100 */ { MAD_F(0x06cd8313) /* 0.425173829 */, 18 },
6511 /* 6101 */ { MAD_F(0x06cde486) /* 0.425266766 */, 18 },
6512 /* 6102 */ { MAD_F(0x06ce45fb) /* 0.425359708 */, 18 },
6513 /* 6103 */ { MAD_F(0x06cea771) /* 0.425452655 */, 18 },
6514 /* 6104 */ { MAD_F(0x06cf08e9) /* 0.425545607 */, 18 },
6515 /* 6105 */ { MAD_F(0x06cf6a62) /* 0.425638564 */, 18 },
6516 /* 6106 */ { MAD_F(0x06cfcbdc) /* 0.425731526 */, 18 },
6517 /* 6107 */ { MAD_F(0x06d02d58) /* 0.425824493 */, 18 },
6518 /* 6108 */ { MAD_F(0x06d08ed5) /* 0.425917465 */, 18 },
6519 /* 6109 */ { MAD_F(0x06d0f053) /* 0.426010443 */, 18 },
6520 /* 6110 */ { MAD_F(0x06d151d3) /* 0.426103425 */, 18 },
6521 /* 6111 */ { MAD_F(0x06d1b354) /* 0.426196412 */, 18 },
6522
6523 /* 6112 */ { MAD_F(0x06d214d7) /* 0.426289405 */, 18 },
6524 /* 6113 */ { MAD_F(0x06d2765a) /* 0.426382403 */, 18 },
6525 /* 6114 */ { MAD_F(0x06d2d7e0) /* 0.426475405 */, 18 },
6526 /* 6115 */ { MAD_F(0x06d33966) /* 0.426568413 */, 18 },
6527 /* 6116 */ { MAD_F(0x06d39aee) /* 0.426661426 */, 18 },
6528 /* 6117 */ { MAD_F(0x06d3fc77) /* 0.426754444 */, 18 },
6529 /* 6118 */ { MAD_F(0x06d45e02) /* 0.426847467 */, 18 },
6530 /* 6119 */ { MAD_F(0x06d4bf8e) /* 0.426940495 */, 18 },
6531 /* 6120 */ { MAD_F(0x06d5211c) /* 0.427033528 */, 18 },
6532 /* 6121 */ { MAD_F(0x06d582aa) /* 0.427126566 */, 18 },
6533 /* 6122 */ { MAD_F(0x06d5e43a) /* 0.427219609 */, 18 },
6534 /* 6123 */ { MAD_F(0x06d645cc) /* 0.427312657 */, 18 },
6535 /* 6124 */ { MAD_F(0x06d6a75f) /* 0.427405711 */, 18 },
6536 /* 6125 */ { MAD_F(0x06d708f3) /* 0.427498769 */, 18 },
6537 /* 6126 */ { MAD_F(0x06d76a88) /* 0.427591833 */, 18 },
6538 /* 6127 */ { MAD_F(0x06d7cc1f) /* 0.427684901 */, 18 },
6539
6540 /* 6128 */ { MAD_F(0x06d82db8) /* 0.427777975 */, 18 },
6541 /* 6129 */ { MAD_F(0x06d88f51) /* 0.427871054 */, 18 },
6542 /* 6130 */ { MAD_F(0x06d8f0ec) /* 0.427964137 */, 18 },
6543 /* 6131 */ { MAD_F(0x06d95288) /* 0.428057226 */, 18 },
6544 /* 6132 */ { MAD_F(0x06d9b426) /* 0.428150320 */, 18 },
6545 /* 6133 */ { MAD_F(0x06da15c5) /* 0.428243419 */, 18 },
6546 /* 6134 */ { MAD_F(0x06da7766) /* 0.428336523 */, 18 },
6547 /* 6135 */ { MAD_F(0x06dad907) /* 0.428429632 */, 18 },
6548 /* 6136 */ { MAD_F(0x06db3aaa) /* 0.428522746 */, 18 },
6549 /* 6137 */ { MAD_F(0x06db9c4f) /* 0.428615865 */, 18 },
6550 /* 6138 */ { MAD_F(0x06dbfdf5) /* 0.428708989 */, 18 },
6551 /* 6139 */ { MAD_F(0x06dc5f9c) /* 0.428802119 */, 18 },
6552 /* 6140 */ { MAD_F(0x06dcc145) /* 0.428895253 */, 18 },
6553 /* 6141 */ { MAD_F(0x06dd22ee) /* 0.428988392 */, 18 },
6554 /* 6142 */ { MAD_F(0x06dd849a) /* 0.429081537 */, 18 },
6555 /* 6143 */ { MAD_F(0x06dde646) /* 0.429174686 */, 18 },
6556
6557 /* 6144 */ { MAD_F(0x06de47f4) /* 0.429267841 */, 18 },
6558 /* 6145 */ { MAD_F(0x06dea9a4) /* 0.429361001 */, 18 },
6559 /* 6146 */ { MAD_F(0x06df0b54) /* 0.429454165 */, 18 },
6560 /* 6147 */ { MAD_F(0x06df6d06) /* 0.429547335 */, 18 },
6561 /* 6148 */ { MAD_F(0x06dfceba) /* 0.429640510 */, 18 },
6562 /* 6149 */ { MAD_F(0x06e0306f) /* 0.429733690 */, 18 },
6563 /* 6150 */ { MAD_F(0x06e09225) /* 0.429826874 */, 18 },
6564 /* 6151 */ { MAD_F(0x06e0f3dc) /* 0.429920064 */, 18 },
6565 /* 6152 */ { MAD_F(0x06e15595) /* 0.430013259 */, 18 },
6566 /* 6153 */ { MAD_F(0x06e1b74f) /* 0.430106459 */, 18 },
6567 /* 6154 */ { MAD_F(0x06e2190b) /* 0.430199664 */, 18 },
6568 /* 6155 */ { MAD_F(0x06e27ac8) /* 0.430292875 */, 18 },
6569 /* 6156 */ { MAD_F(0x06e2dc86) /* 0.430386090 */, 18 },
6570 /* 6157 */ { MAD_F(0x06e33e46) /* 0.430479310 */, 18 },
6571 /* 6158 */ { MAD_F(0x06e3a007) /* 0.430572535 */, 18 },
6572 /* 6159 */ { MAD_F(0x06e401c9) /* 0.430665765 */, 18 },
6573
6574 /* 6160 */ { MAD_F(0x06e4638d) /* 0.430759001 */, 18 },
6575 /* 6161 */ { MAD_F(0x06e4c552) /* 0.430852241 */, 18 },
6576 /* 6162 */ { MAD_F(0x06e52718) /* 0.430945487 */, 18 },
6577 /* 6163 */ { MAD_F(0x06e588e0) /* 0.431038737 */, 18 },
6578 /* 6164 */ { MAD_F(0x06e5eaa9) /* 0.431131993 */, 18 },
6579 /* 6165 */ { MAD_F(0x06e64c73) /* 0.431225253 */, 18 },
6580 /* 6166 */ { MAD_F(0x06e6ae3f) /* 0.431318519 */, 18 },
6581 /* 6167 */ { MAD_F(0x06e7100c) /* 0.431411790 */, 18 },
6582 /* 6168 */ { MAD_F(0x06e771db) /* 0.431505065 */, 18 },
6583 /* 6169 */ { MAD_F(0x06e7d3ab) /* 0.431598346 */, 18 },
6584 /* 6170 */ { MAD_F(0x06e8357c) /* 0.431691632 */, 18 },
6585 /* 6171 */ { MAD_F(0x06e8974e) /* 0.431784923 */, 18 },
6586 /* 6172 */ { MAD_F(0x06e8f922) /* 0.431878218 */, 18 },
6587 /* 6173 */ { MAD_F(0x06e95af8) /* 0.431971519 */, 18 },
6588 /* 6174 */ { MAD_F(0x06e9bcce) /* 0.432064825 */, 18 },
6589 /* 6175 */ { MAD_F(0x06ea1ea6) /* 0.432158136 */, 18 },
6590
6591 /* 6176 */ { MAD_F(0x06ea807f) /* 0.432251452 */, 18 },
6592 /* 6177 */ { MAD_F(0x06eae25a) /* 0.432344773 */, 18 },
6593 /* 6178 */ { MAD_F(0x06eb4436) /* 0.432438099 */, 18 },
6594 /* 6179 */ { MAD_F(0x06eba614) /* 0.432531431 */, 18 },
6595 /* 6180 */ { MAD_F(0x06ec07f2) /* 0.432624767 */, 18 },
6596 /* 6181 */ { MAD_F(0x06ec69d2) /* 0.432718108 */, 18 },
6597 /* 6182 */ { MAD_F(0x06eccbb4) /* 0.432811454 */, 18 },
6598 /* 6183 */ { MAD_F(0x06ed2d97) /* 0.432904805 */, 18 },
6599 /* 6184 */ { MAD_F(0x06ed8f7b) /* 0.432998162 */, 18 },
6600 /* 6185 */ { MAD_F(0x06edf160) /* 0.433091523 */, 18 },
6601 /* 6186 */ { MAD_F(0x06ee5347) /* 0.433184889 */, 18 },
6602 /* 6187 */ { MAD_F(0x06eeb52f) /* 0.433278261 */, 18 },
6603 /* 6188 */ { MAD_F(0x06ef1719) /* 0.433371637 */, 18 },
6604 /* 6189 */ { MAD_F(0x06ef7904) /* 0.433465019 */, 18 },
6605 /* 6190 */ { MAD_F(0x06efdaf0) /* 0.433558405 */, 18 },
6606 /* 6191 */ { MAD_F(0x06f03cde) /* 0.433651797 */, 18 },
6607
6608 /* 6192 */ { MAD_F(0x06f09ecc) /* 0.433745193 */, 18 },
6609 /* 6193 */ { MAD_F(0x06f100bd) /* 0.433838595 */, 18 },
6610 /* 6194 */ { MAD_F(0x06f162ae) /* 0.433932001 */, 18 },
6611 /* 6195 */ { MAD_F(0x06f1c4a1) /* 0.434025413 */, 18 },
6612 /* 6196 */ { MAD_F(0x06f22696) /* 0.434118830 */, 18 },
6613 /* 6197 */ { MAD_F(0x06f2888b) /* 0.434212251 */, 18 },
6614 /* 6198 */ { MAD_F(0x06f2ea82) /* 0.434305678 */, 18 },
6615 /* 6199 */ { MAD_F(0x06f34c7b) /* 0.434399110 */, 18 },
6616 /* 6200 */ { MAD_F(0x06f3ae75) /* 0.434492546 */, 18 },
6617 /* 6201 */ { MAD_F(0x06f41070) /* 0.434585988 */, 18 },
6618 /* 6202 */ { MAD_F(0x06f4726c) /* 0.434679435 */, 18 },
6619 /* 6203 */ { MAD_F(0x06f4d46a) /* 0.434772887 */, 18 },
6620 /* 6204 */ { MAD_F(0x06f53669) /* 0.434866344 */, 18 },
6621 /* 6205 */ { MAD_F(0x06f59869) /* 0.434959806 */, 18 },
6622 /* 6206 */ { MAD_F(0x06f5fa6b) /* 0.435053272 */, 18 },
6623 /* 6207 */ { MAD_F(0x06f65c6e) /* 0.435146744 */, 18 },
6624
6625 /* 6208 */ { MAD_F(0x06f6be73) /* 0.435240221 */, 18 },
6626 /* 6209 */ { MAD_F(0x06f72079) /* 0.435333703 */, 18 },
6627 /* 6210 */ { MAD_F(0x06f78280) /* 0.435427190 */, 18 },
6628 /* 6211 */ { MAD_F(0x06f7e489) /* 0.435520682 */, 18 },
6629 /* 6212 */ { MAD_F(0x06f84693) /* 0.435614179 */, 18 },
6630 /* 6213 */ { MAD_F(0x06f8a89e) /* 0.435707681 */, 18 },
6631 /* 6214 */ { MAD_F(0x06f90aaa) /* 0.435801188 */, 18 },
6632 /* 6215 */ { MAD_F(0x06f96cb8) /* 0.435894700 */, 18 },
6633 /* 6216 */ { MAD_F(0x06f9cec8) /* 0.435988217 */, 18 },
6634 /* 6217 */ { MAD_F(0x06fa30d8) /* 0.436081739 */, 18 },
6635 /* 6218 */ { MAD_F(0x06fa92ea) /* 0.436175266 */, 18 },
6636 /* 6219 */ { MAD_F(0x06faf4fe) /* 0.436268799 */, 18 },
6637 /* 6220 */ { MAD_F(0x06fb5712) /* 0.436362336 */, 18 },
6638 /* 6221 */ { MAD_F(0x06fbb928) /* 0.436455878 */, 18 },
6639 /* 6222 */ { MAD_F(0x06fc1b40) /* 0.436549425 */, 18 },
6640 /* 6223 */ { MAD_F(0x06fc7d58) /* 0.436642977 */, 18 },
6641
6642 /* 6224 */ { MAD_F(0x06fcdf72) /* 0.436736534 */, 18 },
6643 /* 6225 */ { MAD_F(0x06fd418e) /* 0.436830096 */, 18 },
6644 /* 6226 */ { MAD_F(0x06fda3ab) /* 0.436923664 */, 18 },
6645 /* 6227 */ { MAD_F(0x06fe05c9) /* 0.437017236 */, 18 },
6646 /* 6228 */ { MAD_F(0x06fe67e8) /* 0.437110813 */, 18 },
6647 /* 6229 */ { MAD_F(0x06feca09) /* 0.437204395 */, 18 },
6648 /* 6230 */ { MAD_F(0x06ff2c2b) /* 0.437297982 */, 18 },
6649 /* 6231 */ { MAD_F(0x06ff8e4f) /* 0.437391575 */, 18 },
6650 /* 6232 */ { MAD_F(0x06fff073) /* 0.437485172 */, 18 },
6651 /* 6233 */ { MAD_F(0x0700529a) /* 0.437578774 */, 18 },
6652 /* 6234 */ { MAD_F(0x0700b4c1) /* 0.437672381 */, 18 },
6653 /* 6235 */ { MAD_F(0x070116ea) /* 0.437765994 */, 18 },
6654 /* 6236 */ { MAD_F(0x07017914) /* 0.437859611 */, 18 },
6655 /* 6237 */ { MAD_F(0x0701db40) /* 0.437953233 */, 18 },
6656 /* 6238 */ { MAD_F(0x07023d6c) /* 0.438046860 */, 18 },
6657 /* 6239 */ { MAD_F(0x07029f9b) /* 0.438140493 */, 18 },
6658
6659 /* 6240 */ { MAD_F(0x070301ca) /* 0.438234130 */, 18 },
6660 /* 6241 */ { MAD_F(0x070363fb) /* 0.438327772 */, 18 },
6661 /* 6242 */ { MAD_F(0x0703c62d) /* 0.438421419 */, 18 },
6662 /* 6243 */ { MAD_F(0x07042861) /* 0.438515072 */, 18 },
6663 /* 6244 */ { MAD_F(0x07048a96) /* 0.438608729 */, 18 },
6664 /* 6245 */ { MAD_F(0x0704eccc) /* 0.438702391 */, 18 },
6665 /* 6246 */ { MAD_F(0x07054f04) /* 0.438796059 */, 18 },
6666 /* 6247 */ { MAD_F(0x0705b13d) /* 0.438889731 */, 18 },
6667 /* 6248 */ { MAD_F(0x07061377) /* 0.438983408 */, 18 },
6668 /* 6249 */ { MAD_F(0x070675b3) /* 0.439077090 */, 18 },
6669 /* 6250 */ { MAD_F(0x0706d7f0) /* 0.439170778 */, 18 },
6670 /* 6251 */ { MAD_F(0x07073a2e) /* 0.439264470 */, 18 },
6671 /* 6252 */ { MAD_F(0x07079c6e) /* 0.439358167 */, 18 },
6672 /* 6253 */ { MAD_F(0x0707feaf) /* 0.439451869 */, 18 },
6673 /* 6254 */ { MAD_F(0x070860f1) /* 0.439545577 */, 18 },
6674 /* 6255 */ { MAD_F(0x0708c335) /* 0.439639289 */, 18 },
6675
6676 /* 6256 */ { MAD_F(0x0709257a) /* 0.439733006 */, 18 },
6677 /* 6257 */ { MAD_F(0x070987c0) /* 0.439826728 */, 18 },
6678 /* 6258 */ { MAD_F(0x0709ea08) /* 0.439920456 */, 18 },
6679 /* 6259 */ { MAD_F(0x070a4c51) /* 0.440014188 */, 18 },
6680 /* 6260 */ { MAD_F(0x070aae9b) /* 0.440107925 */, 18 },
6681 /* 6261 */ { MAD_F(0x070b10e7) /* 0.440201667 */, 18 },
6682 /* 6262 */ { MAD_F(0x070b7334) /* 0.440295414 */, 18 },
6683 /* 6263 */ { MAD_F(0x070bd583) /* 0.440389167 */, 18 },
6684 /* 6264 */ { MAD_F(0x070c37d2) /* 0.440482924 */, 18 },
6685 /* 6265 */ { MAD_F(0x070c9a23) /* 0.440576686 */, 18 },
6686 /* 6266 */ { MAD_F(0x070cfc76) /* 0.440670453 */, 18 },
6687 /* 6267 */ { MAD_F(0x070d5eca) /* 0.440764225 */, 18 },
6688 /* 6268 */ { MAD_F(0x070dc11f) /* 0.440858002 */, 18 },
6689 /* 6269 */ { MAD_F(0x070e2375) /* 0.440951784 */, 18 },
6690 /* 6270 */ { MAD_F(0x070e85cd) /* 0.441045572 */, 18 },
6691 /* 6271 */ { MAD_F(0x070ee826) /* 0.441139364 */, 18 },
6692
6693 /* 6272 */ { MAD_F(0x070f4a80) /* 0.441233161 */, 18 },
6694 /* 6273 */ { MAD_F(0x070facdc) /* 0.441326963 */, 18 },
6695 /* 6274 */ { MAD_F(0x07100f39) /* 0.441420770 */, 18 },
6696 /* 6275 */ { MAD_F(0x07107198) /* 0.441514582 */, 18 },
6697 /* 6276 */ { MAD_F(0x0710d3f8) /* 0.441608399 */, 18 },
6698 /* 6277 */ { MAD_F(0x07113659) /* 0.441702221 */, 18 },
6699 /* 6278 */ { MAD_F(0x071198bb) /* 0.441796048 */, 18 },
6700 /* 6279 */ { MAD_F(0x0711fb1f) /* 0.441889880 */, 18 },
6701 /* 6280 */ { MAD_F(0x07125d84) /* 0.441983717 */, 18 },
6702 /* 6281 */ { MAD_F(0x0712bfeb) /* 0.442077559 */, 18 },
6703 /* 6282 */ { MAD_F(0x07132253) /* 0.442171406 */, 18 },
6704 /* 6283 */ { MAD_F(0x071384bc) /* 0.442265257 */, 18 },
6705 /* 6284 */ { MAD_F(0x0713e726) /* 0.442359114 */, 18 },
6706 /* 6285 */ { MAD_F(0x07144992) /* 0.442452976 */, 18 },
6707 /* 6286 */ { MAD_F(0x0714abff) /* 0.442546843 */, 18 },
6708 /* 6287 */ { MAD_F(0x07150e6e) /* 0.442640715 */, 18 },
6709
6710 /* 6288 */ { MAD_F(0x071570de) /* 0.442734592 */, 18 },
6711 /* 6289 */ { MAD_F(0x0715d34f) /* 0.442828473 */, 18 },
6712 /* 6290 */ { MAD_F(0x071635c1) /* 0.442922360 */, 18 },
6713 /* 6291 */ { MAD_F(0x07169835) /* 0.443016252 */, 18 },
6714 /* 6292 */ { MAD_F(0x0716faaa) /* 0.443110148 */, 18 },
6715 /* 6293 */ { MAD_F(0x07175d21) /* 0.443204050 */, 18 },
6716 /* 6294 */ { MAD_F(0x0717bf99) /* 0.443297957 */, 18 },
6717 /* 6295 */ { MAD_F(0x07182212) /* 0.443391868 */, 18 },
6718 /* 6296 */ { MAD_F(0x0718848d) /* 0.443485785 */, 18 },
6719 /* 6297 */ { MAD_F(0x0718e709) /* 0.443579706 */, 18 },
6720 /* 6298 */ { MAD_F(0x07194986) /* 0.443673633 */, 18 },
6721 /* 6299 */ { MAD_F(0x0719ac04) /* 0.443767564 */, 18 },
6722 /* 6300 */ { MAD_F(0x071a0e84) /* 0.443861501 */, 18 },
6723 /* 6301 */ { MAD_F(0x071a7105) /* 0.443955442 */, 18 },
6724 /* 6302 */ { MAD_F(0x071ad388) /* 0.444049389 */, 18 },
6725 /* 6303 */ { MAD_F(0x071b360c) /* 0.444143340 */, 18 },
6726
6727 /* 6304 */ { MAD_F(0x071b9891) /* 0.444237296 */, 18 },
6728 /* 6305 */ { MAD_F(0x071bfb18) /* 0.444331258 */, 18 },
6729 /* 6306 */ { MAD_F(0x071c5d9f) /* 0.444425224 */, 18 },
6730 /* 6307 */ { MAD_F(0x071cc029) /* 0.444519195 */, 18 },
6731 /* 6308 */ { MAD_F(0x071d22b3) /* 0.444613171 */, 18 },
6732 /* 6309 */ { MAD_F(0x071d853f) /* 0.444707153 */, 18 },
6733 /* 6310 */ { MAD_F(0x071de7cc) /* 0.444801139 */, 18 },
6734 /* 6311 */ { MAD_F(0x071e4a5b) /* 0.444895130 */, 18 },
6735 /* 6312 */ { MAD_F(0x071eaceb) /* 0.444989126 */, 18 },
6736 /* 6313 */ { MAD_F(0x071f0f7c) /* 0.445083127 */, 18 },
6737 /* 6314 */ { MAD_F(0x071f720e) /* 0.445177133 */, 18 },
6738 /* 6315 */ { MAD_F(0x071fd4a2) /* 0.445271144 */, 18 },
6739 /* 6316 */ { MAD_F(0x07203737) /* 0.445365160 */, 18 },
6740 /* 6317 */ { MAD_F(0x072099ce) /* 0.445459181 */, 18 },
6741 /* 6318 */ { MAD_F(0x0720fc66) /* 0.445553206 */, 18 },
6742 /* 6319 */ { MAD_F(0x07215eff) /* 0.445647237 */, 18 },
6743
6744 /* 6320 */ { MAD_F(0x0721c19a) /* 0.445741273 */, 18 },
6745 /* 6321 */ { MAD_F(0x07222436) /* 0.445835314 */, 18 },
6746 /* 6322 */ { MAD_F(0x072286d3) /* 0.445929359 */, 18 },
6747 /* 6323 */ { MAD_F(0x0722e971) /* 0.446023410 */, 18 },
6748 /* 6324 */ { MAD_F(0x07234c11) /* 0.446117466 */, 18 },
6749 /* 6325 */ { MAD_F(0x0723aeb2) /* 0.446211526 */, 18 },
6750 /* 6326 */ { MAD_F(0x07241155) /* 0.446305592 */, 18 },
6751 /* 6327 */ { MAD_F(0x072473f9) /* 0.446399662 */, 18 },
6752 /* 6328 */ { MAD_F(0x0724d69e) /* 0.446493738 */, 18 },
6753 /* 6329 */ { MAD_F(0x07253944) /* 0.446587818 */, 18 },
6754 /* 6330 */ { MAD_F(0x07259bec) /* 0.446681903 */, 18 },
6755 /* 6331 */ { MAD_F(0x0725fe95) /* 0.446775994 */, 18 },
6756 /* 6332 */ { MAD_F(0x07266140) /* 0.446870089 */, 18 },
6757 /* 6333 */ { MAD_F(0x0726c3ec) /* 0.446964189 */, 18 },
6758 /* 6334 */ { MAD_F(0x07272699) /* 0.447058294 */, 18 },
6759 /* 6335 */ { MAD_F(0x07278947) /* 0.447152404 */, 18 },
6760
6761 /* 6336 */ { MAD_F(0x0727ebf7) /* 0.447246519 */, 18 },
6762 /* 6337 */ { MAD_F(0x07284ea8) /* 0.447340639 */, 18 },
6763 /* 6338 */ { MAD_F(0x0728b15b) /* 0.447434764 */, 18 },
6764 /* 6339 */ { MAD_F(0x0729140f) /* 0.447528894 */, 18 },
6765 /* 6340 */ { MAD_F(0x072976c4) /* 0.447623029 */, 18 },
6766 /* 6341 */ { MAD_F(0x0729d97a) /* 0.447717169 */, 18 },
6767 /* 6342 */ { MAD_F(0x072a3c32) /* 0.447811314 */, 18 },
6768 /* 6343 */ { MAD_F(0x072a9eeb) /* 0.447905463 */, 18 },
6769 /* 6344 */ { MAD_F(0x072b01a6) /* 0.447999618 */, 18 },
6770 /* 6345 */ { MAD_F(0x072b6461) /* 0.448093778 */, 18 },
6771 /* 6346 */ { MAD_F(0x072bc71e) /* 0.448187942 */, 18 },
6772 /* 6347 */ { MAD_F(0x072c29dd) /* 0.448282112 */, 18 },
6773 /* 6348 */ { MAD_F(0x072c8c9d) /* 0.448376286 */, 18 },
6774 /* 6349 */ { MAD_F(0x072cef5e) /* 0.448470466 */, 18 },
6775 /* 6350 */ { MAD_F(0x072d5220) /* 0.448564650 */, 18 },
6776 /* 6351 */ { MAD_F(0x072db4e4) /* 0.448658839 */, 18 },
6777
6778 /* 6352 */ { MAD_F(0x072e17a9) /* 0.448753033 */, 18 },
6779 /* 6353 */ { MAD_F(0x072e7a6f) /* 0.448847233 */, 18 },
6780 /* 6354 */ { MAD_F(0x072edd37) /* 0.448941437 */, 18 },
6781 /* 6355 */ { MAD_F(0x072f4000) /* 0.449035646 */, 18 },
6782 /* 6356 */ { MAD_F(0x072fa2ca) /* 0.449129860 */, 18 },
6783 /* 6357 */ { MAD_F(0x07300596) /* 0.449224079 */, 18 },
6784 /* 6358 */ { MAD_F(0x07306863) /* 0.449318303 */, 18 },
6785 /* 6359 */ { MAD_F(0x0730cb32) /* 0.449412531 */, 18 },
6786 /* 6360 */ { MAD_F(0x07312e01) /* 0.449506765 */, 18 },
6787 /* 6361 */ { MAD_F(0x073190d2) /* 0.449601004 */, 18 },
6788 /* 6362 */ { MAD_F(0x0731f3a5) /* 0.449695247 */, 18 },
6789 /* 6363 */ { MAD_F(0x07325678) /* 0.449789496 */, 18 },
6790 /* 6364 */ { MAD_F(0x0732b94d) /* 0.449883749 */, 18 },
6791 /* 6365 */ { MAD_F(0x07331c23) /* 0.449978008 */, 18 },
6792 /* 6366 */ { MAD_F(0x07337efb) /* 0.450072271 */, 18 },
6793 /* 6367 */ { MAD_F(0x0733e1d4) /* 0.450166540 */, 18 },
6794
6795 /* 6368 */ { MAD_F(0x073444ae) /* 0.450260813 */, 18 },
6796 /* 6369 */ { MAD_F(0x0734a78a) /* 0.450355091 */, 18 },
6797 /* 6370 */ { MAD_F(0x07350a67) /* 0.450449374 */, 18 },
6798 /* 6371 */ { MAD_F(0x07356d45) /* 0.450543662 */, 18 },
6799 /* 6372 */ { MAD_F(0x0735d025) /* 0.450637955 */, 18 },
6800 /* 6373 */ { MAD_F(0x07363306) /* 0.450732253 */, 18 },
6801 /* 6374 */ { MAD_F(0x073695e8) /* 0.450826556 */, 18 },
6802 /* 6375 */ { MAD_F(0x0736f8cb) /* 0.450920864 */, 18 },
6803 /* 6376 */ { MAD_F(0x07375bb0) /* 0.451015176 */, 18 },
6804 /* 6377 */ { MAD_F(0x0737be96) /* 0.451109494 */, 18 },
6805 /* 6378 */ { MAD_F(0x0738217e) /* 0.451203817 */, 18 },
6806 /* 6379 */ { MAD_F(0x07388467) /* 0.451298144 */, 18 },
6807 /* 6380 */ { MAD_F(0x0738e751) /* 0.451392477 */, 18 },
6808 /* 6381 */ { MAD_F(0x07394a3d) /* 0.451486814 */, 18 },
6809 /* 6382 */ { MAD_F(0x0739ad29) /* 0.451581156 */, 18 },
6810 /* 6383 */ { MAD_F(0x073a1017) /* 0.451675503 */, 18 },
6811
6812 /* 6384 */ { MAD_F(0x073a7307) /* 0.451769856 */, 18 },
6813 /* 6385 */ { MAD_F(0x073ad5f8) /* 0.451864213 */, 18 },
6814 /* 6386 */ { MAD_F(0x073b38ea) /* 0.451958575 */, 18 },
6815 /* 6387 */ { MAD_F(0x073b9bdd) /* 0.452052942 */, 18 },
6816 /* 6388 */ { MAD_F(0x073bfed2) /* 0.452147313 */, 18 },
6817 /* 6389 */ { MAD_F(0x073c61c8) /* 0.452241690 */, 18 },
6818 /* 6390 */ { MAD_F(0x073cc4bf) /* 0.452336072 */, 18 },
6819 /* 6391 */ { MAD_F(0x073d27b8) /* 0.452430458 */, 18 },
6820 /* 6392 */ { MAD_F(0x073d8ab2) /* 0.452524850 */, 18 },
6821 /* 6393 */ { MAD_F(0x073dedae) /* 0.452619246 */, 18 },
6822 /* 6394 */ { MAD_F(0x073e50aa) /* 0.452713648 */, 18 },
6823 /* 6395 */ { MAD_F(0x073eb3a8) /* 0.452808054 */, 18 },
6824 /* 6396 */ { MAD_F(0x073f16a8) /* 0.452902465 */, 18 },
6825 /* 6397 */ { MAD_F(0x073f79a8) /* 0.452996882 */, 18 },
6826 /* 6398 */ { MAD_F(0x073fdcaa) /* 0.453091303 */, 18 },
6827 /* 6399 */ { MAD_F(0x07403fad) /* 0.453185729 */, 18 },
6828
6829 /* 6400 */ { MAD_F(0x0740a2b2) /* 0.453280160 */, 18 },
6830 /* 6401 */ { MAD_F(0x074105b8) /* 0.453374595 */, 18 },
6831 /* 6402 */ { MAD_F(0x074168bf) /* 0.453469036 */, 18 },
6832 /* 6403 */ { MAD_F(0x0741cbc8) /* 0.453563482 */, 18 },
6833 /* 6404 */ { MAD_F(0x07422ed2) /* 0.453657932 */, 18 },
6834 /* 6405 */ { MAD_F(0x074291dd) /* 0.453752388 */, 18 },
6835 /* 6406 */ { MAD_F(0x0742f4e9) /* 0.453846848 */, 18 },
6836 /* 6407 */ { MAD_F(0x074357f7) /* 0.453941314 */, 18 },
6837 /* 6408 */ { MAD_F(0x0743bb06) /* 0.454035784 */, 18 },
6838 /* 6409 */ { MAD_F(0x07441e17) /* 0.454130259 */, 18 },
6839 /* 6410 */ { MAD_F(0x07448129) /* 0.454224739 */, 18 },
6840 /* 6411 */ { MAD_F(0x0744e43c) /* 0.454319224 */, 18 },
6841 /* 6412 */ { MAD_F(0x07454750) /* 0.454413714 */, 18 },
6842 /* 6413 */ { MAD_F(0x0745aa66) /* 0.454508209 */, 18 },
6843 /* 6414 */ { MAD_F(0x07460d7d) /* 0.454602708 */, 18 },
6844 /* 6415 */ { MAD_F(0x07467095) /* 0.454697213 */, 18 },
6845
6846 /* 6416 */ { MAD_F(0x0746d3af) /* 0.454791723 */, 18 },
6847 /* 6417 */ { MAD_F(0x074736ca) /* 0.454886237 */, 18 },
6848 /* 6418 */ { MAD_F(0x074799e7) /* 0.454980756 */, 18 },
6849 /* 6419 */ { MAD_F(0x0747fd04) /* 0.455075281 */, 18 },
6850 /* 6420 */ { MAD_F(0x07486023) /* 0.455169810 */, 18 },
6851 /* 6421 */ { MAD_F(0x0748c344) /* 0.455264344 */, 18 },
6852 /* 6422 */ { MAD_F(0x07492665) /* 0.455358883 */, 18 },
6853 /* 6423 */ { MAD_F(0x07498988) /* 0.455453427 */, 18 },
6854 /* 6424 */ { MAD_F(0x0749ecac) /* 0.455547976 */, 18 },
6855 /* 6425 */ { MAD_F(0x074a4fd2) /* 0.455642529 */, 18 },
6856 /* 6426 */ { MAD_F(0x074ab2f9) /* 0.455737088 */, 18 },
6857 /* 6427 */ { MAD_F(0x074b1621) /* 0.455831652 */, 18 },
6858 /* 6428 */ { MAD_F(0x074b794b) /* 0.455926220 */, 18 },
6859 /* 6429 */ { MAD_F(0x074bdc75) /* 0.456020793 */, 18 },
6860 /* 6430 */ { MAD_F(0x074c3fa1) /* 0.456115372 */, 18 },
6861 /* 6431 */ { MAD_F(0x074ca2cf) /* 0.456209955 */, 18 },
6862
6863 /* 6432 */ { MAD_F(0x074d05fe) /* 0.456304543 */, 18 },
6864 /* 6433 */ { MAD_F(0x074d692e) /* 0.456399136 */, 18 },
6865 /* 6434 */ { MAD_F(0x074dcc5f) /* 0.456493733 */, 18 },
6866 /* 6435 */ { MAD_F(0x074e2f92) /* 0.456588336 */, 18 },
6867 /* 6436 */ { MAD_F(0x074e92c6) /* 0.456682944 */, 18 },
6868 /* 6437 */ { MAD_F(0x074ef5fb) /* 0.456777556 */, 18 },
6869 /* 6438 */ { MAD_F(0x074f5932) /* 0.456872174 */, 18 },
6870 /* 6439 */ { MAD_F(0x074fbc6a) /* 0.456966796 */, 18 },
6871 /* 6440 */ { MAD_F(0x07501fa3) /* 0.457061423 */, 18 },
6872 /* 6441 */ { MAD_F(0x075082de) /* 0.457156056 */, 18 },
6873 /* 6442 */ { MAD_F(0x0750e61a) /* 0.457250693 */, 18 },
6874 /* 6443 */ { MAD_F(0x07514957) /* 0.457345335 */, 18 },
6875 /* 6444 */ { MAD_F(0x0751ac96) /* 0.457439981 */, 18 },
6876 /* 6445 */ { MAD_F(0x07520fd6) /* 0.457534633 */, 18 },
6877 /* 6446 */ { MAD_F(0x07527317) /* 0.457629290 */, 18 },
6878 /* 6447 */ { MAD_F(0x0752d659) /* 0.457723951 */, 18 },
6879
6880 /* 6448 */ { MAD_F(0x0753399d) /* 0.457818618 */, 18 },
6881 /* 6449 */ { MAD_F(0x07539ce2) /* 0.457913289 */, 18 },
6882 /* 6450 */ { MAD_F(0x07540029) /* 0.458007965 */, 18 },
6883 /* 6451 */ { MAD_F(0x07546371) /* 0.458102646 */, 18 },
6884 /* 6452 */ { MAD_F(0x0754c6ba) /* 0.458197332 */, 18 },
6885 /* 6453 */ { MAD_F(0x07552a04) /* 0.458292023 */, 18 },
6886 /* 6454 */ { MAD_F(0x07558d50) /* 0.458386719 */, 18 },
6887 /* 6455 */ { MAD_F(0x0755f09d) /* 0.458481420 */, 18 },
6888 /* 6456 */ { MAD_F(0x075653eb) /* 0.458576125 */, 18 },
6889 /* 6457 */ { MAD_F(0x0756b73b) /* 0.458670836 */, 18 },
6890 /* 6458 */ { MAD_F(0x07571a8c) /* 0.458765551 */, 18 },
6891 /* 6459 */ { MAD_F(0x07577dde) /* 0.458860271 */, 18 },
6892 /* 6460 */ { MAD_F(0x0757e131) /* 0.458954996 */, 18 },
6893 /* 6461 */ { MAD_F(0x07584486) /* 0.459049726 */, 18 },
6894 /* 6462 */ { MAD_F(0x0758a7dd) /* 0.459144461 */, 18 },
6895 /* 6463 */ { MAD_F(0x07590b34) /* 0.459239201 */, 18 },
6896
6897 /* 6464 */ { MAD_F(0x07596e8d) /* 0.459333946 */, 18 },
6898 /* 6465 */ { MAD_F(0x0759d1e7) /* 0.459428695 */, 18 },
6899 /* 6466 */ { MAD_F(0x075a3542) /* 0.459523450 */, 18 },
6900 /* 6467 */ { MAD_F(0x075a989f) /* 0.459618209 */, 18 },
6901 /* 6468 */ { MAD_F(0x075afbfd) /* 0.459712973 */, 18 },
6902 /* 6469 */ { MAD_F(0x075b5f5d) /* 0.459807742 */, 18 },
6903 /* 6470 */ { MAD_F(0x075bc2bd) /* 0.459902516 */, 18 },
6904 /* 6471 */ { MAD_F(0x075c261f) /* 0.459997295 */, 18 },
6905 /* 6472 */ { MAD_F(0x075c8983) /* 0.460092079 */, 18 },
6906 /* 6473 */ { MAD_F(0x075cece7) /* 0.460186867 */, 18 },
6907 /* 6474 */ { MAD_F(0x075d504d) /* 0.460281661 */, 18 },
6908 /* 6475 */ { MAD_F(0x075db3b5) /* 0.460376459 */, 18 },
6909 /* 6476 */ { MAD_F(0x075e171d) /* 0.460471262 */, 18 },
6910 /* 6477 */ { MAD_F(0x075e7a87) /* 0.460566071 */, 18 },
6911 /* 6478 */ { MAD_F(0x075eddf2) /* 0.460660884 */, 18 },
6912 /* 6479 */ { MAD_F(0x075f415f) /* 0.460755701 */, 18 },
6913
6914 /* 6480 */ { MAD_F(0x075fa4cc) /* 0.460850524 */, 18 },
6915 /* 6481 */ { MAD_F(0x0760083b) /* 0.460945352 */, 18 },
6916 /* 6482 */ { MAD_F(0x07606bac) /* 0.461040184 */, 18 },
6917 /* 6483 */ { MAD_F(0x0760cf1e) /* 0.461135022 */, 18 },
6918 /* 6484 */ { MAD_F(0x07613291) /* 0.461229864 */, 18 },
6919 /* 6485 */ { MAD_F(0x07619605) /* 0.461324711 */, 18 },
6920 /* 6486 */ { MAD_F(0x0761f97b) /* 0.461419563 */, 18 },
6921 /* 6487 */ { MAD_F(0x07625cf2) /* 0.461514420 */, 18 },
6922 /* 6488 */ { MAD_F(0x0762c06a) /* 0.461609282 */, 18 },
6923 /* 6489 */ { MAD_F(0x076323e3) /* 0.461704149 */, 18 },
6924 /* 6490 */ { MAD_F(0x0763875e) /* 0.461799020 */, 18 },
6925 /* 6491 */ { MAD_F(0x0763eadb) /* 0.461893897 */, 18 },
6926 /* 6492 */ { MAD_F(0x07644e58) /* 0.461988778 */, 18 },
6927 /* 6493 */ { MAD_F(0x0764b1d7) /* 0.462083664 */, 18 },
6928 /* 6494 */ { MAD_F(0x07651557) /* 0.462178555 */, 18 },
6929 /* 6495 */ { MAD_F(0x076578d8) /* 0.462273451 */, 18 },
6930
6931 /* 6496 */ { MAD_F(0x0765dc5b) /* 0.462368352 */, 18 },
6932 /* 6497 */ { MAD_F(0x07663fdf) /* 0.462463257 */, 18 },
6933 /* 6498 */ { MAD_F(0x0766a364) /* 0.462558168 */, 18 },
6934 /* 6499 */ { MAD_F(0x076706eb) /* 0.462653083 */, 18 },
6935 /* 6500 */ { MAD_F(0x07676a73) /* 0.462748003 */, 18 },
6936 /* 6501 */ { MAD_F(0x0767cdfc) /* 0.462842928 */, 18 },
6937 /* 6502 */ { MAD_F(0x07683187) /* 0.462937858 */, 18 },
6938 /* 6503 */ { MAD_F(0x07689513) /* 0.463032793 */, 18 },
6939 /* 6504 */ { MAD_F(0x0768f8a0) /* 0.463127733 */, 18 },
6940 /* 6505 */ { MAD_F(0x07695c2e) /* 0.463222678 */, 18 },
6941 /* 6506 */ { MAD_F(0x0769bfbe) /* 0.463317627 */, 18 },
6942 /* 6507 */ { MAD_F(0x076a234f) /* 0.463412581 */, 18 },
6943 /* 6508 */ { MAD_F(0x076a86e2) /* 0.463507540 */, 18 },
6944 /* 6509 */ { MAD_F(0x076aea75) /* 0.463602504 */, 18 },
6945 /* 6510 */ { MAD_F(0x076b4e0a) /* 0.463697473 */, 18 },
6946 /* 6511 */ { MAD_F(0x076bb1a1) /* 0.463792447 */, 18 },
6947
6948 /* 6512 */ { MAD_F(0x076c1538) /* 0.463887426 */, 18 },
6949 /* 6513 */ { MAD_F(0x076c78d1) /* 0.463982409 */, 18 },
6950 /* 6514 */ { MAD_F(0x076cdc6c) /* 0.464077398 */, 18 },
6951 /* 6515 */ { MAD_F(0x076d4007) /* 0.464172391 */, 18 },
6952 /* 6516 */ { MAD_F(0x076da3a4) /* 0.464267389 */, 18 },
6953 /* 6517 */ { MAD_F(0x076e0742) /* 0.464362392 */, 18 },
6954 /* 6518 */ { MAD_F(0x076e6ae2) /* 0.464457399 */, 18 },
6955 /* 6519 */ { MAD_F(0x076ece82) /* 0.464552412 */, 18 },
6956 /* 6520 */ { MAD_F(0x076f3224) /* 0.464647430 */, 18 },
6957 /* 6521 */ { MAD_F(0x076f95c8) /* 0.464742452 */, 18 },
6958 /* 6522 */ { MAD_F(0x076ff96c) /* 0.464837479 */, 18 },
6959 /* 6523 */ { MAD_F(0x07705d12) /* 0.464932511 */, 18 },
6960 /* 6524 */ { MAD_F(0x0770c0ba) /* 0.465027548 */, 18 },
6961 /* 6525 */ { MAD_F(0x07712462) /* 0.465122590 */, 18 },
6962 /* 6526 */ { MAD_F(0x0771880c) /* 0.465217637 */, 18 },
6963 /* 6527 */ { MAD_F(0x0771ebb7) /* 0.465312688 */, 18 },
6964
6965 /* 6528 */ { MAD_F(0x07724f64) /* 0.465407744 */, 18 },
6966 /* 6529 */ { MAD_F(0x0772b312) /* 0.465502806 */, 18 },
6967 /* 6530 */ { MAD_F(0x077316c1) /* 0.465597872 */, 18 },
6968 /* 6531 */ { MAD_F(0x07737a71) /* 0.465692943 */, 18 },
6969 /* 6532 */ { MAD_F(0x0773de23) /* 0.465788018 */, 18 },
6970 /* 6533 */ { MAD_F(0x077441d6) /* 0.465883099 */, 18 },
6971 /* 6534 */ { MAD_F(0x0774a58a) /* 0.465978184 */, 18 },
6972 /* 6535 */ { MAD_F(0x07750940) /* 0.466073275 */, 18 },
6973 /* 6536 */ { MAD_F(0x07756cf7) /* 0.466168370 */, 18 },
6974 /* 6537 */ { MAD_F(0x0775d0af) /* 0.466263470 */, 18 },
6975 /* 6538 */ { MAD_F(0x07763468) /* 0.466358575 */, 18 },
6976 /* 6539 */ { MAD_F(0x07769823) /* 0.466453684 */, 18 },
6977 /* 6540 */ { MAD_F(0x0776fbdf) /* 0.466548799 */, 18 },
6978 /* 6541 */ { MAD_F(0x07775f9d) /* 0.466643918 */, 18 },
6979 /* 6542 */ { MAD_F(0x0777c35c) /* 0.466739043 */, 18 },
6980 /* 6543 */ { MAD_F(0x0778271c) /* 0.466834172 */, 18 },
6981
6982 /* 6544 */ { MAD_F(0x07788add) /* 0.466929306 */, 18 },
6983 /* 6545 */ { MAD_F(0x0778ee9f) /* 0.467024445 */, 18 },
6984 /* 6546 */ { MAD_F(0x07795263) /* 0.467119588 */, 18 },
6985 /* 6547 */ { MAD_F(0x0779b629) /* 0.467214737 */, 18 },
6986 /* 6548 */ { MAD_F(0x077a19ef) /* 0.467309890 */, 18 },
6987 /* 6549 */ { MAD_F(0x077a7db7) /* 0.467405048 */, 18 },
6988 /* 6550 */ { MAD_F(0x077ae180) /* 0.467500211 */, 18 },
6989 /* 6551 */ { MAD_F(0x077b454b) /* 0.467595379 */, 18 },
6990 /* 6552 */ { MAD_F(0x077ba916) /* 0.467690552 */, 18 },
6991 /* 6553 */ { MAD_F(0x077c0ce3) /* 0.467785729 */, 18 },
6992 /* 6554 */ { MAD_F(0x077c70b2) /* 0.467880912 */, 18 },
6993 /* 6555 */ { MAD_F(0x077cd481) /* 0.467976099 */, 18 },
6994 /* 6556 */ { MAD_F(0x077d3852) /* 0.468071291 */, 18 },
6995 /* 6557 */ { MAD_F(0x077d9c24) /* 0.468166488 */, 18 },
6996 /* 6558 */ { MAD_F(0x077dfff8) /* 0.468261690 */, 18 },
6997 /* 6559 */ { MAD_F(0x077e63cd) /* 0.468356896 */, 18 },
6998
6999 /* 6560 */ { MAD_F(0x077ec7a3) /* 0.468452108 */, 18 },
7000 /* 6561 */ { MAD_F(0x077f2b7a) /* 0.468547324 */, 18 },
7001 /* 6562 */ { MAD_F(0x077f8f53) /* 0.468642545 */, 18 },
7002 /* 6563 */ { MAD_F(0x077ff32d) /* 0.468737771 */, 18 },
7003 /* 6564 */ { MAD_F(0x07805708) /* 0.468833002 */, 18 },
7004 /* 6565 */ { MAD_F(0x0780bae5) /* 0.468928237 */, 18 },
7005 /* 6566 */ { MAD_F(0x07811ec3) /* 0.469023478 */, 18 },
7006 /* 6567 */ { MAD_F(0x078182a2) /* 0.469118723 */, 18 },
7007 /* 6568 */ { MAD_F(0x0781e683) /* 0.469213973 */, 18 },
7008 /* 6569 */ { MAD_F(0x07824a64) /* 0.469309228 */, 18 },
7009 /* 6570 */ { MAD_F(0x0782ae47) /* 0.469404488 */, 18 },
7010 /* 6571 */ { MAD_F(0x0783122c) /* 0.469499752 */, 18 },
7011 /* 6572 */ { MAD_F(0x07837612) /* 0.469595022 */, 18 },
7012 /* 6573 */ { MAD_F(0x0783d9f9) /* 0.469690296 */, 18 },
7013 /* 6574 */ { MAD_F(0x07843de1) /* 0.469785575 */, 18 },
7014 /* 6575 */ { MAD_F(0x0784a1ca) /* 0.469880859 */, 18 },
7015
7016 /* 6576 */ { MAD_F(0x078505b5) /* 0.469976148 */, 18 },
7017 /* 6577 */ { MAD_F(0x078569a2) /* 0.470071442 */, 18 },
7018 /* 6578 */ { MAD_F(0x0785cd8f) /* 0.470166740 */, 18 },
7019 /* 6579 */ { MAD_F(0x0786317e) /* 0.470262043 */, 18 },
7020 /* 6580 */ { MAD_F(0x0786956e) /* 0.470357351 */, 18 },
7021 /* 6581 */ { MAD_F(0x0786f95f) /* 0.470452664 */, 18 },
7022 /* 6582 */ { MAD_F(0x07875d52) /* 0.470547982 */, 18 },
7023 /* 6583 */ { MAD_F(0x0787c146) /* 0.470643305 */, 18 },
7024 /* 6584 */ { MAD_F(0x0788253b) /* 0.470738632 */, 18 },
7025 /* 6585 */ { MAD_F(0x07888932) /* 0.470833964 */, 18 },
7026 /* 6586 */ { MAD_F(0x0788ed2a) /* 0.470929301 */, 18 },
7027 /* 6587 */ { MAD_F(0x07895123) /* 0.471024643 */, 18 },
7028 /* 6588 */ { MAD_F(0x0789b51d) /* 0.471119990 */, 18 },
7029 /* 6589 */ { MAD_F(0x078a1919) /* 0.471215341 */, 18 },
7030 /* 6590 */ { MAD_F(0x078a7d16) /* 0.471310698 */, 18 },
7031 /* 6591 */ { MAD_F(0x078ae114) /* 0.471406059 */, 18 },
7032
7033 /* 6592 */ { MAD_F(0x078b4514) /* 0.471501425 */, 18 },
7034 /* 6593 */ { MAD_F(0x078ba915) /* 0.471596796 */, 18 },
7035 /* 6594 */ { MAD_F(0x078c0d17) /* 0.471692171 */, 18 },
7036 /* 6595 */ { MAD_F(0x078c711a) /* 0.471787552 */, 18 },
7037 /* 6596 */ { MAD_F(0x078cd51f) /* 0.471882937 */, 18 },
7038 /* 6597 */ { MAD_F(0x078d3925) /* 0.471978327 */, 18 },
7039 /* 6598 */ { MAD_F(0x078d9d2d) /* 0.472073722 */, 18 },
7040 /* 6599 */ { MAD_F(0x078e0135) /* 0.472169122 */, 18 },
7041 /* 6600 */ { MAD_F(0x078e653f) /* 0.472264527 */, 18 },
7042 /* 6601 */ { MAD_F(0x078ec94b) /* 0.472359936 */, 18 },
7043 /* 6602 */ { MAD_F(0x078f2d57) /* 0.472455350 */, 18 },
7044 /* 6603 */ { MAD_F(0x078f9165) /* 0.472550769 */, 18 },
7045 /* 6604 */ { MAD_F(0x078ff574) /* 0.472646193 */, 18 },
7046 /* 6605 */ { MAD_F(0x07905985) /* 0.472741622 */, 18 },
7047 /* 6606 */ { MAD_F(0x0790bd96) /* 0.472837055 */, 18 },
7048 /* 6607 */ { MAD_F(0x079121a9) /* 0.472932493 */, 18 },
7049
7050 /* 6608 */ { MAD_F(0x079185be) /* 0.473027937 */, 18 },
7051 /* 6609 */ { MAD_F(0x0791e9d3) /* 0.473123384 */, 18 },
7052 /* 6610 */ { MAD_F(0x07924dea) /* 0.473218837 */, 18 },
7053 /* 6611 */ { MAD_F(0x0792b202) /* 0.473314295 */, 18 },
7054 /* 6612 */ { MAD_F(0x0793161c) /* 0.473409757 */, 18 },
7055 /* 6613 */ { MAD_F(0x07937a37) /* 0.473505224 */, 18 },
7056 /* 6614 */ { MAD_F(0x0793de53) /* 0.473600696 */, 18 },
7057 /* 6615 */ { MAD_F(0x07944270) /* 0.473696173 */, 18 },
7058 /* 6616 */ { MAD_F(0x0794a68f) /* 0.473791655 */, 18 },
7059 /* 6617 */ { MAD_F(0x07950aaf) /* 0.473887141 */, 18 },
7060 /* 6618 */ { MAD_F(0x07956ed0) /* 0.473982632 */, 18 },
7061 /* 6619 */ { MAD_F(0x0795d2f2) /* 0.474078128 */, 18 },
7062 /* 6620 */ { MAD_F(0x07963716) /* 0.474173629 */, 18 },
7063 /* 6621 */ { MAD_F(0x07969b3b) /* 0.474269135 */, 18 },
7064 /* 6622 */ { MAD_F(0x0796ff62) /* 0.474364645 */, 18 },
7065 /* 6623 */ { MAD_F(0x07976389) /* 0.474460161 */, 18 },
7066
7067 /* 6624 */ { MAD_F(0x0797c7b2) /* 0.474555681 */, 18 },
7068 /* 6625 */ { MAD_F(0x07982bdd) /* 0.474651205 */, 18 },
7069 /* 6626 */ { MAD_F(0x07989008) /* 0.474746735 */, 18 },
7070 /* 6627 */ { MAD_F(0x0798f435) /* 0.474842270 */, 18 },
7071 /* 6628 */ { MAD_F(0x07995863) /* 0.474937809 */, 18 },
7072 /* 6629 */ { MAD_F(0x0799bc92) /* 0.475033353 */, 18 },
7073 /* 6630 */ { MAD_F(0x079a20c3) /* 0.475128902 */, 18 },
7074 /* 6631 */ { MAD_F(0x079a84f5) /* 0.475224456 */, 18 },
7075 /* 6632 */ { MAD_F(0x079ae929) /* 0.475320014 */, 18 },
7076 /* 6633 */ { MAD_F(0x079b4d5d) /* 0.475415578 */, 18 },
7077 /* 6634 */ { MAD_F(0x079bb193) /* 0.475511146 */, 18 },
7078 /* 6635 */ { MAD_F(0x079c15ca) /* 0.475606719 */, 18 },
7079 /* 6636 */ { MAD_F(0x079c7a03) /* 0.475702296 */, 18 },
7080 /* 6637 */ { MAD_F(0x079cde3c) /* 0.475797879 */, 18 },
7081 /* 6638 */ { MAD_F(0x079d4277) /* 0.475893466 */, 18 },
7082 /* 6639 */ { MAD_F(0x079da6b4) /* 0.475989058 */, 18 },
7083
7084 /* 6640 */ { MAD_F(0x079e0af1) /* 0.476084655 */, 18 },
7085 /* 6641 */ { MAD_F(0x079e6f30) /* 0.476180257 */, 18 },
7086 /* 6642 */ { MAD_F(0x079ed370) /* 0.476275863 */, 18 },
7087 /* 6643 */ { MAD_F(0x079f37b2) /* 0.476371475 */, 18 },
7088 /* 6644 */ { MAD_F(0x079f9bf5) /* 0.476467091 */, 18 },
7089 /* 6645 */ { MAD_F(0x07a00039) /* 0.476562712 */, 18 },
7090 /* 6646 */ { MAD_F(0x07a0647e) /* 0.476658338 */, 18 },
7091 /* 6647 */ { MAD_F(0x07a0c8c5) /* 0.476753968 */, 18 },
7092 /* 6648 */ { MAD_F(0x07a12d0c) /* 0.476849603 */, 18 },
7093 /* 6649 */ { MAD_F(0x07a19156) /* 0.476945243 */, 18 },
7094 /* 6650 */ { MAD_F(0x07a1f5a0) /* 0.477040888 */, 18 },
7095 /* 6651 */ { MAD_F(0x07a259ec) /* 0.477136538 */, 18 },
7096 /* 6652 */ { MAD_F(0x07a2be39) /* 0.477232193 */, 18 },
7097 /* 6653 */ { MAD_F(0x07a32287) /* 0.477327852 */, 18 },
7098 /* 6654 */ { MAD_F(0x07a386d7) /* 0.477423516 */, 18 },
7099 /* 6655 */ { MAD_F(0x07a3eb28) /* 0.477519185 */, 18 },
7100
7101 /* 6656 */ { MAD_F(0x07a44f7a) /* 0.477614858 */, 18 },
7102 /* 6657 */ { MAD_F(0x07a4b3ce) /* 0.477710537 */, 18 },
7103 /* 6658 */ { MAD_F(0x07a51822) /* 0.477806220 */, 18 },
7104 /* 6659 */ { MAD_F(0x07a57c78) /* 0.477901908 */, 18 },
7105 /* 6660 */ { MAD_F(0x07a5e0d0) /* 0.477997601 */, 18 },
7106 /* 6661 */ { MAD_F(0x07a64528) /* 0.478093299 */, 18 },
7107 /* 6662 */ { MAD_F(0x07a6a982) /* 0.478189001 */, 18 },
7108 /* 6663 */ { MAD_F(0x07a70ddd) /* 0.478284708 */, 18 },
7109 /* 6664 */ { MAD_F(0x07a7723a) /* 0.478380420 */, 18 },
7110 /* 6665 */ { MAD_F(0x07a7d698) /* 0.478476137 */, 18 },
7111 /* 6666 */ { MAD_F(0x07a83af7) /* 0.478571858 */, 18 },
7112 /* 6667 */ { MAD_F(0x07a89f57) /* 0.478667585 */, 18 },
7113 /* 6668 */ { MAD_F(0x07a903b9) /* 0.478763316 */, 18 },
7114 /* 6669 */ { MAD_F(0x07a9681c) /* 0.478859052 */, 18 },
7115 /* 6670 */ { MAD_F(0x07a9cc80) /* 0.478954793 */, 18 },
7116 /* 6671 */ { MAD_F(0x07aa30e5) /* 0.479050538 */, 18 },
7117
7118 /* 6672 */ { MAD_F(0x07aa954c) /* 0.479146288 */, 18 },
7119 /* 6673 */ { MAD_F(0x07aaf9b4) /* 0.479242043 */, 18 },
7120 /* 6674 */ { MAD_F(0x07ab5e1e) /* 0.479337803 */, 18 },
7121 /* 6675 */ { MAD_F(0x07abc288) /* 0.479433568 */, 18 },
7122 /* 6676 */ { MAD_F(0x07ac26f4) /* 0.479529337 */, 18 },
7123 /* 6677 */ { MAD_F(0x07ac8b61) /* 0.479625111 */, 18 },
7124 /* 6678 */ { MAD_F(0x07acefd0) /* 0.479720890 */, 18 },
7125 /* 6679 */ { MAD_F(0x07ad543f) /* 0.479816674 */, 18 },
7126 /* 6680 */ { MAD_F(0x07adb8b0) /* 0.479912463 */, 18 },
7127 /* 6681 */ { MAD_F(0x07ae1d23) /* 0.480008256 */, 18 },
7128 /* 6682 */ { MAD_F(0x07ae8196) /* 0.480104054 */, 18 },
7129 /* 6683 */ { MAD_F(0x07aee60b) /* 0.480199857 */, 18 },
7130 /* 6684 */ { MAD_F(0x07af4a81) /* 0.480295664 */, 18 },
7131 /* 6685 */ { MAD_F(0x07afaef9) /* 0.480391477 */, 18 },
7132 /* 6686 */ { MAD_F(0x07b01372) /* 0.480487294 */, 18 },
7133 /* 6687 */ { MAD_F(0x07b077ec) /* 0.480583116 */, 18 },
7134
7135 /* 6688 */ { MAD_F(0x07b0dc67) /* 0.480678943 */, 18 },
7136 /* 6689 */ { MAD_F(0x07b140e4) /* 0.480774774 */, 18 },
7137 /* 6690 */ { MAD_F(0x07b1a561) /* 0.480870611 */, 18 },
7138 /* 6691 */ { MAD_F(0x07b209e1) /* 0.480966452 */, 18 },
7139 /* 6692 */ { MAD_F(0x07b26e61) /* 0.481062298 */, 18 },
7140 /* 6693 */ { MAD_F(0x07b2d2e3) /* 0.481158148 */, 18 },
7141 /* 6694 */ { MAD_F(0x07b33766) /* 0.481254004 */, 18 },
7142 /* 6695 */ { MAD_F(0x07b39bea) /* 0.481349864 */, 18 },
7143 /* 6696 */ { MAD_F(0x07b4006f) /* 0.481445729 */, 18 },
7144 /* 6697 */ { MAD_F(0x07b464f6) /* 0.481541598 */, 18 },
7145 /* 6698 */ { MAD_F(0x07b4c97e) /* 0.481637473 */, 18 },
7146 /* 6699 */ { MAD_F(0x07b52e08) /* 0.481733352 */, 18 },
7147 /* 6700 */ { MAD_F(0x07b59292) /* 0.481829236 */, 18 },
7148 /* 6701 */ { MAD_F(0x07b5f71e) /* 0.481925125 */, 18 },
7149 /* 6702 */ { MAD_F(0x07b65bac) /* 0.482021019 */, 18 },
7150 /* 6703 */ { MAD_F(0x07b6c03a) /* 0.482116917 */, 18 },
7151
7152 /* 6704 */ { MAD_F(0x07b724ca) /* 0.482212820 */, 18 },
7153 /* 6705 */ { MAD_F(0x07b7895b) /* 0.482308728 */, 18 },
7154 /* 6706 */ { MAD_F(0x07b7eded) /* 0.482404640 */, 18 },
7155 /* 6707 */ { MAD_F(0x07b85281) /* 0.482500558 */, 18 },
7156 /* 6708 */ { MAD_F(0x07b8b716) /* 0.482596480 */, 18 },
7157 /* 6709 */ { MAD_F(0x07b91bac) /* 0.482692407 */, 18 },
7158 /* 6710 */ { MAD_F(0x07b98044) /* 0.482788339 */, 18 },
7159 /* 6711 */ { MAD_F(0x07b9e4dc) /* 0.482884275 */, 18 },
7160 /* 6712 */ { MAD_F(0x07ba4976) /* 0.482980216 */, 18 },
7161 /* 6713 */ { MAD_F(0x07baae12) /* 0.483076162 */, 18 },
7162 /* 6714 */ { MAD_F(0x07bb12ae) /* 0.483172113 */, 18 },
7163 /* 6715 */ { MAD_F(0x07bb774c) /* 0.483268069 */, 18 },
7164 /* 6716 */ { MAD_F(0x07bbdbeb) /* 0.483364029 */, 18 },
7165 /* 6717 */ { MAD_F(0x07bc408c) /* 0.483459994 */, 18 },
7166 /* 6718 */ { MAD_F(0x07bca52d) /* 0.483555964 */, 18 },
7167 /* 6719 */ { MAD_F(0x07bd09d0) /* 0.483651939 */, 18 },
7168
7169 /* 6720 */ { MAD_F(0x07bd6e75) /* 0.483747918 */, 18 },
7170 /* 6721 */ { MAD_F(0x07bdd31a) /* 0.483843902 */, 18 },
7171 /* 6722 */ { MAD_F(0x07be37c1) /* 0.483939891 */, 18 },
7172 /* 6723 */ { MAD_F(0x07be9c69) /* 0.484035885 */, 18 },
7173 /* 6724 */ { MAD_F(0x07bf0113) /* 0.484131883 */, 18 },
7174 /* 6725 */ { MAD_F(0x07bf65bd) /* 0.484227886 */, 18 },
7175 /* 6726 */ { MAD_F(0x07bfca69) /* 0.484323894 */, 18 },
7176 /* 6727 */ { MAD_F(0x07c02f16) /* 0.484419907 */, 18 },
7177 /* 6728 */ { MAD_F(0x07c093c5) /* 0.484515924 */, 18 },
7178 /* 6729 */ { MAD_F(0x07c0f875) /* 0.484611946 */, 18 },
7179 /* 6730 */ { MAD_F(0x07c15d26) /* 0.484707973 */, 18 },
7180 /* 6731 */ { MAD_F(0x07c1c1d8) /* 0.484804005 */, 18 },
7181 /* 6732 */ { MAD_F(0x07c2268b) /* 0.484900041 */, 18 },
7182 /* 6733 */ { MAD_F(0x07c28b40) /* 0.484996083 */, 18 },
7183 /* 6734 */ { MAD_F(0x07c2eff6) /* 0.485092128 */, 18 },
7184 /* 6735 */ { MAD_F(0x07c354ae) /* 0.485188179 */, 18 },
7185
7186 /* 6736 */ { MAD_F(0x07c3b967) /* 0.485284235 */, 18 },
7187 /* 6737 */ { MAD_F(0x07c41e21) /* 0.485380295 */, 18 },
7188 /* 6738 */ { MAD_F(0x07c482dc) /* 0.485476360 */, 18 },
7189 /* 6739 */ { MAD_F(0x07c4e798) /* 0.485572430 */, 18 },
7190 /* 6740 */ { MAD_F(0x07c54c56) /* 0.485668504 */, 18 },
7191 /* 6741 */ { MAD_F(0x07c5b115) /* 0.485764583 */, 18 },
7192 /* 6742 */ { MAD_F(0x07c615d6) /* 0.485860667 */, 18 },
7193 /* 6743 */ { MAD_F(0x07c67a97) /* 0.485956756 */, 18 },
7194 /* 6744 */ { MAD_F(0x07c6df5a) /* 0.486052849 */, 18 },
7195 /* 6745 */ { MAD_F(0x07c7441e) /* 0.486148948 */, 18 },
7196 /* 6746 */ { MAD_F(0x07c7a8e4) /* 0.486245051 */, 18 },
7197 /* 6747 */ { MAD_F(0x07c80daa) /* 0.486341158 */, 18 },
7198 /* 6748 */ { MAD_F(0x07c87272) /* 0.486437271 */, 18 },
7199 /* 6749 */ { MAD_F(0x07c8d73c) /* 0.486533388 */, 18 },
7200 /* 6750 */ { MAD_F(0x07c93c06) /* 0.486629510 */, 18 },
7201 /* 6751 */ { MAD_F(0x07c9a0d2) /* 0.486725637 */, 18 },
7202
7203 /* 6752 */ { MAD_F(0x07ca059f) /* 0.486821768 */, 18 },
7204 /* 6753 */ { MAD_F(0x07ca6a6d) /* 0.486917905 */, 18 },
7205 /* 6754 */ { MAD_F(0x07cacf3d) /* 0.487014045 */, 18 },
7206 /* 6755 */ { MAD_F(0x07cb340e) /* 0.487110191 */, 18 },
7207 /* 6756 */ { MAD_F(0x07cb98e0) /* 0.487206342 */, 18 },
7208 /* 6757 */ { MAD_F(0x07cbfdb4) /* 0.487302497 */, 18 },
7209 /* 6758 */ { MAD_F(0x07cc6288) /* 0.487398657 */, 18 },
7210 /* 6759 */ { MAD_F(0x07ccc75e) /* 0.487494821 */, 18 },
7211 /* 6760 */ { MAD_F(0x07cd2c36) /* 0.487590991 */, 18 },
7212 /* 6761 */ { MAD_F(0x07cd910e) /* 0.487687165 */, 18 },
7213 /* 6762 */ { MAD_F(0x07cdf5e8) /* 0.487783344 */, 18 },
7214 /* 6763 */ { MAD_F(0x07ce5ac3) /* 0.487879528 */, 18 },
7215 /* 6764 */ { MAD_F(0x07cebfa0) /* 0.487975716 */, 18 },
7216 /* 6765 */ { MAD_F(0x07cf247d) /* 0.488071909 */, 18 },
7217 /* 6766 */ { MAD_F(0x07cf895c) /* 0.488168107 */, 18 },
7218 /* 6767 */ { MAD_F(0x07cfee3c) /* 0.488264310 */, 18 },
7219
7220 /* 6768 */ { MAD_F(0x07d0531e) /* 0.488360517 */, 18 },
7221 /* 6769 */ { MAD_F(0x07d0b801) /* 0.488456729 */, 18 },
7222 /* 6770 */ { MAD_F(0x07d11ce5) /* 0.488552946 */, 18 },
7223 /* 6771 */ { MAD_F(0x07d181ca) /* 0.488649167 */, 18 },
7224 /* 6772 */ { MAD_F(0x07d1e6b0) /* 0.488745394 */, 18 },
7225 /* 6773 */ { MAD_F(0x07d24b98) /* 0.488841625 */, 18 },
7226 /* 6774 */ { MAD_F(0x07d2b081) /* 0.488937860 */, 18 },
7227 /* 6775 */ { MAD_F(0x07d3156c) /* 0.489034101 */, 18 },
7228 /* 6776 */ { MAD_F(0x07d37a57) /* 0.489130346 */, 18 },
7229 /* 6777 */ { MAD_F(0x07d3df44) /* 0.489226596 */, 18 },
7230 /* 6778 */ { MAD_F(0x07d44432) /* 0.489322851 */, 18 },
7231 /* 6779 */ { MAD_F(0x07d4a922) /* 0.489419110 */, 18 },
7232 /* 6780 */ { MAD_F(0x07d50e13) /* 0.489515375 */, 18 },
7233 /* 6781 */ { MAD_F(0x07d57305) /* 0.489611643 */, 18 },
7234 /* 6782 */ { MAD_F(0x07d5d7f8) /* 0.489707917 */, 18 },
7235 /* 6783 */ { MAD_F(0x07d63cec) /* 0.489804195 */, 18 },
7236
7237 /* 6784 */ { MAD_F(0x07d6a1e2) /* 0.489900479 */, 18 },
7238 /* 6785 */ { MAD_F(0x07d706d9) /* 0.489996766 */, 18 },
7239 /* 6786 */ { MAD_F(0x07d76bd2) /* 0.490093059 */, 18 },
7240 /* 6787 */ { MAD_F(0x07d7d0cb) /* 0.490189356 */, 18 },
7241 /* 6788 */ { MAD_F(0x07d835c6) /* 0.490285658 */, 18 },
7242 /* 6789 */ { MAD_F(0x07d89ac2) /* 0.490381965 */, 18 },
7243 /* 6790 */ { MAD_F(0x07d8ffc0) /* 0.490478277 */, 18 },
7244 /* 6791 */ { MAD_F(0x07d964be) /* 0.490574593 */, 18 },
7245 /* 6792 */ { MAD_F(0x07d9c9be) /* 0.490670914 */, 18 },
7246 /* 6793 */ { MAD_F(0x07da2ebf) /* 0.490767239 */, 18 },
7247 /* 6794 */ { MAD_F(0x07da93c2) /* 0.490863570 */, 18 },
7248 /* 6795 */ { MAD_F(0x07daf8c6) /* 0.490959905 */, 18 },
7249 /* 6796 */ { MAD_F(0x07db5dcb) /* 0.491056245 */, 18 },
7250 /* 6797 */ { MAD_F(0x07dbc2d1) /* 0.491152589 */, 18 },
7251 /* 6798 */ { MAD_F(0x07dc27d9) /* 0.491248939 */, 18 },
7252 /* 6799 */ { MAD_F(0x07dc8ce1) /* 0.491345293 */, 18 },
7253
7254 /* 6800 */ { MAD_F(0x07dcf1ec) /* 0.491441651 */, 18 },
7255 /* 6801 */ { MAD_F(0x07dd56f7) /* 0.491538015 */, 18 },
7256 /* 6802 */ { MAD_F(0x07ddbc04) /* 0.491634383 */, 18 },
7257 /* 6803 */ { MAD_F(0x07de2111) /* 0.491730756 */, 18 },
7258 /* 6804 */ { MAD_F(0x07de8621) /* 0.491827134 */, 18 },
7259 /* 6805 */ { MAD_F(0x07deeb31) /* 0.491923516 */, 18 },
7260 /* 6806 */ { MAD_F(0x07df5043) /* 0.492019903 */, 18 },
7261 /* 6807 */ { MAD_F(0x07dfb556) /* 0.492116295 */, 18 },
7262 /* 6808 */ { MAD_F(0x07e01a6a) /* 0.492212691 */, 18 },
7263 /* 6809 */ { MAD_F(0x07e07f80) /* 0.492309093 */, 18 },
7264 /* 6810 */ { MAD_F(0x07e0e496) /* 0.492405499 */, 18 },
7265 /* 6811 */ { MAD_F(0x07e149ae) /* 0.492501909 */, 18 },
7266 /* 6812 */ { MAD_F(0x07e1aec8) /* 0.492598325 */, 18 },
7267 /* 6813 */ { MAD_F(0x07e213e2) /* 0.492694745 */, 18 },
7268 /* 6814 */ { MAD_F(0x07e278fe) /* 0.492791170 */, 18 },
7269 /* 6815 */ { MAD_F(0x07e2de1b) /* 0.492887599 */, 18 },
7270
7271 /* 6816 */ { MAD_F(0x07e3433a) /* 0.492984033 */, 18 },
7272 /* 6817 */ { MAD_F(0x07e3a859) /* 0.493080472 */, 18 },
7273 /* 6818 */ { MAD_F(0x07e40d7a) /* 0.493176916 */, 18 },
7274 /* 6819 */ { MAD_F(0x07e4729c) /* 0.493273365 */, 18 },
7275 /* 6820 */ { MAD_F(0x07e4d7c0) /* 0.493369818 */, 18 },
7276 /* 6821 */ { MAD_F(0x07e53ce4) /* 0.493466275 */, 18 },
7277 /* 6822 */ { MAD_F(0x07e5a20a) /* 0.493562738 */, 18 },
7278 /* 6823 */ { MAD_F(0x07e60732) /* 0.493659205 */, 18 },
7279 /* 6824 */ { MAD_F(0x07e66c5a) /* 0.493755677 */, 18 },
7280 /* 6825 */ { MAD_F(0x07e6d184) /* 0.493852154 */, 18 },
7281 /* 6826 */ { MAD_F(0x07e736af) /* 0.493948635 */, 18 },
7282 /* 6827 */ { MAD_F(0x07e79bdb) /* 0.494045122 */, 18 },
7283 /* 6828 */ { MAD_F(0x07e80109) /* 0.494141612 */, 18 },
7284 /* 6829 */ { MAD_F(0x07e86638) /* 0.494238108 */, 18 },
7285 /* 6830 */ { MAD_F(0x07e8cb68) /* 0.494334608 */, 18 },
7286 /* 6831 */ { MAD_F(0x07e93099) /* 0.494431113 */, 18 },
7287
7288 /* 6832 */ { MAD_F(0x07e995cc) /* 0.494527623 */, 18 },
7289 /* 6833 */ { MAD_F(0x07e9fb00) /* 0.494624137 */, 18 },
7290 /* 6834 */ { MAD_F(0x07ea6035) /* 0.494720656 */, 18 },
7291 /* 6835 */ { MAD_F(0x07eac56b) /* 0.494817180 */, 18 },
7292 /* 6836 */ { MAD_F(0x07eb2aa3) /* 0.494913709 */, 18 },
7293 /* 6837 */ { MAD_F(0x07eb8fdc) /* 0.495010242 */, 18 },
7294 /* 6838 */ { MAD_F(0x07ebf516) /* 0.495106780 */, 18 },
7295 /* 6839 */ { MAD_F(0x07ec5a51) /* 0.495203322 */, 18 },
7296 /* 6840 */ { MAD_F(0x07ecbf8e) /* 0.495299870 */, 18 },
7297 /* 6841 */ { MAD_F(0x07ed24cc) /* 0.495396422 */, 18 },
7298 /* 6842 */ { MAD_F(0x07ed8a0b) /* 0.495492978 */, 18 },
7299 /* 6843 */ { MAD_F(0x07edef4c) /* 0.495589540 */, 18 },
7300 /* 6844 */ { MAD_F(0x07ee548e) /* 0.495686106 */, 18 },
7301 /* 6845 */ { MAD_F(0x07eeb9d1) /* 0.495782677 */, 18 },
7302 /* 6846 */ { MAD_F(0x07ef1f15) /* 0.495879252 */, 18 },
7303 /* 6847 */ { MAD_F(0x07ef845b) /* 0.495975833 */, 18 },
7304
7305 /* 6848 */ { MAD_F(0x07efe9a1) /* 0.496072418 */, 18 },
7306 /* 6849 */ { MAD_F(0x07f04ee9) /* 0.496169007 */, 18 },
7307 /* 6850 */ { MAD_F(0x07f0b433) /* 0.496265602 */, 18 },
7308 /* 6851 */ { MAD_F(0x07f1197d) /* 0.496362201 */, 18 },
7309 /* 6852 */ { MAD_F(0x07f17ec9) /* 0.496458804 */, 18 },
7310 /* 6853 */ { MAD_F(0x07f1e416) /* 0.496555413 */, 18 },
7311 /* 6854 */ { MAD_F(0x07f24965) /* 0.496652026 */, 18 },
7312 /* 6855 */ { MAD_F(0x07f2aeb5) /* 0.496748644 */, 18 },
7313 /* 6856 */ { MAD_F(0x07f31405) /* 0.496845266 */, 18 },
7314 /* 6857 */ { MAD_F(0x07f37958) /* 0.496941894 */, 18 },
7315 /* 6858 */ { MAD_F(0x07f3deab) /* 0.497038526 */, 18 },
7316 /* 6859 */ { MAD_F(0x07f44400) /* 0.497135162 */, 18 },
7317 /* 6860 */ { MAD_F(0x07f4a956) /* 0.497231804 */, 18 },
7318 /* 6861 */ { MAD_F(0x07f50ead) /* 0.497328450 */, 18 },
7319 /* 6862 */ { MAD_F(0x07f57405) /* 0.497425100 */, 18 },
7320 /* 6863 */ { MAD_F(0x07f5d95f) /* 0.497521756 */, 18 },
7321
7322 /* 6864 */ { MAD_F(0x07f63eba) /* 0.497618416 */, 18 },
7323 /* 6865 */ { MAD_F(0x07f6a416) /* 0.497715081 */, 18 },
7324 /* 6866 */ { MAD_F(0x07f70974) /* 0.497811750 */, 18 },
7325 /* 6867 */ { MAD_F(0x07f76ed3) /* 0.497908425 */, 18 },
7326 /* 6868 */ { MAD_F(0x07f7d433) /* 0.498005103 */, 18 },
7327 /* 6869 */ { MAD_F(0x07f83994) /* 0.498101787 */, 18 },
7328 /* 6870 */ { MAD_F(0x07f89ef7) /* 0.498198475 */, 18 },
7329 /* 6871 */ { MAD_F(0x07f9045a) /* 0.498295168 */, 18 },
7330 /* 6872 */ { MAD_F(0x07f969c0) /* 0.498391866 */, 18 },
7331 /* 6873 */ { MAD_F(0x07f9cf26) /* 0.498488568 */, 18 },
7332 /* 6874 */ { MAD_F(0x07fa348e) /* 0.498585275 */, 18 },
7333 /* 6875 */ { MAD_F(0x07fa99f6) /* 0.498681987 */, 18 },
7334 /* 6876 */ { MAD_F(0x07faff60) /* 0.498778704 */, 18 },
7335 /* 6877 */ { MAD_F(0x07fb64cc) /* 0.498875425 */, 18 },
7336 /* 6878 */ { MAD_F(0x07fbca38) /* 0.498972150 */, 18 },
7337 /* 6879 */ { MAD_F(0x07fc2fa6) /* 0.499068881 */, 18 },
7338
7339 /* 6880 */ { MAD_F(0x07fc9516) /* 0.499165616 */, 18 },
7340 /* 6881 */ { MAD_F(0x07fcfa86) /* 0.499262356 */, 18 },
7341 /* 6882 */ { MAD_F(0x07fd5ff8) /* 0.499359101 */, 18 },
7342 /* 6883 */ { MAD_F(0x07fdc56b) /* 0.499455850 */, 18 },
7343 /* 6884 */ { MAD_F(0x07fe2adf) /* 0.499552604 */, 18 },
7344 /* 6885 */ { MAD_F(0x07fe9054) /* 0.499649362 */, 18 },
7345 /* 6886 */ { MAD_F(0x07fef5cb) /* 0.499746126 */, 18 },
7346 /* 6887 */ { MAD_F(0x07ff5b43) /* 0.499842894 */, 18 },
7347 /* 6888 */ { MAD_F(0x07ffc0bc) /* 0.499939666 */, 18 },
7348 /* 6889 */ { MAD_F(0x0400131b) /* 0.250018222 */, 19 },
7349 /* 6890 */ { MAD_F(0x040045d9) /* 0.250066613 */, 19 },
7350 /* 6891 */ { MAD_F(0x04007897) /* 0.250115006 */, 19 },
7351 /* 6892 */ { MAD_F(0x0400ab57) /* 0.250163402 */, 19 },
7352 /* 6893 */ { MAD_F(0x0400de16) /* 0.250211800 */, 19 },
7353 /* 6894 */ { MAD_F(0x040110d7) /* 0.250260200 */, 19 },
7354 /* 6895 */ { MAD_F(0x04014398) /* 0.250308603 */, 19 },
7355
7356 /* 6896 */ { MAD_F(0x04017659) /* 0.250357008 */, 19 },
7357 /* 6897 */ { MAD_F(0x0401a91c) /* 0.250405415 */, 19 },
7358 /* 6898 */ { MAD_F(0x0401dbdf) /* 0.250453825 */, 19 },
7359 /* 6899 */ { MAD_F(0x04020ea2) /* 0.250502237 */, 19 },
7360 /* 6900 */ { MAD_F(0x04024166) /* 0.250550652 */, 19 },
7361 /* 6901 */ { MAD_F(0x0402742b) /* 0.250599068 */, 19 },
7362 /* 6902 */ { MAD_F(0x0402a6f0) /* 0.250647488 */, 19 },
7363 /* 6903 */ { MAD_F(0x0402d9b6) /* 0.250695909 */, 19 },
7364 /* 6904 */ { MAD_F(0x04030c7d) /* 0.250744333 */, 19 },
7365 /* 6905 */ { MAD_F(0x04033f44) /* 0.250792759 */, 19 },
7366 /* 6906 */ { MAD_F(0x0403720c) /* 0.250841187 */, 19 },
7367 /* 6907 */ { MAD_F(0x0403a4d5) /* 0.250889618 */, 19 },
7368 /* 6908 */ { MAD_F(0x0403d79e) /* 0.250938051 */, 19 },
7369 /* 6909 */ { MAD_F(0x04040a68) /* 0.250986487 */, 19 },
7370 /* 6910 */ { MAD_F(0x04043d32) /* 0.251034924 */, 19 },
7371 /* 6911 */ { MAD_F(0x04046ffd) /* 0.251083365 */, 19 },
7372
7373 /* 6912 */ { MAD_F(0x0404a2c9) /* 0.251131807 */, 19 },
7374 /* 6913 */ { MAD_F(0x0404d595) /* 0.251180252 */, 19 },
7375 /* 6914 */ { MAD_F(0x04050862) /* 0.251228699 */, 19 },
7376 /* 6915 */ { MAD_F(0x04053b30) /* 0.251277148 */, 19 },
7377 /* 6916 */ { MAD_F(0x04056dfe) /* 0.251325600 */, 19 },
7378 /* 6917 */ { MAD_F(0x0405a0cd) /* 0.251374054 */, 19 },
7379 /* 6918 */ { MAD_F(0x0405d39c) /* 0.251422511 */, 19 },
7380 /* 6919 */ { MAD_F(0x0406066c) /* 0.251470970 */, 19 },
7381 /* 6920 */ { MAD_F(0x0406393d) /* 0.251519431 */, 19 },
7382 /* 6921 */ { MAD_F(0x04066c0e) /* 0.251567894 */, 19 },
7383 /* 6922 */ { MAD_F(0x04069ee0) /* 0.251616360 */, 19 },
7384 /* 6923 */ { MAD_F(0x0406d1b3) /* 0.251664828 */, 19 },
7385 /* 6924 */ { MAD_F(0x04070486) /* 0.251713299 */, 19 },
7386 /* 6925 */ { MAD_F(0x0407375a) /* 0.251761772 */, 19 },
7387 /* 6926 */ { MAD_F(0x04076a2e) /* 0.251810247 */, 19 },
7388 /* 6927 */ { MAD_F(0x04079d03) /* 0.251858724 */, 19 },
7389
7390 /* 6928 */ { MAD_F(0x0407cfd9) /* 0.251907204 */, 19 },
7391 /* 6929 */ { MAD_F(0x040802af) /* 0.251955686 */, 19 },
7392 /* 6930 */ { MAD_F(0x04083586) /* 0.252004171 */, 19 },
7393 /* 6931 */ { MAD_F(0x0408685e) /* 0.252052658 */, 19 },
7394 /* 6932 */ { MAD_F(0x04089b36) /* 0.252101147 */, 19 },
7395 /* 6933 */ { MAD_F(0x0408ce0f) /* 0.252149638 */, 19 },
7396 /* 6934 */ { MAD_F(0x040900e8) /* 0.252198132 */, 19 },
7397 /* 6935 */ { MAD_F(0x040933c2) /* 0.252246628 */, 19 },
7398 /* 6936 */ { MAD_F(0x0409669d) /* 0.252295127 */, 19 },
7399 /* 6937 */ { MAD_F(0x04099978) /* 0.252343627 */, 19 },
7400 /* 6938 */ { MAD_F(0x0409cc54) /* 0.252392131 */, 19 },
7401 /* 6939 */ { MAD_F(0x0409ff31) /* 0.252440636 */, 19 },
7402 /* 6940 */ { MAD_F(0x040a320e) /* 0.252489144 */, 19 },
7403 /* 6941 */ { MAD_F(0x040a64ec) /* 0.252537654 */, 19 },
7404 /* 6942 */ { MAD_F(0x040a97cb) /* 0.252586166 */, 19 },
7405 /* 6943 */ { MAD_F(0x040acaaa) /* 0.252634681 */, 19 },
7406
7407 /* 6944 */ { MAD_F(0x040afd89) /* 0.252683198 */, 19 },
7408 /* 6945 */ { MAD_F(0x040b306a) /* 0.252731718 */, 19 },
7409 /* 6946 */ { MAD_F(0x040b634b) /* 0.252780240 */, 19 },
7410 /* 6947 */ { MAD_F(0x040b962c) /* 0.252828764 */, 19 },
7411 /* 6948 */ { MAD_F(0x040bc90e) /* 0.252877290 */, 19 },
7412 /* 6949 */ { MAD_F(0x040bfbf1) /* 0.252925819 */, 19 },
7413 /* 6950 */ { MAD_F(0x040c2ed5) /* 0.252974350 */, 19 },
7414 /* 6951 */ { MAD_F(0x040c61b9) /* 0.253022883 */, 19 },
7415 /* 6952 */ { MAD_F(0x040c949e) /* 0.253071419 */, 19 },
7416 /* 6953 */ { MAD_F(0x040cc783) /* 0.253119957 */, 19 },
7417 /* 6954 */ { MAD_F(0x040cfa69) /* 0.253168498 */, 19 },
7418 /* 6955 */ { MAD_F(0x040d2d4f) /* 0.253217040 */, 19 },
7419 /* 6956 */ { MAD_F(0x040d6037) /* 0.253265585 */, 19 },
7420 /* 6957 */ { MAD_F(0x040d931e) /* 0.253314133 */, 19 },
7421 /* 6958 */ { MAD_F(0x040dc607) /* 0.253362682 */, 19 },
7422 /* 6959 */ { MAD_F(0x040df8f0) /* 0.253411234 */, 19 },
7423
7424 /* 6960 */ { MAD_F(0x040e2bda) /* 0.253459789 */, 19 },
7425 /* 6961 */ { MAD_F(0x040e5ec4) /* 0.253508345 */, 19 },
7426 /* 6962 */ { MAD_F(0x040e91af) /* 0.253556904 */, 19 },
7427 /* 6963 */ { MAD_F(0x040ec49b) /* 0.253605466 */, 19 },
7428 /* 6964 */ { MAD_F(0x040ef787) /* 0.253654029 */, 19 },
7429 /* 6965 */ { MAD_F(0x040f2a74) /* 0.253702595 */, 19 },
7430 /* 6966 */ { MAD_F(0x040f5d61) /* 0.253751164 */, 19 },
7431 /* 6967 */ { MAD_F(0x040f904f) /* 0.253799734 */, 19 },
7432 /* 6968 */ { MAD_F(0x040fc33e) /* 0.253848307 */, 19 },
7433 /* 6969 */ { MAD_F(0x040ff62d) /* 0.253896883 */, 19 },
7434 /* 6970 */ { MAD_F(0x0410291d) /* 0.253945460 */, 19 },
7435 /* 6971 */ { MAD_F(0x04105c0e) /* 0.253994040 */, 19 },
7436 /* 6972 */ { MAD_F(0x04108eff) /* 0.254042622 */, 19 },
7437 /* 6973 */ { MAD_F(0x0410c1f1) /* 0.254091207 */, 19 },
7438 /* 6974 */ { MAD_F(0x0410f4e3) /* 0.254139794 */, 19 },
7439 /* 6975 */ { MAD_F(0x041127d6) /* 0.254188383 */, 19 },
7440
7441 /* 6976 */ { MAD_F(0x04115aca) /* 0.254236974 */, 19 },
7442 /* 6977 */ { MAD_F(0x04118dbe) /* 0.254285568 */, 19 },
7443 /* 6978 */ { MAD_F(0x0411c0b3) /* 0.254334165 */, 19 },
7444 /* 6979 */ { MAD_F(0x0411f3a9) /* 0.254382763 */, 19 },
7445 /* 6980 */ { MAD_F(0x0412269f) /* 0.254431364 */, 19 },
7446 /* 6981 */ { MAD_F(0x04125996) /* 0.254479967 */, 19 },
7447 /* 6982 */ { MAD_F(0x04128c8d) /* 0.254528572 */, 19 },
7448 /* 6983 */ { MAD_F(0x0412bf85) /* 0.254577180 */, 19 },
7449 /* 6984 */ { MAD_F(0x0412f27e) /* 0.254625790 */, 19 },
7450 /* 6985 */ { MAD_F(0x04132577) /* 0.254674403 */, 19 },
7451 /* 6986 */ { MAD_F(0x04135871) /* 0.254723017 */, 19 },
7452 /* 6987 */ { MAD_F(0x04138b6c) /* 0.254771635 */, 19 },
7453 /* 6988 */ { MAD_F(0x0413be67) /* 0.254820254 */, 19 },
7454 /* 6989 */ { MAD_F(0x0413f163) /* 0.254868876 */, 19 },
7455 /* 6990 */ { MAD_F(0x0414245f) /* 0.254917500 */, 19 },
7456 /* 6991 */ { MAD_F(0x0414575c) /* 0.254966126 */, 19 },
7457
7458 /* 6992 */ { MAD_F(0x04148a5a) /* 0.255014755 */, 19 },
7459 /* 6993 */ { MAD_F(0x0414bd58) /* 0.255063386 */, 19 },
7460 /* 6994 */ { MAD_F(0x0414f057) /* 0.255112019 */, 19 },
7461 /* 6995 */ { MAD_F(0x04152356) /* 0.255160655 */, 19 },
7462 /* 6996 */ { MAD_F(0x04155657) /* 0.255209292 */, 19 },
7463 /* 6997 */ { MAD_F(0x04158957) /* 0.255257933 */, 19 },
7464 /* 6998 */ { MAD_F(0x0415bc59) /* 0.255306575 */, 19 },
7465 /* 6999 */ { MAD_F(0x0415ef5b) /* 0.255355220 */, 19 },
7466 /* 7000 */ { MAD_F(0x0416225d) /* 0.255403867 */, 19 },
7467 /* 7001 */ { MAD_F(0x04165561) /* 0.255452517 */, 19 },
7468 /* 7002 */ { MAD_F(0x04168864) /* 0.255501169 */, 19 },
7469 /* 7003 */ { MAD_F(0x0416bb69) /* 0.255549823 */, 19 },
7470 /* 7004 */ { MAD_F(0x0416ee6e) /* 0.255598479 */, 19 },
7471 /* 7005 */ { MAD_F(0x04172174) /* 0.255647138 */, 19 },
7472 /* 7006 */ { MAD_F(0x0417547a) /* 0.255695799 */, 19 },
7473 /* 7007 */ { MAD_F(0x04178781) /* 0.255744463 */, 19 },
7474
7475 /* 7008 */ { MAD_F(0x0417ba89) /* 0.255793128 */, 19 },
7476 /* 7009 */ { MAD_F(0x0417ed91) /* 0.255841796 */, 19 },
7477 /* 7010 */ { MAD_F(0x0418209a) /* 0.255890467 */, 19 },
7478 /* 7011 */ { MAD_F(0x041853a3) /* 0.255939139 */, 19 },
7479 /* 7012 */ { MAD_F(0x041886ad) /* 0.255987814 */, 19 },
7480 /* 7013 */ { MAD_F(0x0418b9b8) /* 0.256036492 */, 19 },
7481 /* 7014 */ { MAD_F(0x0418ecc3) /* 0.256085171 */, 19 },
7482 /* 7015 */ { MAD_F(0x04191fcf) /* 0.256133853 */, 19 },
7483 /* 7016 */ { MAD_F(0x041952dc) /* 0.256182537 */, 19 },
7484 /* 7017 */ { MAD_F(0x041985e9) /* 0.256231224 */, 19 },
7485 /* 7018 */ { MAD_F(0x0419b8f7) /* 0.256279913 */, 19 },
7486 /* 7019 */ { MAD_F(0x0419ec05) /* 0.256328604 */, 19 },
7487 /* 7020 */ { MAD_F(0x041a1f15) /* 0.256377297 */, 19 },
7488 /* 7021 */ { MAD_F(0x041a5224) /* 0.256425993 */, 19 },
7489 /* 7022 */ { MAD_F(0x041a8534) /* 0.256474691 */, 19 },
7490 /* 7023 */ { MAD_F(0x041ab845) /* 0.256523392 */, 19 },
7491
7492 /* 7024 */ { MAD_F(0x041aeb57) /* 0.256572095 */, 19 },
7493 /* 7025 */ { MAD_F(0x041b1e69) /* 0.256620800 */, 19 },
7494 /* 7026 */ { MAD_F(0x041b517c) /* 0.256669507 */, 19 },
7495 /* 7027 */ { MAD_F(0x041b848f) /* 0.256718217 */, 19 },
7496 /* 7028 */ { MAD_F(0x041bb7a3) /* 0.256766929 */, 19 },
7497 /* 7029 */ { MAD_F(0x041beab8) /* 0.256815643 */, 19 },
7498 /* 7030 */ { MAD_F(0x041c1dcd) /* 0.256864359 */, 19 },
7499 /* 7031 */ { MAD_F(0x041c50e3) /* 0.256913078 */, 19 },
7500 /* 7032 */ { MAD_F(0x041c83fa) /* 0.256961800 */, 19 },
7501 /* 7033 */ { MAD_F(0x041cb711) /* 0.257010523 */, 19 },
7502 /* 7034 */ { MAD_F(0x041cea28) /* 0.257059249 */, 19 },
7503 /* 7035 */ { MAD_F(0x041d1d41) /* 0.257107977 */, 19 },
7504 /* 7036 */ { MAD_F(0x041d505a) /* 0.257156708 */, 19 },
7505 /* 7037 */ { MAD_F(0x041d8373) /* 0.257205440 */, 19 },
7506 /* 7038 */ { MAD_F(0x041db68e) /* 0.257254175 */, 19 },
7507 /* 7039 */ { MAD_F(0x041de9a8) /* 0.257302913 */, 19 },
7508
7509 /* 7040 */ { MAD_F(0x041e1cc4) /* 0.257351652 */, 19 },
7510 /* 7041 */ { MAD_F(0x041e4fe0) /* 0.257400394 */, 19 },
7511 /* 7042 */ { MAD_F(0x041e82fd) /* 0.257449139 */, 19 },
7512 /* 7043 */ { MAD_F(0x041eb61a) /* 0.257497885 */, 19 },
7513 /* 7044 */ { MAD_F(0x041ee938) /* 0.257546634 */, 19 },
7514 /* 7045 */ { MAD_F(0x041f1c57) /* 0.257595386 */, 19 },
7515 /* 7046 */ { MAD_F(0x041f4f76) /* 0.257644139 */, 19 },
7516 /* 7047 */ { MAD_F(0x041f8296) /* 0.257692895 */, 19 },
7517 /* 7048 */ { MAD_F(0x041fb5b6) /* 0.257741653 */, 19 },
7518 /* 7049 */ { MAD_F(0x041fe8d7) /* 0.257790414 */, 19 },
7519 /* 7050 */ { MAD_F(0x04201bf9) /* 0.257839176 */, 19 },
7520 /* 7051 */ { MAD_F(0x04204f1b) /* 0.257887941 */, 19 },
7521 /* 7052 */ { MAD_F(0x0420823e) /* 0.257936709 */, 19 },
7522 /* 7053 */ { MAD_F(0x0420b561) /* 0.257985478 */, 19 },
7523 /* 7054 */ { MAD_F(0x0420e885) /* 0.258034250 */, 19 },
7524 /* 7055 */ { MAD_F(0x04211baa) /* 0.258083025 */, 19 },
7525
7526 /* 7056 */ { MAD_F(0x04214ed0) /* 0.258131801 */, 19 },
7527 /* 7057 */ { MAD_F(0x042181f6) /* 0.258180580 */, 19 },
7528 /* 7058 */ { MAD_F(0x0421b51c) /* 0.258229361 */, 19 },
7529 /* 7059 */ { MAD_F(0x0421e843) /* 0.258278145 */, 19 },
7530 /* 7060 */ { MAD_F(0x04221b6b) /* 0.258326931 */, 19 },
7531 /* 7061 */ { MAD_F(0x04224e94) /* 0.258375719 */, 19 },
7532 /* 7062 */ { MAD_F(0x042281bd) /* 0.258424509 */, 19 },
7533 /* 7063 */ { MAD_F(0x0422b4e6) /* 0.258473302 */, 19 },
7534 /* 7064 */ { MAD_F(0x0422e811) /* 0.258522097 */, 19 },
7535 /* 7065 */ { MAD_F(0x04231b3c) /* 0.258570894 */, 19 },
7536 /* 7066 */ { MAD_F(0x04234e67) /* 0.258619694 */, 19 },
7537 /* 7067 */ { MAD_F(0x04238193) /* 0.258668496 */, 19 },
7538 /* 7068 */ { MAD_F(0x0423b4c0) /* 0.258717300 */, 19 },
7539 /* 7069 */ { MAD_F(0x0423e7ee) /* 0.258766106 */, 19 },
7540 /* 7070 */ { MAD_F(0x04241b1c) /* 0.258814915 */, 19 },
7541 /* 7071 */ { MAD_F(0x04244e4a) /* 0.258863726 */, 19 },
7542
7543 /* 7072 */ { MAD_F(0x04248179) /* 0.258912540 */, 19 },
7544 /* 7073 */ { MAD_F(0x0424b4a9) /* 0.258961356 */, 19 },
7545 /* 7074 */ { MAD_F(0x0424e7da) /* 0.259010174 */, 19 },
7546 /* 7075 */ { MAD_F(0x04251b0b) /* 0.259058994 */, 19 },
7547 /* 7076 */ { MAD_F(0x04254e3d) /* 0.259107817 */, 19 },
7548 /* 7077 */ { MAD_F(0x0425816f) /* 0.259156642 */, 19 },
7549 /* 7078 */ { MAD_F(0x0425b4a2) /* 0.259205469 */, 19 },
7550 /* 7079 */ { MAD_F(0x0425e7d6) /* 0.259254298 */, 19 },
7551 /* 7080 */ { MAD_F(0x04261b0a) /* 0.259303130 */, 19 },
7552 /* 7081 */ { MAD_F(0x04264e3f) /* 0.259351964 */, 19 },
7553 /* 7082 */ { MAD_F(0x04268174) /* 0.259400801 */, 19 },
7554 /* 7083 */ { MAD_F(0x0426b4aa) /* 0.259449639 */, 19 },
7555 /* 7084 */ { MAD_F(0x0426e7e1) /* 0.259498480 */, 19 },
7556 /* 7085 */ { MAD_F(0x04271b18) /* 0.259547324 */, 19 },
7557 /* 7086 */ { MAD_F(0x04274e50) /* 0.259596169 */, 19 },
7558 /* 7087 */ { MAD_F(0x04278188) /* 0.259645017 */, 19 },
7559
7560 /* 7088 */ { MAD_F(0x0427b4c2) /* 0.259693868 */, 19 },
7561 /* 7089 */ { MAD_F(0x0427e7fb) /* 0.259742720 */, 19 },
7562 /* 7090 */ { MAD_F(0x04281b36) /* 0.259791575 */, 19 },
7563 /* 7091 */ { MAD_F(0x04284e71) /* 0.259840432 */, 19 },
7564 /* 7092 */ { MAD_F(0x042881ac) /* 0.259889291 */, 19 },
7565 /* 7093 */ { MAD_F(0x0428b4e8) /* 0.259938153 */, 19 },
7566 /* 7094 */ { MAD_F(0x0428e825) /* 0.259987017 */, 19 },
7567 /* 7095 */ { MAD_F(0x04291b63) /* 0.260035883 */, 19 },
7568 /* 7096 */ { MAD_F(0x04294ea1) /* 0.260084752 */, 19 },
7569 /* 7097 */ { MAD_F(0x042981df) /* 0.260133623 */, 19 },
7570 /* 7098 */ { MAD_F(0x0429b51f) /* 0.260182496 */, 19 },
7571 /* 7099 */ { MAD_F(0x0429e85f) /* 0.260231372 */, 19 },
7572 /* 7100 */ { MAD_F(0x042a1b9f) /* 0.260280249 */, 19 },
7573 /* 7101 */ { MAD_F(0x042a4ee0) /* 0.260329129 */, 19 },
7574 /* 7102 */ { MAD_F(0x042a8222) /* 0.260378012 */, 19 },
7575 /* 7103 */ { MAD_F(0x042ab564) /* 0.260426896 */, 19 },
7576
7577 /* 7104 */ { MAD_F(0x042ae8a7) /* 0.260475783 */, 19 },
7578 /* 7105 */ { MAD_F(0x042b1beb) /* 0.260524673 */, 19 },
7579 /* 7106 */ { MAD_F(0x042b4f2f) /* 0.260573564 */, 19 },
7580 /* 7107 */ { MAD_F(0x042b8274) /* 0.260622458 */, 19 },
7581 /* 7108 */ { MAD_F(0x042bb5ba) /* 0.260671354 */, 19 },
7582 /* 7109 */ { MAD_F(0x042be900) /* 0.260720252 */, 19 },
7583 /* 7110 */ { MAD_F(0x042c1c46) /* 0.260769153 */, 19 },
7584 /* 7111 */ { MAD_F(0x042c4f8e) /* 0.260818056 */, 19 },
7585 /* 7112 */ { MAD_F(0x042c82d6) /* 0.260866961 */, 19 },
7586 /* 7113 */ { MAD_F(0x042cb61e) /* 0.260915869 */, 19 },
7587 /* 7114 */ { MAD_F(0x042ce967) /* 0.260964779 */, 19 },
7588 /* 7115 */ { MAD_F(0x042d1cb1) /* 0.261013691 */, 19 },
7589 /* 7116 */ { MAD_F(0x042d4ffb) /* 0.261062606 */, 19 },
7590 /* 7117 */ { MAD_F(0x042d8346) /* 0.261111522 */, 19 },
7591 /* 7118 */ { MAD_F(0x042db692) /* 0.261160441 */, 19 },
7592 /* 7119 */ { MAD_F(0x042de9de) /* 0.261209363 */, 19 },
7593
7594 /* 7120 */ { MAD_F(0x042e1d2b) /* 0.261258286 */, 19 },
7595 /* 7121 */ { MAD_F(0x042e5078) /* 0.261307212 */, 19 },
7596 /* 7122 */ { MAD_F(0x042e83c6) /* 0.261356140 */, 19 },
7597 /* 7123 */ { MAD_F(0x042eb715) /* 0.261405071 */, 19 },
7598 /* 7124 */ { MAD_F(0x042eea64) /* 0.261454004 */, 19 },
7599 /* 7125 */ { MAD_F(0x042f1db4) /* 0.261502939 */, 19 },
7600 /* 7126 */ { MAD_F(0x042f5105) /* 0.261551876 */, 19 },
7601 /* 7127 */ { MAD_F(0x042f8456) /* 0.261600816 */, 19 },
7602 /* 7128 */ { MAD_F(0x042fb7a8) /* 0.261649758 */, 19 },
7603 /* 7129 */ { MAD_F(0x042feafa) /* 0.261698702 */, 19 },
7604 /* 7130 */ { MAD_F(0x04301e4d) /* 0.261747649 */, 19 },
7605 /* 7131 */ { MAD_F(0x043051a1) /* 0.261796597 */, 19 },
7606 /* 7132 */ { MAD_F(0x043084f5) /* 0.261845548 */, 19 },
7607 /* 7133 */ { MAD_F(0x0430b84a) /* 0.261894502 */, 19 },
7608 /* 7134 */ { MAD_F(0x0430eb9f) /* 0.261943458 */, 19 },
7609 /* 7135 */ { MAD_F(0x04311ef5) /* 0.261992416 */, 19 },
7610
7611 /* 7136 */ { MAD_F(0x0431524c) /* 0.262041376 */, 19 },
7612 /* 7137 */ { MAD_F(0x043185a3) /* 0.262090338 */, 19 },
7613 /* 7138 */ { MAD_F(0x0431b8fb) /* 0.262139303 */, 19 },
7614 /* 7139 */ { MAD_F(0x0431ec54) /* 0.262188270 */, 19 },
7615 /* 7140 */ { MAD_F(0x04321fad) /* 0.262237240 */, 19 },
7616 /* 7141 */ { MAD_F(0x04325306) /* 0.262286211 */, 19 },
7617 /* 7142 */ { MAD_F(0x04328661) /* 0.262335185 */, 19 },
7618 /* 7143 */ { MAD_F(0x0432b9bc) /* 0.262384162 */, 19 },
7619 /* 7144 */ { MAD_F(0x0432ed17) /* 0.262433140 */, 19 },
7620 /* 7145 */ { MAD_F(0x04332074) /* 0.262482121 */, 19 },
7621 /* 7146 */ { MAD_F(0x043353d0) /* 0.262531104 */, 19 },
7622 /* 7147 */ { MAD_F(0x0433872e) /* 0.262580089 */, 19 },
7623 /* 7148 */ { MAD_F(0x0433ba8c) /* 0.262629077 */, 19 },
7624 /* 7149 */ { MAD_F(0x0433edea) /* 0.262678067 */, 19 },
7625 /* 7150 */ { MAD_F(0x0434214a) /* 0.262727059 */, 19 },
7626 /* 7151 */ { MAD_F(0x043454aa) /* 0.262776054 */, 19 },
7627
7628 /* 7152 */ { MAD_F(0x0434880a) /* 0.262825051 */, 19 },
7629 /* 7153 */ { MAD_F(0x0434bb6b) /* 0.262874050 */, 19 },
7630 /* 7154 */ { MAD_F(0x0434eecd) /* 0.262923051 */, 19 },
7631 /* 7155 */ { MAD_F(0x0435222f) /* 0.262972055 */, 19 },
7632 /* 7156 */ { MAD_F(0x04355592) /* 0.263021061 */, 19 },
7633 /* 7157 */ { MAD_F(0x043588f6) /* 0.263070069 */, 19 },
7634 /* 7158 */ { MAD_F(0x0435bc5a) /* 0.263119079 */, 19 },
7635 /* 7159 */ { MAD_F(0x0435efbf) /* 0.263168092 */, 19 },
7636 /* 7160 */ { MAD_F(0x04362324) /* 0.263217107 */, 19 },
7637 /* 7161 */ { MAD_F(0x0436568a) /* 0.263266125 */, 19 },
7638 /* 7162 */ { MAD_F(0x043689f1) /* 0.263315144 */, 19 },
7639 /* 7163 */ { MAD_F(0x0436bd58) /* 0.263364166 */, 19 },
7640 /* 7164 */ { MAD_F(0x0436f0c0) /* 0.263413191 */, 19 },
7641 /* 7165 */ { MAD_F(0x04372428) /* 0.263462217 */, 19 },
7642 /* 7166 */ { MAD_F(0x04375791) /* 0.263511246 */, 19 },
7643 /* 7167 */ { MAD_F(0x04378afb) /* 0.263560277 */, 19 },
7644
7645 /* 7168 */ { MAD_F(0x0437be65) /* 0.263609310 */, 19 },
7646 /* 7169 */ { MAD_F(0x0437f1d0) /* 0.263658346 */, 19 },
7647 /* 7170 */ { MAD_F(0x0438253c) /* 0.263707384 */, 19 },
7648 /* 7171 */ { MAD_F(0x043858a8) /* 0.263756424 */, 19 },
7649 /* 7172 */ { MAD_F(0x04388c14) /* 0.263805466 */, 19 },
7650 /* 7173 */ { MAD_F(0x0438bf82) /* 0.263854511 */, 19 },
7651 /* 7174 */ { MAD_F(0x0438f2f0) /* 0.263903558 */, 19 },
7652 /* 7175 */ { MAD_F(0x0439265e) /* 0.263952607 */, 19 },
7653 /* 7176 */ { MAD_F(0x043959cd) /* 0.264001659 */, 19 },
7654 /* 7177 */ { MAD_F(0x04398d3d) /* 0.264050713 */, 19 },
7655 /* 7178 */ { MAD_F(0x0439c0ae) /* 0.264099769 */, 19 },
7656 /* 7179 */ { MAD_F(0x0439f41f) /* 0.264148827 */, 19 },
7657 /* 7180 */ { MAD_F(0x043a2790) /* 0.264197888 */, 19 },
7658 /* 7181 */ { MAD_F(0x043a5b02) /* 0.264246951 */, 19 },
7659 /* 7182 */ { MAD_F(0x043a8e75) /* 0.264296016 */, 19 },
7660 /* 7183 */ { MAD_F(0x043ac1e9) /* 0.264345084 */, 19 },
7661
7662 /* 7184 */ { MAD_F(0x043af55d) /* 0.264394153 */, 19 },
7663 /* 7185 */ { MAD_F(0x043b28d2) /* 0.264443225 */, 19 },
7664 /* 7186 */ { MAD_F(0x043b5c47) /* 0.264492300 */, 19 },
7665 /* 7187 */ { MAD_F(0x043b8fbd) /* 0.264541376 */, 19 },
7666 /* 7188 */ { MAD_F(0x043bc333) /* 0.264590455 */, 19 },
7667 /* 7189 */ { MAD_F(0x043bf6aa) /* 0.264639536 */, 19 },
7668 /* 7190 */ { MAD_F(0x043c2a22) /* 0.264688620 */, 19 },
7669 /* 7191 */ { MAD_F(0x043c5d9a) /* 0.264737706 */, 19 },
7670 /* 7192 */ { MAD_F(0x043c9113) /* 0.264786794 */, 19 },
7671 /* 7193 */ { MAD_F(0x043cc48d) /* 0.264835884 */, 19 },
7672 /* 7194 */ { MAD_F(0x043cf807) /* 0.264884976 */, 19 },
7673 /* 7195 */ { MAD_F(0x043d2b82) /* 0.264934071 */, 19 },
7674 /* 7196 */ { MAD_F(0x043d5efd) /* 0.264983168 */, 19 },
7675 /* 7197 */ { MAD_F(0x043d9279) /* 0.265032268 */, 19 },
7676 /* 7198 */ { MAD_F(0x043dc5f6) /* 0.265081369 */, 19 },
7677 /* 7199 */ { MAD_F(0x043df973) /* 0.265130473 */, 19 },
7678
7679 /* 7200 */ { MAD_F(0x043e2cf1) /* 0.265179580 */, 19 },
7680 /* 7201 */ { MAD_F(0x043e6070) /* 0.265228688 */, 19 },
7681 /* 7202 */ { MAD_F(0x043e93ef) /* 0.265277799 */, 19 },
7682 /* 7203 */ { MAD_F(0x043ec76e) /* 0.265326912 */, 19 },
7683 /* 7204 */ { MAD_F(0x043efaef) /* 0.265376027 */, 19 },
7684 /* 7205 */ { MAD_F(0x043f2e6f) /* 0.265425145 */, 19 },
7685 /* 7206 */ { MAD_F(0x043f61f1) /* 0.265474264 */, 19 },
7686 /* 7207 */ { MAD_F(0x043f9573) /* 0.265523387 */, 19 },
7687 /* 7208 */ { MAD_F(0x043fc8f6) /* 0.265572511 */, 19 },
7688 /* 7209 */ { MAD_F(0x043ffc79) /* 0.265621638 */, 19 },
7689 /* 7210 */ { MAD_F(0x04402ffd) /* 0.265670766 */, 19 },
7690 /* 7211 */ { MAD_F(0x04406382) /* 0.265719898 */, 19 },
7691 /* 7212 */ { MAD_F(0x04409707) /* 0.265769031 */, 19 },
7692 /* 7213 */ { MAD_F(0x0440ca8d) /* 0.265818167 */, 19 },
7693 /* 7214 */ { MAD_F(0x0440fe13) /* 0.265867305 */, 19 },
7694 /* 7215 */ { MAD_F(0x0441319a) /* 0.265916445 */, 19 },
7695
7696 /* 7216 */ { MAD_F(0x04416522) /* 0.265965588 */, 19 },
7697 /* 7217 */ { MAD_F(0x044198aa) /* 0.266014732 */, 19 },
7698 /* 7218 */ { MAD_F(0x0441cc33) /* 0.266063880 */, 19 },
7699 /* 7219 */ { MAD_F(0x0441ffbc) /* 0.266113029 */, 19 },
7700 /* 7220 */ { MAD_F(0x04423346) /* 0.266162181 */, 19 },
7701 /* 7221 */ { MAD_F(0x044266d1) /* 0.266211334 */, 19 },
7702 /* 7222 */ { MAD_F(0x04429a5c) /* 0.266260491 */, 19 },
7703 /* 7223 */ { MAD_F(0x0442cde8) /* 0.266309649 */, 19 },
7704 /* 7224 */ { MAD_F(0x04430174) /* 0.266358810 */, 19 },
7705 /* 7225 */ { MAD_F(0x04433501) /* 0.266407973 */, 19 },
7706 /* 7226 */ { MAD_F(0x0443688f) /* 0.266457138 */, 19 },
7707 /* 7227 */ { MAD_F(0x04439c1d) /* 0.266506305 */, 19 },
7708 /* 7228 */ { MAD_F(0x0443cfac) /* 0.266555475 */, 19 },
7709 /* 7229 */ { MAD_F(0x0444033c) /* 0.266604647 */, 19 },
7710 /* 7230 */ { MAD_F(0x044436cc) /* 0.266653822 */, 19 },
7711 /* 7231 */ { MAD_F(0x04446a5d) /* 0.266702998 */, 19 },
7712
7713 /* 7232 */ { MAD_F(0x04449dee) /* 0.266752177 */, 19 },
7714 /* 7233 */ { MAD_F(0x0444d180) /* 0.266801358 */, 19 },
7715 /* 7234 */ { MAD_F(0x04450513) /* 0.266850541 */, 19 },
7716 /* 7235 */ { MAD_F(0x044538a6) /* 0.266899727 */, 19 },
7717 /* 7236 */ { MAD_F(0x04456c39) /* 0.266948915 */, 19 },
7718 /* 7237 */ { MAD_F(0x04459fce) /* 0.266998105 */, 19 },
7719 /* 7238 */ { MAD_F(0x0445d363) /* 0.267047298 */, 19 },
7720 /* 7239 */ { MAD_F(0x044606f8) /* 0.267096492 */, 19 },
7721 /* 7240 */ { MAD_F(0x04463a8f) /* 0.267145689 */, 19 },
7722 /* 7241 */ { MAD_F(0x04466e25) /* 0.267194888 */, 19 },
7723 /* 7242 */ { MAD_F(0x0446a1bd) /* 0.267244090 */, 19 },
7724 /* 7243 */ { MAD_F(0x0446d555) /* 0.267293294 */, 19 },
7725 /* 7244 */ { MAD_F(0x044708ee) /* 0.267342500 */, 19 },
7726 /* 7245 */ { MAD_F(0x04473c87) /* 0.267391708 */, 19 },
7727 /* 7246 */ { MAD_F(0x04477021) /* 0.267440919 */, 19 },
7728 /* 7247 */ { MAD_F(0x0447a3bb) /* 0.267490131 */, 19 },
7729
7730 /* 7248 */ { MAD_F(0x0447d756) /* 0.267539347 */, 19 },
7731 /* 7249 */ { MAD_F(0x04480af2) /* 0.267588564 */, 19 },
7732 /* 7250 */ { MAD_F(0x04483e8e) /* 0.267637783 */, 19 },
7733 /* 7251 */ { MAD_F(0x0448722b) /* 0.267687005 */, 19 },
7734 /* 7252 */ { MAD_F(0x0448a5c9) /* 0.267736229 */, 19 },
7735 /* 7253 */ { MAD_F(0x0448d967) /* 0.267785456 */, 19 },
7736 /* 7254 */ { MAD_F(0x04490d05) /* 0.267834685 */, 19 },
7737 /* 7255 */ { MAD_F(0x044940a5) /* 0.267883915 */, 19 },
7738 /* 7256 */ { MAD_F(0x04497445) /* 0.267933149 */, 19 },
7739 /* 7257 */ { MAD_F(0x0449a7e5) /* 0.267982384 */, 19 },
7740 /* 7258 */ { MAD_F(0x0449db86) /* 0.268031622 */, 19 },
7741 /* 7259 */ { MAD_F(0x044a0f28) /* 0.268080862 */, 19 },
7742 /* 7260 */ { MAD_F(0x044a42ca) /* 0.268130104 */, 19 },
7743 /* 7261 */ { MAD_F(0x044a766d) /* 0.268179349 */, 19 },
7744 /* 7262 */ { MAD_F(0x044aaa11) /* 0.268228595 */, 19 },
7745 /* 7263 */ { MAD_F(0x044addb5) /* 0.268277844 */, 19 },
7746
7747 /* 7264 */ { MAD_F(0x044b115a) /* 0.268327096 */, 19 },
7748 /* 7265 */ { MAD_F(0x044b44ff) /* 0.268376349 */, 19 },
7749 /* 7266 */ { MAD_F(0x044b78a5) /* 0.268425605 */, 19 },
7750 /* 7267 */ { MAD_F(0x044bac4c) /* 0.268474863 */, 19 },
7751 /* 7268 */ { MAD_F(0x044bdff3) /* 0.268524123 */, 19 },
7752 /* 7269 */ { MAD_F(0x044c139b) /* 0.268573386 */, 19 },
7753 /* 7270 */ { MAD_F(0x044c4743) /* 0.268622651 */, 19 },
7754 /* 7271 */ { MAD_F(0x044c7aec) /* 0.268671918 */, 19 },
7755 /* 7272 */ { MAD_F(0x044cae96) /* 0.268721187 */, 19 },
7756 /* 7273 */ { MAD_F(0x044ce240) /* 0.268770459 */, 19 },
7757 /* 7274 */ { MAD_F(0x044d15eb) /* 0.268819733 */, 19 },
7758 /* 7275 */ { MAD_F(0x044d4997) /* 0.268869009 */, 19 },
7759 /* 7276 */ { MAD_F(0x044d7d43) /* 0.268918287 */, 19 },
7760 /* 7277 */ { MAD_F(0x044db0ef) /* 0.268967568 */, 19 },
7761 /* 7278 */ { MAD_F(0x044de49d) /* 0.269016851 */, 19 },
7762 /* 7279 */ { MAD_F(0x044e184b) /* 0.269066136 */, 19 },
7763
7764 /* 7280 */ { MAD_F(0x044e4bf9) /* 0.269115423 */, 19 },
7765 /* 7281 */ { MAD_F(0x044e7fa8) /* 0.269164713 */, 19 },
7766 /* 7282 */ { MAD_F(0x044eb358) /* 0.269214005 */, 19 },
7767 /* 7283 */ { MAD_F(0x044ee708) /* 0.269263299 */, 19 },
7768 /* 7284 */ { MAD_F(0x044f1ab9) /* 0.269312595 */, 19 },
7769 /* 7285 */ { MAD_F(0x044f4e6b) /* 0.269361894 */, 19 },
7770 /* 7286 */ { MAD_F(0x044f821d) /* 0.269411195 */, 19 },
7771 /* 7287 */ { MAD_F(0x044fb5cf) /* 0.269460498 */, 19 },
7772 /* 7288 */ { MAD_F(0x044fe983) /* 0.269509804 */, 19 },
7773 /* 7289 */ { MAD_F(0x04501d37) /* 0.269559111 */, 19 },
7774 /* 7290 */ { MAD_F(0x045050eb) /* 0.269608421 */, 19 },
7775 /* 7291 */ { MAD_F(0x045084a0) /* 0.269657734 */, 19 },
7776 /* 7292 */ { MAD_F(0x0450b856) /* 0.269707048 */, 19 },
7777 /* 7293 */ { MAD_F(0x0450ec0d) /* 0.269756365 */, 19 },
7778 /* 7294 */ { MAD_F(0x04511fc4) /* 0.269805684 */, 19 },
7779 /* 7295 */ { MAD_F(0x0451537b) /* 0.269855005 */, 19 },
7780
7781 /* 7296 */ { MAD_F(0x04518733) /* 0.269904329 */, 19 },
7782 /* 7297 */ { MAD_F(0x0451baec) /* 0.269953654 */, 19 },
7783 /* 7298 */ { MAD_F(0x0451eea5) /* 0.270002982 */, 19 },
7784 /* 7299 */ { MAD_F(0x0452225f) /* 0.270052313 */, 19 },
7785 /* 7300 */ { MAD_F(0x0452561a) /* 0.270101645 */, 19 },
7786 /* 7301 */ { MAD_F(0x045289d5) /* 0.270150980 */, 19 },
7787 /* 7302 */ { MAD_F(0x0452bd91) /* 0.270200317 */, 19 },
7788 /* 7303 */ { MAD_F(0x0452f14d) /* 0.270249656 */, 19 },
7789 /* 7304 */ { MAD_F(0x0453250a) /* 0.270298998 */, 19 },
7790 /* 7305 */ { MAD_F(0x045358c8) /* 0.270348341 */, 19 },
7791 /* 7306 */ { MAD_F(0x04538c86) /* 0.270397687 */, 19 },
7792 /* 7307 */ { MAD_F(0x0453c045) /* 0.270447036 */, 19 },
7793 /* 7308 */ { MAD_F(0x0453f405) /* 0.270496386 */, 19 },
7794 /* 7309 */ { MAD_F(0x045427c5) /* 0.270545739 */, 19 },
7795 /* 7310 */ { MAD_F(0x04545b85) /* 0.270595094 */, 19 },
7796 /* 7311 */ { MAD_F(0x04548f46) /* 0.270644451 */, 19 },
7797
7798 /* 7312 */ { MAD_F(0x0454c308) /* 0.270693811 */, 19 },
7799 /* 7313 */ { MAD_F(0x0454f6cb) /* 0.270743173 */, 19 },
7800 /* 7314 */ { MAD_F(0x04552a8e) /* 0.270792537 */, 19 },
7801 /* 7315 */ { MAD_F(0x04555e51) /* 0.270841903 */, 19 },
7802 /* 7316 */ { MAD_F(0x04559216) /* 0.270891271 */, 19 },
7803 /* 7317 */ { MAD_F(0x0455c5db) /* 0.270940642 */, 19 },
7804 /* 7318 */ { MAD_F(0x0455f9a0) /* 0.270990015 */, 19 },
7805 /* 7319 */ { MAD_F(0x04562d66) /* 0.271039390 */, 19 },
7806 /* 7320 */ { MAD_F(0x0456612d) /* 0.271088768 */, 19 },
7807 /* 7321 */ { MAD_F(0x045694f4) /* 0.271138148 */, 19 },
7808 /* 7322 */ { MAD_F(0x0456c8bc) /* 0.271187530 */, 19 },
7809 /* 7323 */ { MAD_F(0x0456fc84) /* 0.271236914 */, 19 },
7810 /* 7324 */ { MAD_F(0x0457304e) /* 0.271286301 */, 19 },
7811 /* 7325 */ { MAD_F(0x04576417) /* 0.271335689 */, 19 },
7812 /* 7326 */ { MAD_F(0x045797e2) /* 0.271385080 */, 19 },
7813 /* 7327 */ { MAD_F(0x0457cbac) /* 0.271434474 */, 19 },
7814
7815 /* 7328 */ { MAD_F(0x0457ff78) /* 0.271483869 */, 19 },
7816 /* 7329 */ { MAD_F(0x04583344) /* 0.271533267 */, 19 },
7817 /* 7330 */ { MAD_F(0x04586711) /* 0.271582667 */, 19 },
7818 /* 7331 */ { MAD_F(0x04589ade) /* 0.271632069 */, 19 },
7819 /* 7332 */ { MAD_F(0x0458ceac) /* 0.271681474 */, 19 },
7820 /* 7333 */ { MAD_F(0x0459027b) /* 0.271730880 */, 19 },
7821 /* 7334 */ { MAD_F(0x0459364a) /* 0.271780289 */, 19 },
7822 /* 7335 */ { MAD_F(0x04596a19) /* 0.271829701 */, 19 },
7823 /* 7336 */ { MAD_F(0x04599dea) /* 0.271879114 */, 19 },
7824 /* 7337 */ { MAD_F(0x0459d1bb) /* 0.271928530 */, 19 },
7825 /* 7338 */ { MAD_F(0x045a058c) /* 0.271977948 */, 19 },
7826 /* 7339 */ { MAD_F(0x045a395e) /* 0.272027368 */, 19 },
7827 /* 7340 */ { MAD_F(0x045a6d31) /* 0.272076790 */, 19 },
7828 /* 7341 */ { MAD_F(0x045aa104) /* 0.272126215 */, 19 },
7829 /* 7342 */ { MAD_F(0x045ad4d8) /* 0.272175642 */, 19 },
7830 /* 7343 */ { MAD_F(0x045b08ad) /* 0.272225071 */, 19 },
7831
7832 /* 7344 */ { MAD_F(0x045b3c82) /* 0.272274503 */, 19 },
7833 /* 7345 */ { MAD_F(0x045b7058) /* 0.272323936 */, 19 },
7834 /* 7346 */ { MAD_F(0x045ba42e) /* 0.272373372 */, 19 },
7835 /* 7347 */ { MAD_F(0x045bd805) /* 0.272422810 */, 19 },
7836 /* 7348 */ { MAD_F(0x045c0bdd) /* 0.272472251 */, 19 },
7837 /* 7349 */ { MAD_F(0x045c3fb5) /* 0.272521693 */, 19 },
7838 /* 7350 */ { MAD_F(0x045c738e) /* 0.272571138 */, 19 },
7839 /* 7351 */ { MAD_F(0x045ca767) /* 0.272620585 */, 19 },
7840 /* 7352 */ { MAD_F(0x045cdb41) /* 0.272670035 */, 19 },
7841 /* 7353 */ { MAD_F(0x045d0f1b) /* 0.272719486 */, 19 },
7842 /* 7354 */ { MAD_F(0x045d42f7) /* 0.272768940 */, 19 },
7843 /* 7355 */ { MAD_F(0x045d76d2) /* 0.272818396 */, 19 },
7844 /* 7356 */ { MAD_F(0x045daaaf) /* 0.272867855 */, 19 },
7845 /* 7357 */ { MAD_F(0x045dde8c) /* 0.272917315 */, 19 },
7846 /* 7358 */ { MAD_F(0x045e1269) /* 0.272966778 */, 19 },
7847 /* 7359 */ { MAD_F(0x045e4647) /* 0.273016243 */, 19 },
7848
7849 /* 7360 */ { MAD_F(0x045e7a26) /* 0.273065710 */, 19 },
7850 /* 7361 */ { MAD_F(0x045eae06) /* 0.273115180 */, 19 },
7851 /* 7362 */ { MAD_F(0x045ee1e6) /* 0.273164652 */, 19 },
7852 /* 7363 */ { MAD_F(0x045f15c6) /* 0.273214126 */, 19 },
7853 /* 7364 */ { MAD_F(0x045f49a7) /* 0.273263602 */, 19 },
7854 /* 7365 */ { MAD_F(0x045f7d89) /* 0.273313081 */, 19 },
7855 /* 7366 */ { MAD_F(0x045fb16c) /* 0.273362561 */, 19 },
7856 /* 7367 */ { MAD_F(0x045fe54f) /* 0.273412044 */, 19 },
7857 /* 7368 */ { MAD_F(0x04601932) /* 0.273461530 */, 19 },
7858 /* 7369 */ { MAD_F(0x04604d16) /* 0.273511017 */, 19 },
7859 /* 7370 */ { MAD_F(0x046080fb) /* 0.273560507 */, 19 },
7860 /* 7371 */ { MAD_F(0x0460b4e1) /* 0.273609999 */, 19 },
7861 /* 7372 */ { MAD_F(0x0460e8c7) /* 0.273659493 */, 19 },
7862 /* 7373 */ { MAD_F(0x04611cad) /* 0.273708989 */, 19 },
7863 /* 7374 */ { MAD_F(0x04615094) /* 0.273758488 */, 19 },
7864 /* 7375 */ { MAD_F(0x0461847c) /* 0.273807989 */, 19 },
7865
7866 /* 7376 */ { MAD_F(0x0461b864) /* 0.273857492 */, 19 },
7867 /* 7377 */ { MAD_F(0x0461ec4d) /* 0.273906997 */, 19 },
7868 /* 7378 */ { MAD_F(0x04622037) /* 0.273956505 */, 19 },
7869 /* 7379 */ { MAD_F(0x04625421) /* 0.274006015 */, 19 },
7870 /* 7380 */ { MAD_F(0x0462880c) /* 0.274055527 */, 19 },
7871 /* 7381 */ { MAD_F(0x0462bbf7) /* 0.274105041 */, 19 },
7872 /* 7382 */ { MAD_F(0x0462efe3) /* 0.274154558 */, 19 },
7873 /* 7383 */ { MAD_F(0x046323d0) /* 0.274204076 */, 19 },
7874 /* 7384 */ { MAD_F(0x046357bd) /* 0.274253597 */, 19 },
7875 /* 7385 */ { MAD_F(0x04638bab) /* 0.274303121 */, 19 },
7876 /* 7386 */ { MAD_F(0x0463bf99) /* 0.274352646 */, 19 },
7877 /* 7387 */ { MAD_F(0x0463f388) /* 0.274402174 */, 19 },
7878 /* 7388 */ { MAD_F(0x04642778) /* 0.274451704 */, 19 },
7879 /* 7389 */ { MAD_F(0x04645b68) /* 0.274501236 */, 19 },
7880 /* 7390 */ { MAD_F(0x04648f59) /* 0.274550771 */, 19 },
7881 /* 7391 */ { MAD_F(0x0464c34a) /* 0.274600307 */, 19 },
7882
7883 /* 7392 */ { MAD_F(0x0464f73c) /* 0.274649846 */, 19 },
7884 /* 7393 */ { MAD_F(0x04652b2f) /* 0.274699387 */, 19 },
7885 /* 7394 */ { MAD_F(0x04655f22) /* 0.274748931 */, 19 },
7886 /* 7395 */ { MAD_F(0x04659316) /* 0.274798476 */, 19 },
7887 /* 7396 */ { MAD_F(0x0465c70a) /* 0.274848024 */, 19 },
7888 /* 7397 */ { MAD_F(0x0465faff) /* 0.274897574 */, 19 },
7889 /* 7398 */ { MAD_F(0x04662ef5) /* 0.274947126 */, 19 },
7890 /* 7399 */ { MAD_F(0x046662eb) /* 0.274996681 */, 19 },
7891 /* 7400 */ { MAD_F(0x046696e2) /* 0.275046238 */, 19 },
7892 /* 7401 */ { MAD_F(0x0466cad9) /* 0.275095797 */, 19 },
7893 /* 7402 */ { MAD_F(0x0466fed1) /* 0.275145358 */, 19 },
7894 /* 7403 */ { MAD_F(0x046732ca) /* 0.275194921 */, 19 },
7895 /* 7404 */ { MAD_F(0x046766c3) /* 0.275244487 */, 19 },
7896 /* 7405 */ { MAD_F(0x04679abd) /* 0.275294055 */, 19 },
7897 /* 7406 */ { MAD_F(0x0467ceb7) /* 0.275343625 */, 19 },
7898 /* 7407 */ { MAD_F(0x046802b2) /* 0.275393198 */, 19 },
7899
7900 /* 7408 */ { MAD_F(0x046836ae) /* 0.275442772 */, 19 },
7901 /* 7409 */ { MAD_F(0x04686aaa) /* 0.275492349 */, 19 },
7902 /* 7410 */ { MAD_F(0x04689ea7) /* 0.275541928 */, 19 },
7903 /* 7411 */ { MAD_F(0x0468d2a4) /* 0.275591509 */, 19 },
7904 /* 7412 */ { MAD_F(0x046906a2) /* 0.275641093 */, 19 },
7905 /* 7413 */ { MAD_F(0x04693aa1) /* 0.275690679 */, 19 },
7906 /* 7414 */ { MAD_F(0x04696ea0) /* 0.275740267 */, 19 },
7907 /* 7415 */ { MAD_F(0x0469a2a0) /* 0.275789857 */, 19 },
7908 /* 7416 */ { MAD_F(0x0469d6a0) /* 0.275839449 */, 19 },
7909 /* 7417 */ { MAD_F(0x046a0aa1) /* 0.275889044 */, 19 },
7910 /* 7418 */ { MAD_F(0x046a3ea3) /* 0.275938641 */, 19 },
7911 /* 7419 */ { MAD_F(0x046a72a5) /* 0.275988240 */, 19 },
7912 /* 7420 */ { MAD_F(0x046aa6a8) /* 0.276037842 */, 19 },
7913 /* 7421 */ { MAD_F(0x046adaab) /* 0.276087445 */, 19 },
7914 /* 7422 */ { MAD_F(0x046b0eaf) /* 0.276137051 */, 19 },
7915 /* 7423 */ { MAD_F(0x046b42b3) /* 0.276186659 */, 19 },
7916
7917 /* 7424 */ { MAD_F(0x046b76b9) /* 0.276236269 */, 19 },
7918 /* 7425 */ { MAD_F(0x046baabe) /* 0.276285882 */, 19 },
7919 /* 7426 */ { MAD_F(0x046bdec5) /* 0.276335497 */, 19 },
7920 /* 7427 */ { MAD_F(0x046c12cc) /* 0.276385113 */, 19 },
7921 /* 7428 */ { MAD_F(0x046c46d3) /* 0.276434733 */, 19 },
7922 /* 7429 */ { MAD_F(0x046c7adb) /* 0.276484354 */, 19 },
7923 /* 7430 */ { MAD_F(0x046caee4) /* 0.276533978 */, 19 },
7924 /* 7431 */ { MAD_F(0x046ce2ee) /* 0.276583604 */, 19 },
7925 /* 7432 */ { MAD_F(0x046d16f7) /* 0.276633232 */, 19 },
7926 /* 7433 */ { MAD_F(0x046d4b02) /* 0.276682862 */, 19 },
7927 /* 7434 */ { MAD_F(0x046d7f0d) /* 0.276732495 */, 19 },
7928 /* 7435 */ { MAD_F(0x046db319) /* 0.276782129 */, 19 },
7929 /* 7436 */ { MAD_F(0x046de725) /* 0.276831766 */, 19 },
7930 /* 7437 */ { MAD_F(0x046e1b32) /* 0.276881406 */, 19 },
7931 /* 7438 */ { MAD_F(0x046e4f40) /* 0.276931047 */, 19 },
7932 /* 7439 */ { MAD_F(0x046e834e) /* 0.276980691 */, 19 },
7933
7934 /* 7440 */ { MAD_F(0x046eb75c) /* 0.277030337 */, 19 },
7935 /* 7441 */ { MAD_F(0x046eeb6c) /* 0.277079985 */, 19 },
7936 /* 7442 */ { MAD_F(0x046f1f7c) /* 0.277129635 */, 19 },
7937 /* 7443 */ { MAD_F(0x046f538c) /* 0.277179288 */, 19 },
7938 /* 7444 */ { MAD_F(0x046f879d) /* 0.277228942 */, 19 },
7939 /* 7445 */ { MAD_F(0x046fbbaf) /* 0.277278600 */, 19 },
7940 /* 7446 */ { MAD_F(0x046fefc1) /* 0.277328259 */, 19 },
7941 /* 7447 */ { MAD_F(0x047023d4) /* 0.277377920 */, 19 },
7942 /* 7448 */ { MAD_F(0x047057e8) /* 0.277427584 */, 19 },
7943 /* 7449 */ { MAD_F(0x04708bfc) /* 0.277477250 */, 19 },
7944 /* 7450 */ { MAD_F(0x0470c011) /* 0.277526918 */, 19 },
7945 /* 7451 */ { MAD_F(0x0470f426) /* 0.277576588 */, 19 },
7946 /* 7452 */ { MAD_F(0x0471283c) /* 0.277626261 */, 19 },
7947 /* 7453 */ { MAD_F(0x04715c52) /* 0.277675936 */, 19 },
7948 /* 7454 */ { MAD_F(0x04719069) /* 0.277725613 */, 19 },
7949 /* 7455 */ { MAD_F(0x0471c481) /* 0.277775292 */, 19 },
7950
7951 /* 7456 */ { MAD_F(0x0471f899) /* 0.277824973 */, 19 },
7952 /* 7457 */ { MAD_F(0x04722cb2) /* 0.277874657 */, 19 },
7953 /* 7458 */ { MAD_F(0x047260cc) /* 0.277924343 */, 19 },
7954 /* 7459 */ { MAD_F(0x047294e6) /* 0.277974031 */, 19 },
7955 /* 7460 */ { MAD_F(0x0472c900) /* 0.278023722 */, 19 },
7956 /* 7461 */ { MAD_F(0x0472fd1b) /* 0.278073414 */, 19 },
7957 /* 7462 */ { MAD_F(0x04733137) /* 0.278123109 */, 19 },
7958 /* 7463 */ { MAD_F(0x04736554) /* 0.278172806 */, 19 },
7959 /* 7464 */ { MAD_F(0x04739971) /* 0.278222505 */, 19 },
7960 /* 7465 */ { MAD_F(0x0473cd8e) /* 0.278272207 */, 19 },
7961 /* 7466 */ { MAD_F(0x047401ad) /* 0.278321910 */, 19 },
7962 /* 7467 */ { MAD_F(0x047435cb) /* 0.278371616 */, 19 },
7963 /* 7468 */ { MAD_F(0x047469eb) /* 0.278421324 */, 19 },
7964 /* 7469 */ { MAD_F(0x04749e0b) /* 0.278471035 */, 19 },
7965 /* 7470 */ { MAD_F(0x0474d22c) /* 0.278520747 */, 19 },
7966 /* 7471 */ { MAD_F(0x0475064d) /* 0.278570462 */, 19 },
7967
7968 /* 7472 */ { MAD_F(0x04753a6f) /* 0.278620179 */, 19 },
7969 /* 7473 */ { MAD_F(0x04756e91) /* 0.278669898 */, 19 },
7970 /* 7474 */ { MAD_F(0x0475a2b4) /* 0.278719619 */, 19 },
7971 /* 7475 */ { MAD_F(0x0475d6d7) /* 0.278769343 */, 19 },
7972 /* 7476 */ { MAD_F(0x04760afc) /* 0.278819069 */, 19 },
7973 /* 7477 */ { MAD_F(0x04763f20) /* 0.278868797 */, 19 },
7974 /* 7478 */ { MAD_F(0x04767346) /* 0.278918527 */, 19 },
7975 /* 7479 */ { MAD_F(0x0476a76c) /* 0.278968260 */, 19 },
7976 /* 7480 */ { MAD_F(0x0476db92) /* 0.279017995 */, 19 },
7977 /* 7481 */ { MAD_F(0x04770fba) /* 0.279067731 */, 19 },
7978 /* 7482 */ { MAD_F(0x047743e1) /* 0.279117471 */, 19 },
7979 /* 7483 */ { MAD_F(0x0477780a) /* 0.279167212 */, 19 },
7980 /* 7484 */ { MAD_F(0x0477ac33) /* 0.279216956 */, 19 },
7981 /* 7485 */ { MAD_F(0x0477e05c) /* 0.279266701 */, 19 },
7982 /* 7486 */ { MAD_F(0x04781486) /* 0.279316449 */, 19 },
7983 /* 7487 */ { MAD_F(0x047848b1) /* 0.279366200 */, 19 },
7984
7985 /* 7488 */ { MAD_F(0x04787cdc) /* 0.279415952 */, 19 },
7986 /* 7489 */ { MAD_F(0x0478b108) /* 0.279465707 */, 19 },
7987 /* 7490 */ { MAD_F(0x0478e535) /* 0.279515464 */, 19 },
7988 /* 7491 */ { MAD_F(0x04791962) /* 0.279565223 */, 19 },
7989 /* 7492 */ { MAD_F(0x04794d8f) /* 0.279614984 */, 19 },
7990 /* 7493 */ { MAD_F(0x047981be) /* 0.279664748 */, 19 },
7991 /* 7494 */ { MAD_F(0x0479b5ed) /* 0.279714513 */, 19 },
7992 /* 7495 */ { MAD_F(0x0479ea1c) /* 0.279764281 */, 19 },
7993 /* 7496 */ { MAD_F(0x047a1e4c) /* 0.279814051 */, 19 },
7994 /* 7497 */ { MAD_F(0x047a527d) /* 0.279863824 */, 19 },
7995 /* 7498 */ { MAD_F(0x047a86ae) /* 0.279913598 */, 19 },
7996 /* 7499 */ { MAD_F(0x047abae0) /* 0.279963375 */, 19 },
7997 /* 7500 */ { MAD_F(0x047aef12) /* 0.280013154 */, 19 },
7998 /* 7501 */ { MAD_F(0x047b2346) /* 0.280062935 */, 19 },
7999 /* 7502 */ { MAD_F(0x047b5779) /* 0.280112719 */, 19 },
8000 /* 7503 */ { MAD_F(0x047b8bad) /* 0.280162504 */, 19 },
8001
8002 /* 7504 */ { MAD_F(0x047bbfe2) /* 0.280212292 */, 19 },
8003 /* 7505 */ { MAD_F(0x047bf418) /* 0.280262082 */, 19 },
8004 /* 7506 */ { MAD_F(0x047c284e) /* 0.280311875 */, 19 },
8005 /* 7507 */ { MAD_F(0x047c5c84) /* 0.280361669 */, 19 },
8006 /* 7508 */ { MAD_F(0x047c90bb) /* 0.280411466 */, 19 },
8007 /* 7509 */ { MAD_F(0x047cc4f3) /* 0.280461265 */, 19 },
8008 /* 7510 */ { MAD_F(0x047cf92c) /* 0.280511066 */, 19 },
8009 /* 7511 */ { MAD_F(0x047d2d65) /* 0.280560869 */, 19 },
8010 /* 7512 */ { MAD_F(0x047d619e) /* 0.280610675 */, 19 },
8011 /* 7513 */ { MAD_F(0x047d95d8) /* 0.280660483 */, 19 },
8012 /* 7514 */ { MAD_F(0x047dca13) /* 0.280710292 */, 19 },
8013 /* 7515 */ { MAD_F(0x047dfe4e) /* 0.280760105 */, 19 },
8014 /* 7516 */ { MAD_F(0x047e328a) /* 0.280809919 */, 19 },
8015 /* 7517 */ { MAD_F(0x047e66c7) /* 0.280859736 */, 19 },
8016 /* 7518 */ { MAD_F(0x047e9b04) /* 0.280909554 */, 19 },
8017 /* 7519 */ { MAD_F(0x047ecf42) /* 0.280959375 */, 19 },
8018
8019 /* 7520 */ { MAD_F(0x047f0380) /* 0.281009199 */, 19 },
8020 /* 7521 */ { MAD_F(0x047f37bf) /* 0.281059024 */, 19 },
8021 /* 7522 */ { MAD_F(0x047f6bff) /* 0.281108852 */, 19 },
8022 /* 7523 */ { MAD_F(0x047fa03f) /* 0.281158682 */, 19 },
8023 /* 7524 */ { MAD_F(0x047fd47f) /* 0.281208514 */, 19 },
8024 /* 7525 */ { MAD_F(0x048008c1) /* 0.281258348 */, 19 },
8025 /* 7526 */ { MAD_F(0x04803d02) /* 0.281308184 */, 19 },
8026 /* 7527 */ { MAD_F(0x04807145) /* 0.281358023 */, 19 },
8027 /* 7528 */ { MAD_F(0x0480a588) /* 0.281407864 */, 19 },
8028 /* 7529 */ { MAD_F(0x0480d9cc) /* 0.281457707 */, 19 },
8029 /* 7530 */ { MAD_F(0x04810e10) /* 0.281507552 */, 19 },
8030 /* 7531 */ { MAD_F(0x04814255) /* 0.281557400 */, 19 },
8031 /* 7532 */ { MAD_F(0x0481769a) /* 0.281607250 */, 19 },
8032 /* 7533 */ { MAD_F(0x0481aae0) /* 0.281657101 */, 19 },
8033 /* 7534 */ { MAD_F(0x0481df27) /* 0.281706956 */, 19 },
8034 /* 7535 */ { MAD_F(0x0482136e) /* 0.281756812 */, 19 },
8035
8036 /* 7536 */ { MAD_F(0x048247b6) /* 0.281806670 */, 19 },
8037 /* 7537 */ { MAD_F(0x04827bfe) /* 0.281856531 */, 19 },
8038 /* 7538 */ { MAD_F(0x0482b047) /* 0.281906394 */, 19 },
8039 /* 7539 */ { MAD_F(0x0482e491) /* 0.281956259 */, 19 },
8040 /* 7540 */ { MAD_F(0x048318db) /* 0.282006127 */, 19 },
8041 /* 7541 */ { MAD_F(0x04834d26) /* 0.282055996 */, 19 },
8042 /* 7542 */ { MAD_F(0x04838171) /* 0.282105868 */, 19 },
8043 /* 7543 */ { MAD_F(0x0483b5bd) /* 0.282155742 */, 19 },
8044 /* 7544 */ { MAD_F(0x0483ea0a) /* 0.282205618 */, 19 },
8045 /* 7545 */ { MAD_F(0x04841e57) /* 0.282255496 */, 19 },
8046 /* 7546 */ { MAD_F(0x048452a4) /* 0.282305377 */, 19 },
8047 /* 7547 */ { MAD_F(0x048486f3) /* 0.282355260 */, 19 },
8048 /* 7548 */ { MAD_F(0x0484bb42) /* 0.282405145 */, 19 },
8049 /* 7549 */ { MAD_F(0x0484ef91) /* 0.282455032 */, 19 },
8050 /* 7550 */ { MAD_F(0x048523e1) /* 0.282504921 */, 19 },
8051 /* 7551 */ { MAD_F(0x04855832) /* 0.282554813 */, 19 },
8052
8053 /* 7552 */ { MAD_F(0x04858c83) /* 0.282604707 */, 19 },
8054 /* 7553 */ { MAD_F(0x0485c0d5) /* 0.282654603 */, 19 },
8055 /* 7554 */ { MAD_F(0x0485f527) /* 0.282704501 */, 19 },
8056 /* 7555 */ { MAD_F(0x0486297a) /* 0.282754401 */, 19 },
8057 /* 7556 */ { MAD_F(0x04865dce) /* 0.282804304 */, 19 },
8058 /* 7557 */ { MAD_F(0x04869222) /* 0.282854209 */, 19 },
8059 /* 7558 */ { MAD_F(0x0486c677) /* 0.282904116 */, 19 },
8060 /* 7559 */ { MAD_F(0x0486facc) /* 0.282954025 */, 19 },
8061 /* 7560 */ { MAD_F(0x04872f22) /* 0.283003936 */, 19 },
8062 /* 7561 */ { MAD_F(0x04876379) /* 0.283053850 */, 19 },
8063 /* 7562 */ { MAD_F(0x048797d0) /* 0.283103766 */, 19 },
8064 /* 7563 */ { MAD_F(0x0487cc28) /* 0.283153684 */, 19 },
8065 /* 7564 */ { MAD_F(0x04880080) /* 0.283203604 */, 19 },
8066 /* 7565 */ { MAD_F(0x048834d9) /* 0.283253527 */, 19 },
8067 /* 7566 */ { MAD_F(0x04886933) /* 0.283303451 */, 19 },
8068 /* 7567 */ { MAD_F(0x04889d8d) /* 0.283353378 */, 19 },
8069
8070 /* 7568 */ { MAD_F(0x0488d1e8) /* 0.283403307 */, 19 },
8071 /* 7569 */ { MAD_F(0x04890643) /* 0.283453238 */, 19 },
8072 /* 7570 */ { MAD_F(0x04893a9f) /* 0.283503172 */, 19 },
8073 /* 7571 */ { MAD_F(0x04896efb) /* 0.283553107 */, 19 },
8074 /* 7572 */ { MAD_F(0x0489a358) /* 0.283603045 */, 19 },
8075 /* 7573 */ { MAD_F(0x0489d7b6) /* 0.283652985 */, 19 },
8076 /* 7574 */ { MAD_F(0x048a0c14) /* 0.283702927 */, 19 },
8077 /* 7575 */ { MAD_F(0x048a4073) /* 0.283752872 */, 19 },
8078 /* 7576 */ { MAD_F(0x048a74d3) /* 0.283802818 */, 19 },
8079 /* 7577 */ { MAD_F(0x048aa933) /* 0.283852767 */, 19 },
8080 /* 7578 */ { MAD_F(0x048add93) /* 0.283902718 */, 19 },
8081 /* 7579 */ { MAD_F(0x048b11f5) /* 0.283952671 */, 19 },
8082 /* 7580 */ { MAD_F(0x048b4656) /* 0.284002627 */, 19 },
8083 /* 7581 */ { MAD_F(0x048b7ab9) /* 0.284052584 */, 19 },
8084 /* 7582 */ { MAD_F(0x048baf1c) /* 0.284102544 */, 19 },
8085 /* 7583 */ { MAD_F(0x048be37f) /* 0.284152506 */, 19 },
8086
8087 /* 7584 */ { MAD_F(0x048c17e3) /* 0.284202470 */, 19 },
8088 /* 7585 */ { MAD_F(0x048c4c48) /* 0.284252436 */, 19 },
8089 /* 7586 */ { MAD_F(0x048c80ad) /* 0.284302405 */, 19 },
8090 /* 7587 */ { MAD_F(0x048cb513) /* 0.284352376 */, 19 },
8091 /* 7588 */ { MAD_F(0x048ce97a) /* 0.284402349 */, 19 },
8092 /* 7589 */ { MAD_F(0x048d1de1) /* 0.284452324 */, 19 },
8093 /* 7590 */ { MAD_F(0x048d5249) /* 0.284502301 */, 19 },
8094 /* 7591 */ { MAD_F(0x048d86b1) /* 0.284552281 */, 19 },
8095 /* 7592 */ { MAD_F(0x048dbb1a) /* 0.284602263 */, 19 },
8096 /* 7593 */ { MAD_F(0x048def83) /* 0.284652246 */, 19 },
8097 /* 7594 */ { MAD_F(0x048e23ed) /* 0.284702233 */, 19 },
8098 /* 7595 */ { MAD_F(0x048e5858) /* 0.284752221 */, 19 },
8099 /* 7596 */ { MAD_F(0x048e8cc3) /* 0.284802211 */, 19 },
8100 /* 7597 */ { MAD_F(0x048ec12f) /* 0.284852204 */, 19 },
8101 /* 7598 */ { MAD_F(0x048ef59b) /* 0.284902199 */, 19 },
8102 /* 7599 */ { MAD_F(0x048f2a08) /* 0.284952196 */, 19 },
8103
8104 /* 7600 */ { MAD_F(0x048f5e76) /* 0.285002195 */, 19 },
8105 /* 7601 */ { MAD_F(0x048f92e4) /* 0.285052197 */, 19 },
8106 /* 7602 */ { MAD_F(0x048fc753) /* 0.285102201 */, 19 },
8107 /* 7603 */ { MAD_F(0x048ffbc2) /* 0.285152206 */, 19 },
8108 /* 7604 */ { MAD_F(0x04903032) /* 0.285202214 */, 19 },
8109 /* 7605 */ { MAD_F(0x049064a3) /* 0.285252225 */, 19 },
8110 /* 7606 */ { MAD_F(0x04909914) /* 0.285302237 */, 19 },
8111 /* 7607 */ { MAD_F(0x0490cd86) /* 0.285352252 */, 19 },
8112 /* 7608 */ { MAD_F(0x049101f8) /* 0.285402269 */, 19 },
8113 /* 7609 */ { MAD_F(0x0491366b) /* 0.285452288 */, 19 },
8114 /* 7610 */ { MAD_F(0x04916ade) /* 0.285502309 */, 19 },
8115 /* 7611 */ { MAD_F(0x04919f52) /* 0.285552332 */, 19 },
8116 /* 7612 */ { MAD_F(0x0491d3c7) /* 0.285602358 */, 19 },
8117 /* 7613 */ { MAD_F(0x0492083c) /* 0.285652386 */, 19 },
8118 /* 7614 */ { MAD_F(0x04923cb2) /* 0.285702416 */, 19 },
8119 /* 7615 */ { MAD_F(0x04927128) /* 0.285752448 */, 19 },
8120
8121 /* 7616 */ { MAD_F(0x0492a59f) /* 0.285802482 */, 19 },
8122 /* 7617 */ { MAD_F(0x0492da17) /* 0.285852519 */, 19 },
8123 /* 7618 */ { MAD_F(0x04930e8f) /* 0.285902557 */, 19 },
8124 /* 7619 */ { MAD_F(0x04934308) /* 0.285952598 */, 19 },
8125 /* 7620 */ { MAD_F(0x04937781) /* 0.286002641 */, 19 },
8126 /* 7621 */ { MAD_F(0x0493abfb) /* 0.286052687 */, 19 },
8127 /* 7622 */ { MAD_F(0x0493e076) /* 0.286102734 */, 19 },
8128 /* 7623 */ { MAD_F(0x049414f1) /* 0.286152784 */, 19 },
8129 /* 7624 */ { MAD_F(0x0494496c) /* 0.286202836 */, 19 },
8130 /* 7625 */ { MAD_F(0x04947de9) /* 0.286252890 */, 19 },
8131 /* 7626 */ { MAD_F(0x0494b266) /* 0.286302946 */, 19 },
8132 /* 7627 */ { MAD_F(0x0494e6e3) /* 0.286353005 */, 19 },
8133 /* 7628 */ { MAD_F(0x04951b61) /* 0.286403065 */, 19 },
8134 /* 7629 */ { MAD_F(0x04954fe0) /* 0.286453128 */, 19 },
8135 /* 7630 */ { MAD_F(0x0495845f) /* 0.286503193 */, 19 },
8136 /* 7631 */ { MAD_F(0x0495b8df) /* 0.286553260 */, 19 },
8137
8138 /* 7632 */ { MAD_F(0x0495ed5f) /* 0.286603329 */, 19 },
8139 /* 7633 */ { MAD_F(0x049621e0) /* 0.286653401 */, 19 },
8140 /* 7634 */ { MAD_F(0x04965662) /* 0.286703475 */, 19 },
8141 /* 7635 */ { MAD_F(0x04968ae4) /* 0.286753551 */, 19 },
8142 /* 7636 */ { MAD_F(0x0496bf67) /* 0.286803629 */, 19 },
8143 /* 7637 */ { MAD_F(0x0496f3ea) /* 0.286853709 */, 19 },
8144 /* 7638 */ { MAD_F(0x0497286e) /* 0.286903792 */, 19 },
8145 /* 7639 */ { MAD_F(0x04975cf2) /* 0.286953876 */, 19 },
8146 /* 7640 */ { MAD_F(0x04979177) /* 0.287003963 */, 19 },
8147 /* 7641 */ { MAD_F(0x0497c5fd) /* 0.287054052 */, 19 },
8148 /* 7642 */ { MAD_F(0x0497fa83) /* 0.287104143 */, 19 },
8149 /* 7643 */ { MAD_F(0x04982f0a) /* 0.287154237 */, 19 },
8150 /* 7644 */ { MAD_F(0x04986392) /* 0.287204332 */, 19 },
8151 /* 7645 */ { MAD_F(0x0498981a) /* 0.287254430 */, 19 },
8152 /* 7646 */ { MAD_F(0x0498cca2) /* 0.287304530 */, 19 },
8153 /* 7647 */ { MAD_F(0x0499012c) /* 0.287354632 */, 19 },
8154
8155 /* 7648 */ { MAD_F(0x049935b5) /* 0.287404737 */, 19 },
8156 /* 7649 */ { MAD_F(0x04996a40) /* 0.287454843 */, 19 },
8157 /* 7650 */ { MAD_F(0x04999ecb) /* 0.287504952 */, 19 },
8158 /* 7651 */ { MAD_F(0x0499d356) /* 0.287555063 */, 19 },
8159 /* 7652 */ { MAD_F(0x049a07e2) /* 0.287605176 */, 19 },
8160 /* 7653 */ { MAD_F(0x049a3c6f) /* 0.287655291 */, 19 },
8161 /* 7654 */ { MAD_F(0x049a70fc) /* 0.287705409 */, 19 },
8162 /* 7655 */ { MAD_F(0x049aa58a) /* 0.287755528 */, 19 },
8163 /* 7656 */ { MAD_F(0x049ada19) /* 0.287805650 */, 19 },
8164 /* 7657 */ { MAD_F(0x049b0ea8) /* 0.287855774 */, 19 },
8165 /* 7658 */ { MAD_F(0x049b4337) /* 0.287905900 */, 19 },
8166 /* 7659 */ { MAD_F(0x049b77c8) /* 0.287956028 */, 19 },
8167 /* 7660 */ { MAD_F(0x049bac58) /* 0.288006159 */, 19 },
8168 /* 7661 */ { MAD_F(0x049be0ea) /* 0.288056292 */, 19 },
8169 /* 7662 */ { MAD_F(0x049c157c) /* 0.288106427 */, 19 },
8170 /* 7663 */ { MAD_F(0x049c4a0e) /* 0.288156564 */, 19 },
8171
8172 /* 7664 */ { MAD_F(0x049c7ea1) /* 0.288206703 */, 19 },
8173 /* 7665 */ { MAD_F(0x049cb335) /* 0.288256844 */, 19 },
8174 /* 7666 */ { MAD_F(0x049ce7ca) /* 0.288306988 */, 19 },
8175 /* 7667 */ { MAD_F(0x049d1c5e) /* 0.288357134 */, 19 },
8176 /* 7668 */ { MAD_F(0x049d50f4) /* 0.288407282 */, 19 },
8177 /* 7669 */ { MAD_F(0x049d858a) /* 0.288457432 */, 19 },
8178 /* 7670 */ { MAD_F(0x049dba21) /* 0.288507584 */, 19 },
8179 /* 7671 */ { MAD_F(0x049deeb8) /* 0.288557739 */, 19 },
8180 /* 7672 */ { MAD_F(0x049e2350) /* 0.288607895 */, 19 },
8181 /* 7673 */ { MAD_F(0x049e57e8) /* 0.288658054 */, 19 },
8182 /* 7674 */ { MAD_F(0x049e8c81) /* 0.288708215 */, 19 },
8183 /* 7675 */ { MAD_F(0x049ec11b) /* 0.288758379 */, 19 },
8184 /* 7676 */ { MAD_F(0x049ef5b5) /* 0.288808544 */, 19 },
8185 /* 7677 */ { MAD_F(0x049f2a50) /* 0.288858712 */, 19 },
8186 /* 7678 */ { MAD_F(0x049f5eeb) /* 0.288908881 */, 19 },
8187 /* 7679 */ { MAD_F(0x049f9387) /* 0.288959053 */, 19 },
8188
8189 /* 7680 */ { MAD_F(0x049fc824) /* 0.289009227 */, 19 },
8190 /* 7681 */ { MAD_F(0x049ffcc1) /* 0.289059404 */, 19 },
8191 /* 7682 */ { MAD_F(0x04a0315e) /* 0.289109582 */, 19 },
8192 /* 7683 */ { MAD_F(0x04a065fd) /* 0.289159763 */, 19 },
8193 /* 7684 */ { MAD_F(0x04a09a9b) /* 0.289209946 */, 19 },
8194 /* 7685 */ { MAD_F(0x04a0cf3b) /* 0.289260131 */, 19 },
8195 /* 7686 */ { MAD_F(0x04a103db) /* 0.289310318 */, 19 },
8196 /* 7687 */ { MAD_F(0x04a1387b) /* 0.289360507 */, 19 },
8197 /* 7688 */ { MAD_F(0x04a16d1d) /* 0.289410699 */, 19 },
8198 /* 7689 */ { MAD_F(0x04a1a1be) /* 0.289460893 */, 19 },
8199 /* 7690 */ { MAD_F(0x04a1d661) /* 0.289511088 */, 19 },
8200 /* 7691 */ { MAD_F(0x04a20b04) /* 0.289561287 */, 19 },
8201 /* 7692 */ { MAD_F(0x04a23fa7) /* 0.289611487 */, 19 },
8202 /* 7693 */ { MAD_F(0x04a2744b) /* 0.289661689 */, 19 },
8203 /* 7694 */ { MAD_F(0x04a2a8f0) /* 0.289711894 */, 19 },
8204 /* 7695 */ { MAD_F(0x04a2dd95) /* 0.289762101 */, 19 },
8205
8206 /* 7696 */ { MAD_F(0x04a3123b) /* 0.289812309 */, 19 },
8207 /* 7697 */ { MAD_F(0x04a346e2) /* 0.289862521 */, 19 },
8208 /* 7698 */ { MAD_F(0x04a37b89) /* 0.289912734 */, 19 },
8209 /* 7699 */ { MAD_F(0x04a3b030) /* 0.289962949 */, 19 },
8210 /* 7700 */ { MAD_F(0x04a3e4d8) /* 0.290013167 */, 19 },
8211 /* 7701 */ { MAD_F(0x04a41981) /* 0.290063387 */, 19 },
8212 /* 7702 */ { MAD_F(0x04a44e2b) /* 0.290113609 */, 19 },
8213 /* 7703 */ { MAD_F(0x04a482d5) /* 0.290163833 */, 19 },
8214 /* 7704 */ { MAD_F(0x04a4b77f) /* 0.290214059 */, 19 },
8215 /* 7705 */ { MAD_F(0x04a4ec2a) /* 0.290264288 */, 19 },
8216 /* 7706 */ { MAD_F(0x04a520d6) /* 0.290314519 */, 19 },
8217 /* 7707 */ { MAD_F(0x04a55582) /* 0.290364751 */, 19 },
8218 /* 7708 */ { MAD_F(0x04a58a2f) /* 0.290414986 */, 19 },
8219 /* 7709 */ { MAD_F(0x04a5bedd) /* 0.290465224 */, 19 },
8220 /* 7710 */ { MAD_F(0x04a5f38b) /* 0.290515463 */, 19 },
8221 /* 7711 */ { MAD_F(0x04a62839) /* 0.290565705 */, 19 },
8222
8223 /* 7712 */ { MAD_F(0x04a65ce8) /* 0.290615948 */, 19 },
8224 /* 7713 */ { MAD_F(0x04a69198) /* 0.290666194 */, 19 },
8225 /* 7714 */ { MAD_F(0x04a6c648) /* 0.290716442 */, 19 },
8226 /* 7715 */ { MAD_F(0x04a6faf9) /* 0.290766692 */, 19 },
8227 /* 7716 */ { MAD_F(0x04a72fab) /* 0.290816945 */, 19 },
8228 /* 7717 */ { MAD_F(0x04a7645d) /* 0.290867199 */, 19 },
8229 /* 7718 */ { MAD_F(0x04a79910) /* 0.290917456 */, 19 },
8230 /* 7719 */ { MAD_F(0x04a7cdc3) /* 0.290967715 */, 19 },
8231 /* 7720 */ { MAD_F(0x04a80277) /* 0.291017976 */, 19 },
8232 /* 7721 */ { MAD_F(0x04a8372b) /* 0.291068239 */, 19 },
8233 /* 7722 */ { MAD_F(0x04a86be0) /* 0.291118505 */, 19 },
8234 /* 7723 */ { MAD_F(0x04a8a096) /* 0.291168772 */, 19 },
8235 /* 7724 */ { MAD_F(0x04a8d54c) /* 0.291219042 */, 19 },
8236 /* 7725 */ { MAD_F(0x04a90a03) /* 0.291269314 */, 19 },
8237 /* 7726 */ { MAD_F(0x04a93eba) /* 0.291319588 */, 19 },
8238 /* 7727 */ { MAD_F(0x04a97372) /* 0.291369865 */, 19 },
8239
8240 /* 7728 */ { MAD_F(0x04a9a82b) /* 0.291420143 */, 19 },
8241 /* 7729 */ { MAD_F(0x04a9dce4) /* 0.291470424 */, 19 },
8242 /* 7730 */ { MAD_F(0x04aa119d) /* 0.291520706 */, 19 },
8243 /* 7731 */ { MAD_F(0x04aa4658) /* 0.291570991 */, 19 },
8244 /* 7732 */ { MAD_F(0x04aa7b13) /* 0.291621278 */, 19 },
8245 /* 7733 */ { MAD_F(0x04aaafce) /* 0.291671568 */, 19 },
8246 /* 7734 */ { MAD_F(0x04aae48a) /* 0.291721859 */, 19 },
8247 /* 7735 */ { MAD_F(0x04ab1947) /* 0.291772153 */, 19 },
8248 /* 7736 */ { MAD_F(0x04ab4e04) /* 0.291822449 */, 19 },
8249 /* 7737 */ { MAD_F(0x04ab82c2) /* 0.291872747 */, 19 },
8250 /* 7738 */ { MAD_F(0x04abb780) /* 0.291923047 */, 19 },
8251 /* 7739 */ { MAD_F(0x04abec3f) /* 0.291973349 */, 19 },
8252 /* 7740 */ { MAD_F(0x04ac20fe) /* 0.292023653 */, 19 },
8253 /* 7741 */ { MAD_F(0x04ac55be) /* 0.292073960 */, 19 },
8254 /* 7742 */ { MAD_F(0x04ac8a7f) /* 0.292124269 */, 19 },
8255 /* 7743 */ { MAD_F(0x04acbf40) /* 0.292174580 */, 19 },
8256
8257 /* 7744 */ { MAD_F(0x04acf402) /* 0.292224893 */, 19 },
8258 /* 7745 */ { MAD_F(0x04ad28c5) /* 0.292275208 */, 19 },
8259 /* 7746 */ { MAD_F(0x04ad5d88) /* 0.292325526 */, 19 },
8260 /* 7747 */ { MAD_F(0x04ad924b) /* 0.292375845 */, 19 },
8261 /* 7748 */ { MAD_F(0x04adc70f) /* 0.292426167 */, 19 },
8262 /* 7749 */ { MAD_F(0x04adfbd4) /* 0.292476491 */, 19 },
8263 /* 7750 */ { MAD_F(0x04ae3099) /* 0.292526817 */, 19 },
8264 /* 7751 */ { MAD_F(0x04ae655f) /* 0.292577145 */, 19 },
8265 /* 7752 */ { MAD_F(0x04ae9a26) /* 0.292627476 */, 19 },
8266 /* 7753 */ { MAD_F(0x04aeceed) /* 0.292677808 */, 19 },
8267 /* 7754 */ { MAD_F(0x04af03b4) /* 0.292728143 */, 19 },
8268 /* 7755 */ { MAD_F(0x04af387d) /* 0.292778480 */, 19 },
8269 /* 7756 */ { MAD_F(0x04af6d45) /* 0.292828819 */, 19 },
8270 /* 7757 */ { MAD_F(0x04afa20f) /* 0.292879160 */, 19 },
8271 /* 7758 */ { MAD_F(0x04afd6d9) /* 0.292929504 */, 19 },
8272 /* 7759 */ { MAD_F(0x04b00ba3) /* 0.292979849 */, 19 },
8273
8274 /* 7760 */ { MAD_F(0x04b0406e) /* 0.293030197 */, 19 },
8275 /* 7761 */ { MAD_F(0x04b0753a) /* 0.293080547 */, 19 },
8276 /* 7762 */ { MAD_F(0x04b0aa06) /* 0.293130899 */, 19 },
8277 /* 7763 */ { MAD_F(0x04b0ded3) /* 0.293181253 */, 19 },
8278 /* 7764 */ { MAD_F(0x04b113a1) /* 0.293231610 */, 19 },
8279 /* 7765 */ { MAD_F(0x04b1486f) /* 0.293281968 */, 19 },
8280 /* 7766 */ { MAD_F(0x04b17d3d) /* 0.293332329 */, 19 },
8281 /* 7767 */ { MAD_F(0x04b1b20c) /* 0.293382692 */, 19 },
8282 /* 7768 */ { MAD_F(0x04b1e6dc) /* 0.293433057 */, 19 },
8283 /* 7769 */ { MAD_F(0x04b21bad) /* 0.293483424 */, 19 },
8284 /* 7770 */ { MAD_F(0x04b2507d) /* 0.293533794 */, 19 },
8285 /* 7771 */ { MAD_F(0x04b2854f) /* 0.293584165 */, 19 },
8286 /* 7772 */ { MAD_F(0x04b2ba21) /* 0.293634539 */, 19 },
8287 /* 7773 */ { MAD_F(0x04b2eef4) /* 0.293684915 */, 19 },
8288 /* 7774 */ { MAD_F(0x04b323c7) /* 0.293735293 */, 19 },
8289 /* 7775 */ { MAD_F(0x04b3589b) /* 0.293785673 */, 19 },
8290
8291 /* 7776 */ { MAD_F(0x04b38d6f) /* 0.293836055 */, 19 },
8292 /* 7777 */ { MAD_F(0x04b3c244) /* 0.293886440 */, 19 },
8293 /* 7778 */ { MAD_F(0x04b3f71a) /* 0.293936826 */, 19 },
8294 /* 7779 */ { MAD_F(0x04b42bf0) /* 0.293987215 */, 19 },
8295 /* 7780 */ { MAD_F(0x04b460c7) /* 0.294037606 */, 19 },
8296 /* 7781 */ { MAD_F(0x04b4959e) /* 0.294087999 */, 19 },
8297 /* 7782 */ { MAD_F(0x04b4ca76) /* 0.294138395 */, 19 },
8298 /* 7783 */ { MAD_F(0x04b4ff4e) /* 0.294188792 */, 19 },
8299 /* 7784 */ { MAD_F(0x04b53427) /* 0.294239192 */, 19 },
8300 /* 7785 */ { MAD_F(0x04b56901) /* 0.294289593 */, 19 },
8301 /* 7786 */ { MAD_F(0x04b59ddb) /* 0.294339997 */, 19 },
8302 /* 7787 */ { MAD_F(0x04b5d2b6) /* 0.294390403 */, 19 },
8303 /* 7788 */ { MAD_F(0x04b60791) /* 0.294440812 */, 19 },
8304 /* 7789 */ { MAD_F(0x04b63c6d) /* 0.294491222 */, 19 },
8305 /* 7790 */ { MAD_F(0x04b6714a) /* 0.294541635 */, 19 },
8306 /* 7791 */ { MAD_F(0x04b6a627) /* 0.294592049 */, 19 },
8307
8308 /* 7792 */ { MAD_F(0x04b6db05) /* 0.294642466 */, 19 },
8309 /* 7793 */ { MAD_F(0x04b70fe3) /* 0.294692885 */, 19 },
8310 /* 7794 */ { MAD_F(0x04b744c2) /* 0.294743306 */, 19 },
8311 /* 7795 */ { MAD_F(0x04b779a1) /* 0.294793730 */, 19 },
8312 /* 7796 */ { MAD_F(0x04b7ae81) /* 0.294844155 */, 19 },
8313 /* 7797 */ { MAD_F(0x04b7e362) /* 0.294894583 */, 19 },
8314 /* 7798 */ { MAD_F(0x04b81843) /* 0.294945013 */, 19 },
8315 /* 7799 */ { MAD_F(0x04b84d24) /* 0.294995445 */, 19 },
8316 /* 7800 */ { MAD_F(0x04b88207) /* 0.295045879 */, 19 },
8317 /* 7801 */ { MAD_F(0x04b8b6ea) /* 0.295096315 */, 19 },
8318 /* 7802 */ { MAD_F(0x04b8ebcd) /* 0.295146753 */, 19 },
8319 /* 7803 */ { MAD_F(0x04b920b1) /* 0.295197194 */, 19 },
8320 /* 7804 */ { MAD_F(0x04b95596) /* 0.295247637 */, 19 },
8321 /* 7805 */ { MAD_F(0x04b98a7b) /* 0.295298082 */, 19 },
8322 /* 7806 */ { MAD_F(0x04b9bf61) /* 0.295348529 */, 19 },
8323 /* 7807 */ { MAD_F(0x04b9f447) /* 0.295398978 */, 19 },
8324
8325 /* 7808 */ { MAD_F(0x04ba292e) /* 0.295449429 */, 19 },
8326 /* 7809 */ { MAD_F(0x04ba5e16) /* 0.295499883 */, 19 },
8327 /* 7810 */ { MAD_F(0x04ba92fe) /* 0.295550338 */, 19 },
8328 /* 7811 */ { MAD_F(0x04bac7e6) /* 0.295600796 */, 19 },
8329 /* 7812 */ { MAD_F(0x04bafcd0) /* 0.295651256 */, 19 },
8330 /* 7813 */ { MAD_F(0x04bb31b9) /* 0.295701718 */, 19 },
8331 /* 7814 */ { MAD_F(0x04bb66a4) /* 0.295752183 */, 19 },
8332 /* 7815 */ { MAD_F(0x04bb9b8f) /* 0.295802649 */, 19 },
8333 /* 7816 */ { MAD_F(0x04bbd07a) /* 0.295853118 */, 19 },
8334 /* 7817 */ { MAD_F(0x04bc0566) /* 0.295903588 */, 19 },
8335 /* 7818 */ { MAD_F(0x04bc3a53) /* 0.295954061 */, 19 },
8336 /* 7819 */ { MAD_F(0x04bc6f40) /* 0.296004536 */, 19 },
8337 /* 7820 */ { MAD_F(0x04bca42e) /* 0.296055013 */, 19 },
8338 /* 7821 */ { MAD_F(0x04bcd91d) /* 0.296105493 */, 19 },
8339 /* 7822 */ { MAD_F(0x04bd0e0c) /* 0.296155974 */, 19 },
8340 /* 7823 */ { MAD_F(0x04bd42fb) /* 0.296206458 */, 19 },
8341
8342 /* 7824 */ { MAD_F(0x04bd77ec) /* 0.296256944 */, 19 },
8343 /* 7825 */ { MAD_F(0x04bdacdc) /* 0.296307432 */, 19 },
8344 /* 7826 */ { MAD_F(0x04bde1ce) /* 0.296357922 */, 19 },
8345 /* 7827 */ { MAD_F(0x04be16c0) /* 0.296408414 */, 19 },
8346 /* 7828 */ { MAD_F(0x04be4bb2) /* 0.296458908 */, 19 },
8347 /* 7829 */ { MAD_F(0x04be80a5) /* 0.296509405 */, 19 },
8348 /* 7830 */ { MAD_F(0x04beb599) /* 0.296559904 */, 19 },
8349 /* 7831 */ { MAD_F(0x04beea8d) /* 0.296610404 */, 19 },
8350 /* 7832 */ { MAD_F(0x04bf1f82) /* 0.296660907 */, 19 },
8351 /* 7833 */ { MAD_F(0x04bf5477) /* 0.296711413 */, 19 },
8352 /* 7834 */ { MAD_F(0x04bf896d) /* 0.296761920 */, 19 },
8353 /* 7835 */ { MAD_F(0x04bfbe64) /* 0.296812429 */, 19 },
8354 /* 7836 */ { MAD_F(0x04bff35b) /* 0.296862941 */, 19 },
8355 /* 7837 */ { MAD_F(0x04c02852) /* 0.296913455 */, 19 },
8356 /* 7838 */ { MAD_F(0x04c05d4b) /* 0.296963971 */, 19 },
8357 /* 7839 */ { MAD_F(0x04c09243) /* 0.297014489 */, 19 },
8358
8359 /* 7840 */ { MAD_F(0x04c0c73d) /* 0.297065009 */, 19 },
8360 /* 7841 */ { MAD_F(0x04c0fc37) /* 0.297115531 */, 19 },
8361 /* 7842 */ { MAD_F(0x04c13131) /* 0.297166056 */, 19 },
8362 /* 7843 */ { MAD_F(0x04c1662d) /* 0.297216582 */, 19 },
8363 /* 7844 */ { MAD_F(0x04c19b28) /* 0.297267111 */, 19 },
8364 /* 7845 */ { MAD_F(0x04c1d025) /* 0.297317642 */, 19 },
8365 /* 7846 */ { MAD_F(0x04c20521) /* 0.297368175 */, 19 },
8366 /* 7847 */ { MAD_F(0x04c23a1f) /* 0.297418710 */, 19 },
8367 /* 7848 */ { MAD_F(0x04c26f1d) /* 0.297469248 */, 19 },
8368 /* 7849 */ { MAD_F(0x04c2a41b) /* 0.297519787 */, 19 },
8369 /* 7850 */ { MAD_F(0x04c2d91b) /* 0.297570329 */, 19 },
8370 /* 7851 */ { MAD_F(0x04c30e1a) /* 0.297620873 */, 19 },
8371 /* 7852 */ { MAD_F(0x04c3431b) /* 0.297671418 */, 19 },
8372 /* 7853 */ { MAD_F(0x04c3781c) /* 0.297721967 */, 19 },
8373 /* 7854 */ { MAD_F(0x04c3ad1d) /* 0.297772517 */, 19 },
8374 /* 7855 */ { MAD_F(0x04c3e21f) /* 0.297823069 */, 19 },
8375
8376 /* 7856 */ { MAD_F(0x04c41722) /* 0.297873624 */, 19 },
8377 /* 7857 */ { MAD_F(0x04c44c25) /* 0.297924180 */, 19 },
8378 /* 7858 */ { MAD_F(0x04c48129) /* 0.297974739 */, 19 },
8379 /* 7859 */ { MAD_F(0x04c4b62d) /* 0.298025300 */, 19 },
8380 /* 7860 */ { MAD_F(0x04c4eb32) /* 0.298075863 */, 19 },
8381 /* 7861 */ { MAD_F(0x04c52038) /* 0.298126429 */, 19 },
8382 /* 7862 */ { MAD_F(0x04c5553e) /* 0.298176996 */, 19 },
8383 /* 7863 */ { MAD_F(0x04c58a44) /* 0.298227565 */, 19 },
8384 /* 7864 */ { MAD_F(0x04c5bf4c) /* 0.298278137 */, 19 },
8385 /* 7865 */ { MAD_F(0x04c5f453) /* 0.298328711 */, 19 },
8386 /* 7866 */ { MAD_F(0x04c6295c) /* 0.298379287 */, 19 },
8387 /* 7867 */ { MAD_F(0x04c65e65) /* 0.298429865 */, 19 },
8388 /* 7868 */ { MAD_F(0x04c6936e) /* 0.298480445 */, 19 },
8389 /* 7869 */ { MAD_F(0x04c6c878) /* 0.298531028 */, 19 },
8390 /* 7870 */ { MAD_F(0x04c6fd83) /* 0.298581612 */, 19 },
8391 /* 7871 */ { MAD_F(0x04c7328e) /* 0.298632199 */, 19 },
8392
8393 /* 7872 */ { MAD_F(0x04c7679a) /* 0.298682788 */, 19 },
8394 /* 7873 */ { MAD_F(0x04c79ca7) /* 0.298733379 */, 19 },
8395 /* 7874 */ { MAD_F(0x04c7d1b4) /* 0.298783972 */, 19 },
8396 /* 7875 */ { MAD_F(0x04c806c1) /* 0.298834567 */, 19 },
8397 /* 7876 */ { MAD_F(0x04c83bcf) /* 0.298885165 */, 19 },
8398 /* 7877 */ { MAD_F(0x04c870de) /* 0.298935764 */, 19 },
8399 /* 7878 */ { MAD_F(0x04c8a5ed) /* 0.298986366 */, 19 },
8400 /* 7879 */ { MAD_F(0x04c8dafd) /* 0.299036970 */, 19 },
8401 /* 7880 */ { MAD_F(0x04c9100d) /* 0.299087576 */, 19 },
8402 /* 7881 */ { MAD_F(0x04c9451e) /* 0.299138184 */, 19 },
8403 /* 7882 */ { MAD_F(0x04c97a30) /* 0.299188794 */, 19 },
8404 /* 7883 */ { MAD_F(0x04c9af42) /* 0.299239406 */, 19 },
8405 /* 7884 */ { MAD_F(0x04c9e455) /* 0.299290021 */, 19 },
8406 /* 7885 */ { MAD_F(0x04ca1968) /* 0.299340638 */, 19 },
8407 /* 7886 */ { MAD_F(0x04ca4e7c) /* 0.299391256 */, 19 },
8408 /* 7887 */ { MAD_F(0x04ca8391) /* 0.299441877 */, 19 },
8409
8410 /* 7888 */ { MAD_F(0x04cab8a6) /* 0.299492500 */, 19 },
8411 /* 7889 */ { MAD_F(0x04caedbb) /* 0.299543126 */, 19 },
8412 /* 7890 */ { MAD_F(0x04cb22d1) /* 0.299593753 */, 19 },
8413 /* 7891 */ { MAD_F(0x04cb57e8) /* 0.299644382 */, 19 },
8414 /* 7892 */ { MAD_F(0x04cb8d00) /* 0.299695014 */, 19 },
8415 /* 7893 */ { MAD_F(0x04cbc217) /* 0.299745648 */, 19 },
8416 /* 7894 */ { MAD_F(0x04cbf730) /* 0.299796284 */, 19 },
8417 /* 7895 */ { MAD_F(0x04cc2c49) /* 0.299846922 */, 19 },
8418 /* 7896 */ { MAD_F(0x04cc6163) /* 0.299897562 */, 19 },
8419 /* 7897 */ { MAD_F(0x04cc967d) /* 0.299948204 */, 19 },
8420 /* 7898 */ { MAD_F(0x04cccb98) /* 0.299998849 */, 19 },
8421 /* 7899 */ { MAD_F(0x04cd00b3) /* 0.300049495 */, 19 },
8422 /* 7900 */ { MAD_F(0x04cd35cf) /* 0.300100144 */, 19 },
8423 /* 7901 */ { MAD_F(0x04cd6aeb) /* 0.300150795 */, 19 },
8424 /* 7902 */ { MAD_F(0x04cda008) /* 0.300201448 */, 19 },
8425 /* 7903 */ { MAD_F(0x04cdd526) /* 0.300252103 */, 19 },
8426
8427 /* 7904 */ { MAD_F(0x04ce0a44) /* 0.300302761 */, 19 },
8428 /* 7905 */ { MAD_F(0x04ce3f63) /* 0.300353420 */, 19 },
8429 /* 7906 */ { MAD_F(0x04ce7482) /* 0.300404082 */, 19 },
8430 /* 7907 */ { MAD_F(0x04cea9a2) /* 0.300454745 */, 19 },
8431 /* 7908 */ { MAD_F(0x04cedec3) /* 0.300505411 */, 19 },
8432 /* 7909 */ { MAD_F(0x04cf13e4) /* 0.300556079 */, 19 },
8433 /* 7910 */ { MAD_F(0x04cf4906) /* 0.300606749 */, 19 },
8434 /* 7911 */ { MAD_F(0x04cf7e28) /* 0.300657421 */, 19 },
8435 /* 7912 */ { MAD_F(0x04cfb34b) /* 0.300708096 */, 19 },
8436 /* 7913 */ { MAD_F(0x04cfe86e) /* 0.300758772 */, 19 },
8437 /* 7914 */ { MAD_F(0x04d01d92) /* 0.300809451 */, 19 },
8438 /* 7915 */ { MAD_F(0x04d052b6) /* 0.300860132 */, 19 },
8439 /* 7916 */ { MAD_F(0x04d087db) /* 0.300910815 */, 19 },
8440 /* 7917 */ { MAD_F(0x04d0bd01) /* 0.300961500 */, 19 },
8441 /* 7918 */ { MAD_F(0x04d0f227) /* 0.301012187 */, 19 },
8442 /* 7919 */ { MAD_F(0x04d1274e) /* 0.301062876 */, 19 },
8443
8444 /* 7920 */ { MAD_F(0x04d15c76) /* 0.301113568 */, 19 },
8445 /* 7921 */ { MAD_F(0x04d1919e) /* 0.301164261 */, 19 },
8446 /* 7922 */ { MAD_F(0x04d1c6c6) /* 0.301214957 */, 19 },
8447 /* 7923 */ { MAD_F(0x04d1fbef) /* 0.301265655 */, 19 },
8448 /* 7924 */ { MAD_F(0x04d23119) /* 0.301316355 */, 19 },
8449 /* 7925 */ { MAD_F(0x04d26643) /* 0.301367057 */, 19 },
8450 /* 7926 */ { MAD_F(0x04d29b6e) /* 0.301417761 */, 19 },
8451 /* 7927 */ { MAD_F(0x04d2d099) /* 0.301468468 */, 19 },
8452 /* 7928 */ { MAD_F(0x04d305c5) /* 0.301519176 */, 19 },
8453 /* 7929 */ { MAD_F(0x04d33af2) /* 0.301569887 */, 19 },
8454 /* 7930 */ { MAD_F(0x04d3701f) /* 0.301620599 */, 19 },
8455 /* 7931 */ { MAD_F(0x04d3a54d) /* 0.301671314 */, 19 },
8456 /* 7932 */ { MAD_F(0x04d3da7b) /* 0.301722031 */, 19 },
8457 /* 7933 */ { MAD_F(0x04d40faa) /* 0.301772751 */, 19 },
8458 /* 7934 */ { MAD_F(0x04d444d9) /* 0.301823472 */, 19 },
8459 /* 7935 */ { MAD_F(0x04d47a09) /* 0.301874195 */, 19 },
8460
8461 /* 7936 */ { MAD_F(0x04d4af3a) /* 0.301924921 */, 19 },
8462 /* 7937 */ { MAD_F(0x04d4e46b) /* 0.301975649 */, 19 },
8463 /* 7938 */ { MAD_F(0x04d5199c) /* 0.302026378 */, 19 },
8464 /* 7939 */ { MAD_F(0x04d54ecf) /* 0.302077110 */, 19 },
8465 /* 7940 */ { MAD_F(0x04d58401) /* 0.302127845 */, 19 },
8466 /* 7941 */ { MAD_F(0x04d5b935) /* 0.302178581 */, 19 },
8467 /* 7942 */ { MAD_F(0x04d5ee69) /* 0.302229319 */, 19 },
8468 /* 7943 */ { MAD_F(0x04d6239d) /* 0.302280060 */, 19 },
8469 /* 7944 */ { MAD_F(0x04d658d2) /* 0.302330802 */, 19 },
8470 /* 7945 */ { MAD_F(0x04d68e08) /* 0.302381547 */, 19 },
8471 /* 7946 */ { MAD_F(0x04d6c33e) /* 0.302432294 */, 19 },
8472 /* 7947 */ { MAD_F(0x04d6f875) /* 0.302483043 */, 19 },
8473 /* 7948 */ { MAD_F(0x04d72dad) /* 0.302533794 */, 19 },
8474 /* 7949 */ { MAD_F(0x04d762e5) /* 0.302584547 */, 19 },
8475 /* 7950 */ { MAD_F(0x04d7981d) /* 0.302635303 */, 19 },
8476 /* 7951 */ { MAD_F(0x04d7cd56) /* 0.302686060 */, 19 },
8477
8478 /* 7952 */ { MAD_F(0x04d80290) /* 0.302736820 */, 19 },
8479 /* 7953 */ { MAD_F(0x04d837ca) /* 0.302787581 */, 19 },
8480 /* 7954 */ { MAD_F(0x04d86d05) /* 0.302838345 */, 19 },
8481 /* 7955 */ { MAD_F(0x04d8a240) /* 0.302889111 */, 19 },
8482 /* 7956 */ { MAD_F(0x04d8d77c) /* 0.302939879 */, 19 },
8483 /* 7957 */ { MAD_F(0x04d90cb9) /* 0.302990650 */, 19 },
8484 /* 7958 */ { MAD_F(0x04d941f6) /* 0.303041422 */, 19 },
8485 /* 7959 */ { MAD_F(0x04d97734) /* 0.303092197 */, 19 },
8486 /* 7960 */ { MAD_F(0x04d9ac72) /* 0.303142973 */, 19 },
8487 /* 7961 */ { MAD_F(0x04d9e1b1) /* 0.303193752 */, 19 },
8488 /* 7962 */ { MAD_F(0x04da16f0) /* 0.303244533 */, 19 },
8489 /* 7963 */ { MAD_F(0x04da4c30) /* 0.303295316 */, 19 },
8490 /* 7964 */ { MAD_F(0x04da8171) /* 0.303346101 */, 19 },
8491 /* 7965 */ { MAD_F(0x04dab6b2) /* 0.303396889 */, 19 },
8492 /* 7966 */ { MAD_F(0x04daebf4) /* 0.303447678 */, 19 },
8493 /* 7967 */ { MAD_F(0x04db2136) /* 0.303498469 */, 19 },
8494
8495 /* 7968 */ { MAD_F(0x04db5679) /* 0.303549263 */, 19 },
8496 /* 7969 */ { MAD_F(0x04db8bbc) /* 0.303600059 */, 19 },
8497 /* 7970 */ { MAD_F(0x04dbc100) /* 0.303650857 */, 19 },
8498 /* 7971 */ { MAD_F(0x04dbf644) /* 0.303701657 */, 19 },
8499 /* 7972 */ { MAD_F(0x04dc2b8a) /* 0.303752459 */, 19 },
8500 /* 7973 */ { MAD_F(0x04dc60cf) /* 0.303803263 */, 19 },
8501 /* 7974 */ { MAD_F(0x04dc9616) /* 0.303854070 */, 19 },
8502 /* 7975 */ { MAD_F(0x04dccb5c) /* 0.303904878 */, 19 },
8503 /* 7976 */ { MAD_F(0x04dd00a4) /* 0.303955689 */, 19 },
8504 /* 7977 */ { MAD_F(0x04dd35ec) /* 0.304006502 */, 19 },
8505 /* 7978 */ { MAD_F(0x04dd6b34) /* 0.304057317 */, 19 },
8506 /* 7979 */ { MAD_F(0x04dda07d) /* 0.304108134 */, 19 },
8507 /* 7980 */ { MAD_F(0x04ddd5c7) /* 0.304158953 */, 19 },
8508 /* 7981 */ { MAD_F(0x04de0b11) /* 0.304209774 */, 19 },
8509 /* 7982 */ { MAD_F(0x04de405c) /* 0.304260597 */, 19 },
8510 /* 7983 */ { MAD_F(0x04de75a7) /* 0.304311423 */, 19 },
8511
8512 /* 7984 */ { MAD_F(0x04deaaf3) /* 0.304362251 */, 19 },
8513 /* 7985 */ { MAD_F(0x04dee040) /* 0.304413080 */, 19 },
8514 /* 7986 */ { MAD_F(0x04df158d) /* 0.304463912 */, 19 },
8515 /* 7987 */ { MAD_F(0x04df4adb) /* 0.304514746 */, 19 },
8516 /* 7988 */ { MAD_F(0x04df8029) /* 0.304565582 */, 19 },
8517 /* 7989 */ { MAD_F(0x04dfb578) /* 0.304616421 */, 19 },
8518 /* 7990 */ { MAD_F(0x04dfeac7) /* 0.304667261 */, 19 },
8519 /* 7991 */ { MAD_F(0x04e02017) /* 0.304718103 */, 19 },
8520 /* 7992 */ { MAD_F(0x04e05567) /* 0.304768948 */, 19 },
8521 /* 7993 */ { MAD_F(0x04e08ab8) /* 0.304819795 */, 19 },
8522 /* 7994 */ { MAD_F(0x04e0c00a) /* 0.304870644 */, 19 },
8523 /* 7995 */ { MAD_F(0x04e0f55c) /* 0.304921495 */, 19 },
8524 /* 7996 */ { MAD_F(0x04e12aaf) /* 0.304972348 */, 19 },
8525 /* 7997 */ { MAD_F(0x04e16002) /* 0.305023203 */, 19 },
8526 /* 7998 */ { MAD_F(0x04e19556) /* 0.305074060 */, 19 },
8527 /* 7999 */ { MAD_F(0x04e1caab) /* 0.305124920 */, 19 },
8528
8529 /* 8000 */ { MAD_F(0x04e20000) /* 0.305175781 */, 19 },
8530 /* 8001 */ { MAD_F(0x04e23555) /* 0.305226645 */, 19 },
8531 /* 8002 */ { MAD_F(0x04e26aac) /* 0.305277511 */, 19 },
8532 /* 8003 */ { MAD_F(0x04e2a002) /* 0.305328379 */, 19 },
8533 /* 8004 */ { MAD_F(0x04e2d55a) /* 0.305379249 */, 19 },
8534 /* 8005 */ { MAD_F(0x04e30ab2) /* 0.305430121 */, 19 },
8535 /* 8006 */ { MAD_F(0x04e3400a) /* 0.305480995 */, 19 },
8536 /* 8007 */ { MAD_F(0x04e37563) /* 0.305531872 */, 19 },
8537 /* 8008 */ { MAD_F(0x04e3aabd) /* 0.305582750 */, 19 },
8538 /* 8009 */ { MAD_F(0x04e3e017) /* 0.305633631 */, 19 },
8539 /* 8010 */ { MAD_F(0x04e41572) /* 0.305684513 */, 19 },
8540 /* 8011 */ { MAD_F(0x04e44acd) /* 0.305735398 */, 19 },
8541 /* 8012 */ { MAD_F(0x04e48029) /* 0.305786285 */, 19 },
8542 /* 8013 */ { MAD_F(0x04e4b585) /* 0.305837174 */, 19 },
8543 /* 8014 */ { MAD_F(0x04e4eae2) /* 0.305888066 */, 19 },
8544 /* 8015 */ { MAD_F(0x04e52040) /* 0.305938959 */, 19 },
8545
8546 /* 8016 */ { MAD_F(0x04e5559e) /* 0.305989854 */, 19 },
8547 /* 8017 */ { MAD_F(0x04e58afd) /* 0.306040752 */, 19 },
8548 /* 8018 */ { MAD_F(0x04e5c05c) /* 0.306091652 */, 19 },
8549 /* 8019 */ { MAD_F(0x04e5f5bc) /* 0.306142554 */, 19 },
8550 /* 8020 */ { MAD_F(0x04e62b1c) /* 0.306193457 */, 19 },
8551 /* 8021 */ { MAD_F(0x04e6607d) /* 0.306244364 */, 19 },
8552 /* 8022 */ { MAD_F(0x04e695df) /* 0.306295272 */, 19 },
8553 /* 8023 */ { MAD_F(0x04e6cb41) /* 0.306346182 */, 19 },
8554 /* 8024 */ { MAD_F(0x04e700a3) /* 0.306397094 */, 19 },
8555 /* 8025 */ { MAD_F(0x04e73607) /* 0.306448009 */, 19 },
8556 /* 8026 */ { MAD_F(0x04e76b6b) /* 0.306498925 */, 19 },
8557 /* 8027 */ { MAD_F(0x04e7a0cf) /* 0.306549844 */, 19 },
8558 /* 8028 */ { MAD_F(0x04e7d634) /* 0.306600765 */, 19 },
8559 /* 8029 */ { MAD_F(0x04e80b99) /* 0.306651688 */, 19 },
8560 /* 8030 */ { MAD_F(0x04e84100) /* 0.306702613 */, 19 },
8561 /* 8031 */ { MAD_F(0x04e87666) /* 0.306753540 */, 19 },
8562
8563 /* 8032 */ { MAD_F(0x04e8abcd) /* 0.306804470 */, 19 },
8564 /* 8033 */ { MAD_F(0x04e8e135) /* 0.306855401 */, 19 },
8565 /* 8034 */ { MAD_F(0x04e9169e) /* 0.306906334 */, 19 },
8566 /* 8035 */ { MAD_F(0x04e94c07) /* 0.306957270 */, 19 },
8567 /* 8036 */ { MAD_F(0x04e98170) /* 0.307008208 */, 19 },
8568 /* 8037 */ { MAD_F(0x04e9b6da) /* 0.307059148 */, 19 },
8569 /* 8038 */ { MAD_F(0x04e9ec45) /* 0.307110090 */, 19 },
8570 /* 8039 */ { MAD_F(0x04ea21b0) /* 0.307161034 */, 19 },
8571 /* 8040 */ { MAD_F(0x04ea571c) /* 0.307211980 */, 19 },
8572 /* 8041 */ { MAD_F(0x04ea8c88) /* 0.307262928 */, 19 },
8573 /* 8042 */ { MAD_F(0x04eac1f5) /* 0.307313879 */, 19 },
8574 /* 8043 */ { MAD_F(0x04eaf762) /* 0.307364831 */, 19 },
8575 /* 8044 */ { MAD_F(0x04eb2cd0) /* 0.307415786 */, 19 },
8576 /* 8045 */ { MAD_F(0x04eb623f) /* 0.307466743 */, 19 },
8577 /* 8046 */ { MAD_F(0x04eb97ae) /* 0.307517702 */, 19 },
8578 /* 8047 */ { MAD_F(0x04ebcd1e) /* 0.307568663 */, 19 },
8579
8580 /* 8048 */ { MAD_F(0x04ec028e) /* 0.307619626 */, 19 },
8581 /* 8049 */ { MAD_F(0x04ec37ff) /* 0.307670591 */, 19 },
8582 /* 8050 */ { MAD_F(0x04ec6d71) /* 0.307721558 */, 19 },
8583 /* 8051 */ { MAD_F(0x04eca2e3) /* 0.307772528 */, 19 },
8584 /* 8052 */ { MAD_F(0x04ecd855) /* 0.307823499 */, 19 },
8585 /* 8053 */ { MAD_F(0x04ed0dc8) /* 0.307874473 */, 19 },
8586 /* 8054 */ { MAD_F(0x04ed433c) /* 0.307925449 */, 19 },
8587 /* 8055 */ { MAD_F(0x04ed78b0) /* 0.307976426 */, 19 },
8588 /* 8056 */ { MAD_F(0x04edae25) /* 0.308027406 */, 19 },
8589 /* 8057 */ { MAD_F(0x04ede39a) /* 0.308078389 */, 19 },
8590 /* 8058 */ { MAD_F(0x04ee1910) /* 0.308129373 */, 19 },
8591 /* 8059 */ { MAD_F(0x04ee4e87) /* 0.308180359 */, 19 },
8592 /* 8060 */ { MAD_F(0x04ee83fe) /* 0.308231347 */, 19 },
8593 /* 8061 */ { MAD_F(0x04eeb976) /* 0.308282338 */, 19 },
8594 /* 8062 */ { MAD_F(0x04eeeeee) /* 0.308333331 */, 19 },
8595 /* 8063 */ { MAD_F(0x04ef2467) /* 0.308384325 */, 19 },
8596
8597 /* 8064 */ { MAD_F(0x04ef59e0) /* 0.308435322 */, 19 },
8598 /* 8065 */ { MAD_F(0x04ef8f5a) /* 0.308486321 */, 19 },
8599 /* 8066 */ { MAD_F(0x04efc4d5) /* 0.308537322 */, 19 },
8600 /* 8067 */ { MAD_F(0x04effa50) /* 0.308588325 */, 19 },
8601 /* 8068 */ { MAD_F(0x04f02fcb) /* 0.308639331 */, 19 },
8602 /* 8069 */ { MAD_F(0x04f06547) /* 0.308690338 */, 19 },
8603 /* 8070 */ { MAD_F(0x04f09ac4) /* 0.308741348 */, 19 },
8604 /* 8071 */ { MAD_F(0x04f0d041) /* 0.308792359 */, 19 },
8605 /* 8072 */ { MAD_F(0x04f105bf) /* 0.308843373 */, 19 },
8606 /* 8073 */ { MAD_F(0x04f13b3e) /* 0.308894389 */, 19 },
8607 /* 8074 */ { MAD_F(0x04f170bd) /* 0.308945407 */, 19 },
8608 /* 8075 */ { MAD_F(0x04f1a63c) /* 0.308996427 */, 19 },
8609 /* 8076 */ { MAD_F(0x04f1dbbd) /* 0.309047449 */, 19 },
8610 /* 8077 */ { MAD_F(0x04f2113d) /* 0.309098473 */, 19 },
8611 /* 8078 */ { MAD_F(0x04f246bf) /* 0.309149499 */, 19 },
8612 /* 8079 */ { MAD_F(0x04f27c40) /* 0.309200528 */, 19 },
8613
8614 /* 8080 */ { MAD_F(0x04f2b1c3) /* 0.309251558 */, 19 },
8615 /* 8081 */ { MAD_F(0x04f2e746) /* 0.309302591 */, 19 },
8616 /* 8082 */ { MAD_F(0x04f31cc9) /* 0.309353626 */, 19 },
8617 /* 8083 */ { MAD_F(0x04f3524d) /* 0.309404663 */, 19 },
8618 /* 8084 */ { MAD_F(0x04f387d2) /* 0.309455702 */, 19 },
8619 /* 8085 */ { MAD_F(0x04f3bd57) /* 0.309506743 */, 19 },
8620 /* 8086 */ { MAD_F(0x04f3f2dd) /* 0.309557786 */, 19 },
8621 /* 8087 */ { MAD_F(0x04f42864) /* 0.309608831 */, 19 },
8622 /* 8088 */ { MAD_F(0x04f45dea) /* 0.309659879 */, 19 },
8623 /* 8089 */ { MAD_F(0x04f49372) /* 0.309710928 */, 19 },
8624 /* 8090 */ { MAD_F(0x04f4c8fa) /* 0.309761980 */, 19 },
8625 /* 8091 */ { MAD_F(0x04f4fe83) /* 0.309813033 */, 19 },
8626 /* 8092 */ { MAD_F(0x04f5340c) /* 0.309864089 */, 19 },
8627 /* 8093 */ { MAD_F(0x04f56996) /* 0.309915147 */, 19 },
8628 /* 8094 */ { MAD_F(0x04f59f20) /* 0.309966207 */, 19 },
8629 /* 8095 */ { MAD_F(0x04f5d4ab) /* 0.310017269 */, 19 },
8630
8631 /* 8096 */ { MAD_F(0x04f60a36) /* 0.310068333 */, 19 },
8632 /* 8097 */ { MAD_F(0x04f63fc2) /* 0.310119400 */, 19 },
8633 /* 8098 */ { MAD_F(0x04f6754f) /* 0.310170468 */, 19 },
8634 /* 8099 */ { MAD_F(0x04f6aadc) /* 0.310221539 */, 19 },
8635 /* 8100 */ { MAD_F(0x04f6e06a) /* 0.310272611 */, 19 },
8636 /* 8101 */ { MAD_F(0x04f715f8) /* 0.310323686 */, 19 },
8637 /* 8102 */ { MAD_F(0x04f74b87) /* 0.310374763 */, 19 },
8638 /* 8103 */ { MAD_F(0x04f78116) /* 0.310425842 */, 19 },
8639 /* 8104 */ { MAD_F(0x04f7b6a6) /* 0.310476923 */, 19 },
8640 /* 8105 */ { MAD_F(0x04f7ec37) /* 0.310528006 */, 19 },
8641 /* 8106 */ { MAD_F(0x04f821c8) /* 0.310579091 */, 19 },
8642 /* 8107 */ { MAD_F(0x04f85759) /* 0.310630179 */, 19 },
8643 /* 8108 */ { MAD_F(0x04f88cec) /* 0.310681268 */, 19 },
8644 /* 8109 */ { MAD_F(0x04f8c27e) /* 0.310732360 */, 19 },
8645 /* 8110 */ { MAD_F(0x04f8f812) /* 0.310783453 */, 19 },
8646 /* 8111 */ { MAD_F(0x04f92da6) /* 0.310834549 */, 19 },
8647
8648 /* 8112 */ { MAD_F(0x04f9633a) /* 0.310885647 */, 19 },
8649 /* 8113 */ { MAD_F(0x04f998cf) /* 0.310936747 */, 19 },
8650 /* 8114 */ { MAD_F(0x04f9ce65) /* 0.310987849 */, 19 },
8651 /* 8115 */ { MAD_F(0x04fa03fb) /* 0.311038953 */, 19 },
8652 /* 8116 */ { MAD_F(0x04fa3992) /* 0.311090059 */, 19 },
8653 /* 8117 */ { MAD_F(0x04fa6f29) /* 0.311141168 */, 19 },
8654 /* 8118 */ { MAD_F(0x04faa4c1) /* 0.311192278 */, 19 },
8655 /* 8119 */ { MAD_F(0x04fada59) /* 0.311243390 */, 19 },
8656 /* 8120 */ { MAD_F(0x04fb0ff2) /* 0.311294505 */, 19 },
8657 /* 8121 */ { MAD_F(0x04fb458c) /* 0.311345622 */, 19 },
8658 /* 8122 */ { MAD_F(0x04fb7b26) /* 0.311396741 */, 19 },
8659 /* 8123 */ { MAD_F(0x04fbb0c1) /* 0.311447862 */, 19 },
8660 /* 8124 */ { MAD_F(0x04fbe65c) /* 0.311498985 */, 19 },
8661 /* 8125 */ { MAD_F(0x04fc1bf8) /* 0.311550110 */, 19 },
8662 /* 8126 */ { MAD_F(0x04fc5194) /* 0.311601237 */, 19 },
8663 /* 8127 */ { MAD_F(0x04fc8731) /* 0.311652366 */, 19 },
8664
8665 /* 8128 */ { MAD_F(0x04fcbcce) /* 0.311703498 */, 19 },
8666 /* 8129 */ { MAD_F(0x04fcf26c) /* 0.311754631 */, 19 },
8667 /* 8130 */ { MAD_F(0x04fd280b) /* 0.311805767 */, 19 },
8668 /* 8131 */ { MAD_F(0x04fd5daa) /* 0.311856905 */, 19 },
8669 /* 8132 */ { MAD_F(0x04fd934a) /* 0.311908044 */, 19 },
8670 /* 8133 */ { MAD_F(0x04fdc8ea) /* 0.311959186 */, 19 },
8671 /* 8134 */ { MAD_F(0x04fdfe8b) /* 0.312010330 */, 19 },
8672 /* 8135 */ { MAD_F(0x04fe342c) /* 0.312061476 */, 19 },
8673 /* 8136 */ { MAD_F(0x04fe69ce) /* 0.312112625 */, 19 },
8674 /* 8137 */ { MAD_F(0x04fe9f71) /* 0.312163775 */, 19 },
8675 /* 8138 */ { MAD_F(0x04fed514) /* 0.312214927 */, 19 },
8676 /* 8139 */ { MAD_F(0x04ff0ab8) /* 0.312266082 */, 19 },
8677 /* 8140 */ { MAD_F(0x04ff405c) /* 0.312317238 */, 19 },
8678 /* 8141 */ { MAD_F(0x04ff7601) /* 0.312368397 */, 19 },
8679 /* 8142 */ { MAD_F(0x04ffaba6) /* 0.312419558 */, 19 },
8680 /* 8143 */ { MAD_F(0x04ffe14c) /* 0.312470720 */, 19 },
8681
8682 /* 8144 */ { MAD_F(0x050016f3) /* 0.312521885 */, 19 },
8683 /* 8145 */ { MAD_F(0x05004c9a) /* 0.312573052 */, 19 },
8684 /* 8146 */ { MAD_F(0x05008241) /* 0.312624222 */, 19 },
8685 /* 8147 */ { MAD_F(0x0500b7e9) /* 0.312675393 */, 19 },
8686 /* 8148 */ { MAD_F(0x0500ed92) /* 0.312726566 */, 19 },
8687 /* 8149 */ { MAD_F(0x0501233b) /* 0.312777742 */, 19 },
8688 /* 8150 */ { MAD_F(0x050158e5) /* 0.312828919 */, 19 },
8689 /* 8151 */ { MAD_F(0x05018e90) /* 0.312880099 */, 19 },
8690 /* 8152 */ { MAD_F(0x0501c43b) /* 0.312931280 */, 19 },
8691 /* 8153 */ { MAD_F(0x0501f9e6) /* 0.312982464 */, 19 },
8692 /* 8154 */ { MAD_F(0x05022f92) /* 0.313033650 */, 19 },
8693 /* 8155 */ { MAD_F(0x0502653f) /* 0.313084838 */, 19 },
8694 /* 8156 */ { MAD_F(0x05029aec) /* 0.313136028 */, 19 },
8695 /* 8157 */ { MAD_F(0x0502d09a) /* 0.313187220 */, 19 },
8696 /* 8158 */ { MAD_F(0x05030648) /* 0.313238414 */, 19 },
8697 /* 8159 */ { MAD_F(0x05033bf7) /* 0.313289611 */, 19 },
8698
8699 /* 8160 */ { MAD_F(0x050371a7) /* 0.313340809 */, 19 },
8700 /* 8161 */ { MAD_F(0x0503a757) /* 0.313392010 */, 19 },
8701 /* 8162 */ { MAD_F(0x0503dd07) /* 0.313443212 */, 19 },
8702 /* 8163 */ { MAD_F(0x050412b9) /* 0.313494417 */, 19 },
8703 /* 8164 */ { MAD_F(0x0504486a) /* 0.313545624 */, 19 },
8704 /* 8165 */ { MAD_F(0x05047e1d) /* 0.313596833 */, 19 },
8705 /* 8166 */ { MAD_F(0x0504b3cf) /* 0.313648044 */, 19 },
8706 /* 8167 */ { MAD_F(0x0504e983) /* 0.313699257 */, 19 },
8707 /* 8168 */ { MAD_F(0x05051f37) /* 0.313750472 */, 19 },
8708 /* 8169 */ { MAD_F(0x050554eb) /* 0.313801689 */, 19 },
8709 /* 8170 */ { MAD_F(0x05058aa0) /* 0.313852909 */, 19 },
8710 /* 8171 */ { MAD_F(0x0505c056) /* 0.313904130 */, 19 },
8711 /* 8172 */ { MAD_F(0x0505f60c) /* 0.313955354 */, 19 },
8712 /* 8173 */ { MAD_F(0x05062bc3) /* 0.314006579 */, 19 },
8713 /* 8174 */ { MAD_F(0x0506617a) /* 0.314057807 */, 19 },
8714 /* 8175 */ { MAD_F(0x05069732) /* 0.314109037 */, 19 },
8715
8716 /* 8176 */ { MAD_F(0x0506cceb) /* 0.314160269 */, 19 },
8717 /* 8177 */ { MAD_F(0x050702a4) /* 0.314211502 */, 19 },
8718 /* 8178 */ { MAD_F(0x0507385d) /* 0.314262739 */, 19 },
8719 /* 8179 */ { MAD_F(0x05076e17) /* 0.314313977 */, 19 },
8720 /* 8180 */ { MAD_F(0x0507a3d2) /* 0.314365217 */, 19 },
8721 /* 8181 */ { MAD_F(0x0507d98d) /* 0.314416459 */, 19 },
8722 /* 8182 */ { MAD_F(0x05080f49) /* 0.314467704 */, 19 },
8723 /* 8183 */ { MAD_F(0x05084506) /* 0.314518950 */, 19 },
8724 /* 8184 */ { MAD_F(0x05087ac2) /* 0.314570199 */, 19 },
8725 /* 8185 */ { MAD_F(0x0508b080) /* 0.314621449 */, 19 },
8726 /* 8186 */ { MAD_F(0x0508e63e) /* 0.314672702 */, 19 },
8727 /* 8187 */ { MAD_F(0x05091bfd) /* 0.314723957 */, 19 },
8728 /* 8188 */ { MAD_F(0x050951bc) /* 0.314775214 */, 19 },
8729 /* 8189 */ { MAD_F(0x0509877c) /* 0.314826473 */, 19 },
8730 /* 8190 */ { MAD_F(0x0509bd3c) /* 0.314877734 */, 19 },
8731 /* 8191 */ { MAD_F(0x0509f2fd) /* 0.314928997 */, 19 },
8732
8733 /* 8192 */ { MAD_F(0x050a28be) /* 0.314980262 */, 19 },
8734 /* 8193 */ { MAD_F(0x050a5e80) /* 0.315031530 */, 19 },
8735 /* 8194 */ { MAD_F(0x050a9443) /* 0.315082799 */, 19 },
8736 /* 8195 */ { MAD_F(0x050aca06) /* 0.315134071 */, 19 },
8737 /* 8196 */ { MAD_F(0x050affc9) /* 0.315185344 */, 19 },
8738 /* 8197 */ { MAD_F(0x050b358e) /* 0.315236620 */, 19 },
8739 /* 8198 */ { MAD_F(0x050b6b52) /* 0.315287898 */, 19 },
8740 /* 8199 */ { MAD_F(0x050ba118) /* 0.315339178 */, 19 },
8741 /* 8200 */ { MAD_F(0x050bd6de) /* 0.315390460 */, 19 },
8742 /* 8201 */ { MAD_F(0x050c0ca4) /* 0.315441744 */, 19 },
8743 /* 8202 */ { MAD_F(0x050c426b) /* 0.315493030 */, 19 },
8744 /* 8203 */ { MAD_F(0x050c7833) /* 0.315544318 */, 19 },
8745 /* 8204 */ { MAD_F(0x050cadfb) /* 0.315595608 */, 19 },
8746 /* 8205 */ { MAD_F(0x050ce3c4) /* 0.315646901 */, 19 },
8747 /* 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 @@
1/*
2 * mad - MPEG audio decoder
3 * Copyright (C) 2000-2001 Robert Leslie
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * $Id$
20 */
21
22/*
23 * These are the scalefactor values for Layer I and Layer II.
24 * The values are from Table B.1 of ISO/IEC 11172-3.
25 *
26 * There is some error introduced by the 32-bit fixed-point representation;
27 * the amount of error is shown. For 16-bit PCM output, this shouldn't be
28 * too much of a problem.
29 */
30
31 MAD_F(0x20000000), /* 2.000000000000 => 2.000000000000, e 0.000000000000 */
32 MAD_F(0x1965fea5), /* 1.587401051968 => 1.587401051074, e 0.000000000894 */
33 MAD_F(0x1428a2fa), /* 1.259921049895 => 1.259921051562, e -0.000000001667 */
34 MAD_F(0x10000000), /* 1.000000000000 => 1.000000000000, e 0.000000000000 */
35 MAD_F(0x0cb2ff53), /* 0.793700525984 => 0.793700527400, e -0.000000001416 */
36 MAD_F(0x0a14517d), /* 0.629960524947 => 0.629960525781, e -0.000000000833 */
37 MAD_F(0x08000000), /* 0.500000000000 => 0.500000000000, e 0.000000000000 */
38 MAD_F(0x06597fa9), /* 0.396850262992 => 0.396850261837, e 0.000000001155 */
39
40 MAD_F(0x050a28be), /* 0.314980262474 => 0.314980261028, e 0.000000001446 */
41 MAD_F(0x04000000), /* 0.250000000000 => 0.250000000000, e 0.000000000000 */
42 MAD_F(0x032cbfd5), /* 0.198425131496 => 0.198425132781, e -0.000000001285 */
43 MAD_F(0x0285145f), /* 0.157490131237 => 0.157490130514, e 0.000000000723 */
44 MAD_F(0x02000000), /* 0.125000000000 => 0.125000000000, e 0.000000000000 */
45 MAD_F(0x01965fea), /* 0.099212565748 => 0.099212564528, e 0.000000001220 */
46 MAD_F(0x01428a30), /* 0.078745065618 => 0.078745067120, e -0.000000001501 */
47 MAD_F(0x01000000), /* 0.062500000000 => 0.062500000000, e 0.000000000000 */
48
49 MAD_F(0x00cb2ff5), /* 0.049606282874 => 0.049606282264, e 0.000000000610 */
50 MAD_F(0x00a14518), /* 0.039372532809 => 0.039372533560, e -0.000000000751 */
51 MAD_F(0x00800000), /* 0.031250000000 => 0.031250000000, e 0.000000000000 */
52 MAD_F(0x006597fb), /* 0.024803141437 => 0.024803142995, e -0.000000001558 */
53 MAD_F(0x0050a28c), /* 0.019686266405 => 0.019686266780, e -0.000000000375 */
54 MAD_F(0x00400000), /* 0.015625000000 => 0.015625000000, e 0.000000000000 */
55 MAD_F(0x0032cbfd), /* 0.012401570719 => 0.012401569635, e 0.000000001084 */
56 MAD_F(0x00285146), /* 0.009843133202 => 0.009843133390, e -0.000000000188 */
57
58 MAD_F(0x00200000), /* 0.007812500000 => 0.007812500000, e 0.000000000000 */
59 MAD_F(0x001965ff), /* 0.006200785359 => 0.006200786680, e -0.000000001321 */
60 MAD_F(0x001428a3), /* 0.004921566601 => 0.004921566695, e -0.000000000094 */
61 MAD_F(0x00100000), /* 0.003906250000 => 0.003906250000, e 0.000000000000 */
62 MAD_F(0x000cb2ff), /* 0.003100392680 => 0.003100391477, e 0.000000001202 */
63 MAD_F(0x000a1451), /* 0.002460783301 => 0.002460781485, e 0.000000001816 */
64 MAD_F(0x00080000), /* 0.001953125000 => 0.001953125000, e 0.000000000000 */
65 MAD_F(0x00065980), /* 0.001550196340 => 0.001550197601, e -0.000000001262 */
66
67 MAD_F(0x00050a29), /* 0.001230391650 => 0.001230392605, e -0.000000000955 */
68 MAD_F(0x00040000), /* 0.000976562500 => 0.000976562500, e 0.000000000000 */
69 MAD_F(0x00032cc0), /* 0.000775098170 => 0.000775098801, e -0.000000000631 */
70 MAD_F(0x00028514), /* 0.000615195825 => 0.000615194440, e 0.000000001385 */
71 MAD_F(0x00020000), /* 0.000488281250 => 0.000488281250, e 0.000000000000 */
72 MAD_F(0x00019660), /* 0.000387549085 => 0.000387549400, e -0.000000000315 */
73 MAD_F(0x0001428a), /* 0.000307597913 => 0.000307597220, e 0.000000000693 */
74 MAD_F(0x00010000), /* 0.000244140625 => 0.000244140625, e 0.000000000000 */
75
76 MAD_F(0x0000cb30), /* 0.000193774542 => 0.000193774700, e -0.000000000158 */
77 MAD_F(0x0000a145), /* 0.000153798956 => 0.000153798610, e 0.000000000346 */
78 MAD_F(0x00008000), /* 0.000122070313 => 0.000122070313, e 0.000000000000 */
79 MAD_F(0x00006598), /* 0.000096887271 => 0.000096887350, e -0.000000000079 */
80 MAD_F(0x000050a3), /* 0.000076899478 => 0.000076901168, e -0.000000001689 */
81 MAD_F(0x00004000), /* 0.000061035156 => 0.000061035156, e 0.000000000000 */
82 MAD_F(0x000032cc), /* 0.000048443636 => 0.000048443675, e -0.000000000039 */
83 MAD_F(0x00002851), /* 0.000038449739 => 0.000038448721, e 0.000000001018 */
84
85 MAD_F(0x00002000), /* 0.000030517578 => 0.000030517578, e 0.000000000000 */
86 MAD_F(0x00001966), /* 0.000024221818 => 0.000024221838, e -0.000000000020 */
87 MAD_F(0x00001429), /* 0.000019224870 => 0.000019226223, e -0.000000001354 */
88 MAD_F(0x00001000), /* 0.000015258789 => 0.000015258789, e -0.000000000000 */
89 MAD_F(0x00000cb3), /* 0.000012110909 => 0.000012110919, e -0.000000000010 */
90 MAD_F(0x00000a14), /* 0.000009612435 => 0.000009611249, e 0.000000001186 */
91 MAD_F(0x00000800), /* 0.000007629395 => 0.000007629395, e -0.000000000000 */
92 MAD_F(0x00000659), /* 0.000006055454 => 0.000006053597, e 0.000000001858 */
93
94 MAD_F(0x0000050a), /* 0.000004806217 => 0.000004805624, e 0.000000000593 */
95 MAD_F(0x00000400), /* 0.000003814697 => 0.000003814697, e 0.000000000000 */
96 MAD_F(0x0000032d), /* 0.000003027727 => 0.000003028661, e -0.000000000934 */
97 MAD_F(0x00000285), /* 0.000002403109 => 0.000002402812, e 0.000000000296 */
98 MAD_F(0x00000200), /* 0.000001907349 => 0.000001907349, e -0.000000000000 */
99 MAD_F(0x00000196), /* 0.000001513864 => 0.000001512468, e 0.000000001396 */
100 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 @@
1/*
2 * mad - MPEG audio decoder
3 * Copyright (C) 2000-2001 Robert Leslie
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * $Id$
20 */
21
22# ifdef HAVE_CONFIG_H
23# include "libmad_config.h"
24# endif
25
26# include "libmad_global.h"
27
28# include <stdlib.h>
29
30# include "bit.h"
31# include "stream.h"
32
33/*
34 * NAME:stream->init()
35 * DESCRIPTION:initialize stream struct
36 */
37void mad_stream_init(struct mad_stream *stream)
38{
39 stream->buffer = 0;
40 stream->bufend = 0;
41 stream->skiplen = 0;
42
43 stream->sync = 0;
44 stream->freerate = 0;
45
46 stream->this_frame = 0;
47 stream->next_frame = 0;
48 mad_bit_init(&stream->ptr, 0);
49
50 mad_bit_init(&stream->anc_ptr, 0);
51 stream->anc_bitlen = 0;
52
53 stream->main_data = 0;
54 stream->md_len = 0;
55
56 stream->options = 0;
57 stream->error = 0;
58}
59
60/*
61 * NAME:stream->finish()
62 * DESCRIPTION:deallocate any dynamic memory associated with stream
63 */
64void mad_stream_finish(struct mad_stream *stream)
65{
66 if (stream->main_data) {
67 free(stream->main_data);
68 stream->main_data = 0;
69 }
70
71 mad_bit_finish(&stream->anc_ptr);
72 mad_bit_finish(&stream->ptr);
73}
74
75/*
76 * NAME:stream->buffer()
77 * DESCRIPTION:set stream buffer pointers
78 */
79void mad_stream_buffer(struct mad_stream *stream,
80 unsigned char const *buffer, unsigned long length)
81{
82 stream->buffer = buffer;
83 stream->bufend = buffer + length;
84
85 stream->this_frame = buffer;
86 stream->next_frame = buffer;
87
88 stream->sync = 1;
89
90 mad_bit_init(&stream->ptr, buffer);
91}
92
93/*
94 * NAME:stream->skip()
95 * DESCRIPTION:arrange to skip bytes before the next frame
96 */
97void mad_stream_skip(struct mad_stream *stream, unsigned long length)
98{
99 stream->skiplen += length;
100}
101
102/*
103 * NAME:stream->sync()
104 * DESCRIPTION:locate the next stream sync word
105 */
106int mad_stream_sync(struct mad_stream *stream)
107{
108 register unsigned char const *ptr, *end;
109
110 ptr = mad_bit_nextbyte(&stream->ptr);
111 end = stream->bufend;
112
113 while (ptr < end - 1 &&
114 !(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0))
115 ++ptr;
116
117 if (end - ptr < MAD_BUFFER_GUARD)
118 return -1;
119
120 mad_bit_init(&stream->ptr, ptr);
121
122 return 0;
123}
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 @@
1/*
2 * mad - MPEG audio decoder
3 * Copyright (C) 2000-2001 Robert Leslie
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * $Id$
20 */
21
22# ifndef LIBMAD_STREAM_H
23# define LIBMAD_STREAM_H
24
25# include "bit.h"
26
27 # define MAD_BUFFER_GUARD8
28 # define MAD_BUFFER_MDLEN(511 + 2048 + MAD_BUFFER_GUARD)
29
30enum mad_error {
31 MAD_ERROR_BUFLEN = 0x0001,/* input buffer too small (or EOF) */
32 MAD_ERROR_BUFPTR = 0x0002,/* invalid (null) buffer pointer */
33
34 MAD_ERROR_NOMEM = 0x0031,/* not enough memory */
35
36 MAD_ERROR_LOSTSYNC = 0x0101,/* lost synchronization */
37 MAD_ERROR_BADLAYER = 0x0102,/* reserved header layer value */
38 MAD_ERROR_BADBITRATE = 0x0103,/* forbidden bitrate value */
39 MAD_ERROR_BADSAMPLERATE = 0x0104,/* reserved sample frequency value */
40 MAD_ERROR_BADEMPHASIS = 0x0105,/* reserved emphasis value */
41
42 MAD_ERROR_BADCRC = 0x0201,/* CRC check failed */
43 MAD_ERROR_BADBITALLOC = 0x0211,/* forbidden bit allocation value */
44 MAD_ERROR_BADSCALEFACTOR = 0x0221,/* bad scalefactor index */
45 MAD_ERROR_BADFRAMELEN = 0x0231,/* bad frame length */
46 MAD_ERROR_BADBIGVALUES = 0x0232,/* bad big_values count */
47 MAD_ERROR_BADBLOCKTYPE = 0x0233,/* reserved block_type */
48 MAD_ERROR_BADSCFSI = 0x0234,/* bad scalefactor selection info */
49 MAD_ERROR_BADDATAPTR = 0x0235,/* bad main_data_begin pointer */
50 MAD_ERROR_BADPART3LEN = 0x0236,/* bad audio data length */
51 MAD_ERROR_BADHUFFTABLE = 0x0237,/* bad Huffman table select */
52 MAD_ERROR_BADHUFFDATA = 0x0238,/* Huffman data overrun */
53 MAD_ERROR_BADSTEREO = 0x0239/* incompatible block_type for JS */
54};
55
56 # define MAD_RECOVERABLE(error)((error) & 0xff00)
57
58struct mad_stream {
59 unsigned char const *buffer; /* input bitstream buffer */
60 unsigned char const *bufend; /* end of buffer */
61 unsigned long skiplen; /* bytes to skip before next frame */
62
63 int sync; /* stream sync found */
64 unsigned long freerate; /* free bitrate (fixed) */
65
66 unsigned char const *this_frame;/* start of current frame */
67 unsigned char const *next_frame;/* start of next frame */
68 struct mad_bitptr ptr; /* current processing bit pointer */
69
70 struct mad_bitptr anc_ptr; /* ancillary bits pointer */
71 unsigned int anc_bitlen; /* number of ancillary bits */
72
73 unsigned char (*main_data)[MAD_BUFFER_MDLEN];
74 /* Layer III main_data() */
75 unsigned int md_len; /* bytes in main_data */
76
77 int options; /* decoding options (see below) */
78 enum mad_error error; /* error code (see above) */
79};
80
81enum {
82 MAD_OPTION_IGNORECRC = 0x0001,/* ignore CRC errors */
83 MAD_OPTION_HALFSAMPLERATE = 0x0002,/* generate PCM at 1/2 sample rate */
84# if 0 /* not yet implemented */
85 MAD_OPTION_LEFTCHANNEL = 0x0010,/* decode left channel only */
86 MAD_OPTION_RIGHTCHANNEL = 0x0020,/* decode right channel only */
87 MAD_OPTION_SINGLECHANNEL = 0x0030,/* combine channels */
88# endif
89};
90
91void mad_stream_init(struct mad_stream *);
92void mad_stream_finish(struct mad_stream *);
93
94# define mad_stream_options(stream, opts) ((stream)->options = (opts))
95
96void mad_stream_buffer(struct mad_stream *,
97 unsigned char const *, unsigned long);
98void mad_stream_skip(struct mad_stream *, unsigned long);
99
100int mad_stream_sync(struct mad_stream *);
101
102# 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 @@
1/*
2 * mad - MPEG audio decoder
3 * Copyright (C) 2000-2001 Robert Leslie
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * $Id$
20 */
21
22# ifdef HAVE_CONFIG_H
23# include "libmad_config.h"
24# endif
25
26# include "libmad_global.h"
27
28# include "fixed.h"
29# include "frame.h"
30# include "synth.h"
31
32/*
33 * NAME:synth->init()
34 * DESCRIPTION:initialize synth struct
35 */
36void mad_synth_init(struct mad_synth *synth)
37{
38 mad_synth_mute(synth);
39
40 synth->phase = 0;
41
42 synth->pcm.samplerate = 0;
43 synth->pcm.channels = 0;
44 synth->pcm.length = 0;
45}
46
47/*
48 * NAME:synth->mute()
49 * DESCRIPTION:zero all polyphase filterbank values, resetting synthesis
50 */
51void mad_synth_mute(struct mad_synth *synth)
52{
53 unsigned int ch, s, v;
54
55 for (ch = 0; ch < 2; ++ch) {
56 for (s = 0; s < 16; ++s) {
57 for (v = 0; v < 8; ++v) {
58 synth->filter[ch][0][0][s][v] = synth->filter[ch][0][1][s][v] =
59 synth->filter[ch][1][0][s][v] = synth->filter[ch][1][1][s][v] = 0;
60 }
61 }
62 }
63}
64
65/*
66 * An optional optimization called here the Subband Synthesis Optimization
67 * (SSO) improves the performance of subband synthesis at the expense of
68 * accuracy.
69 *
70 * The idea is to simplify 32x32->64-bit multiplication to 32x32->32 such
71 * that extra scaling and rounding are not necessary. This often allows the
72 * compiler to use faster 32-bit multiply-accumulate instructions instead of
73 * explicit 64-bit multiply, shift, and add instructions.
74 *
75 * SSO works like this: a full 32x32->64-bit multiply of two mad_fixed_t
76 * values requires the result to be right-shifted 28 bits to be properly
77 * scaled to the same fixed-point format. Right shifts can be applied at any
78 * time to either operand or to the result, so the optimization involves
79 * careful placement of these shifts to minimize the loss of accuracy.
80 *
81 * First, a 14-bit shift is applied with rounding at compile-time to the D[]
82 * table of coefficients for the subband synthesis window. This only loses 2
83 * bits of accuracy because the lower 12 bits are always zero. A second
84 * 12-bit shift occurs after the DCT calculation. This loses 12 bits of
85 * accuracy. Finally, a third 2-bit shift occurs just before the sample is
86 * saved in the PCM buffer. 14 + 12 + 2 == 28 bits.
87 */
88
89/* FPM_DEFAULT without OPT_SSO will actually lose accuracy and performance */
90
91# if defined(FPM_DEFAULT) && !defined(OPT_SSO)
92# define OPT_SSO
93# endif
94
95/* second SSO shift, with rounding */
96
97# if defined(OPT_SSO)
98# define SHIFT(x) (((x) + (1L << 11)) >> 12)
99# else
100# define SHIFT(x) (x)
101# endif
102
103/* possible DCT speed optimization */
104
105# if defined(OPT_SPEED) && defined(MAD_F_MLX)
106# define OPT_DCTO
107# define MUL(x, y) \
108 ({ mad_fixed64hi_t hi; \
109 mad_fixed64lo_t lo; \
110 MAD_F_MLX(hi, lo, (x), (y)); \
111 hi << (32 - MAD_F_SCALEBITS - 3); \
112 })
113# else
114# undef OPT_DCTO
115# define MUL(x, y) mad_f_mul((x), (y))
116# endif
117
118/*
119 * NAME:dct32()
120 * DESCRIPTION:perform fast in[32]->out[32] DCT
121 */
122static
123void dct32(mad_fixed_t const in[32], unsigned int slot,
124 mad_fixed_t lo[16][8], mad_fixed_t hi[16][8])
125{
126 mad_fixed_t t0, t1, t2, t3, t4, t5, t6, t7;
127 mad_fixed_t t8, t9, t10, t11, t12, t13, t14, t15;
128 mad_fixed_t t16, t17, t18, t19, t20, t21, t22, t23;
129 mad_fixed_t t24, t25, t26, t27, t28, t29, t30, t31;
130 mad_fixed_t t32, t33, t34, t35, t36, t37, t38, t39;
131 mad_fixed_t t40, t41, t42, t43, t44, t45, t46, t47;
132 mad_fixed_t t48, t49, t50, t51, t52, t53, t54, t55;
133 mad_fixed_t t56, t57, t58, t59, t60, t61, t62, t63;
134 mad_fixed_t t64, t65, t66, t67, t68, t69, t70, t71;
135 mad_fixed_t t72, t73, t74, t75, t76, t77, t78, t79;
136 mad_fixed_t t80, t81, t82, t83, t84, t85, t86, t87;
137 mad_fixed_t t88, t89, t90, t91, t92, t93, t94, t95;
138 mad_fixed_t t96, t97, t98, t99, t100, t101, t102, t103;
139 mad_fixed_t t104, t105, t106, t107, t108, t109, t110, t111;
140 mad_fixed_t t112, t113, t114, t115, t116, t117, t118, t119;
141 mad_fixed_t t120, t121, t122, t123, t124, t125, t126, t127;
142 mad_fixed_t t128, t129, t130, t131, t132, t133, t134, t135;
143 mad_fixed_t t136, t137, t138, t139, t140, t141, t142, t143;
144 mad_fixed_t t144, t145, t146, t147, t148, t149, t150, t151;
145 mad_fixed_t t152, t153, t154, t155, t156, t157, t158, t159;
146 mad_fixed_t t160, t161, t162, t163, t164, t165, t166, t167;
147 mad_fixed_t t168, t169, t170, t171, t172, t173, t174, t175;
148 mad_fixed_t t176;
149
150 /* costab[i] = cos(PI / (2 * 32) * i) */
151
152# if defined(OPT_DCTO)
153 enum {
154 costab1 = MAD_F(0x7fd8878e),
155 costab2 = MAD_F(0x7f62368f),
156 costab3 = MAD_F(0x7e9d55fc),
157 costab4 = MAD_F(0x7d8a5f40),
158 costab5 = MAD_F(0x7c29fbee),
159 costab6 = MAD_F(0x7a7d055b),
160 costab7 = MAD_F(0x78848414),
161 costab8 = MAD_F(0x7641af3d),
162 costab9 = MAD_F(0x73b5ebd1),
163 costab10 = MAD_F(0x70e2cbc6),
164 costab11 = MAD_F(0x6dca0d14),
165 costab12 = MAD_F(0x6a6d98a4),
166 costab13 = MAD_F(0x66cf8120),
167 costab14 = MAD_F(0x62f201ac),
168 costab15 = MAD_F(0x5ed77c8a),
169 costab16 = MAD_F(0x5a82799a),
170 costab17 = MAD_F(0x55f5a4d2),
171 costab18 = MAD_F(0x5133cc94),
172 costab19 = MAD_F(0x4c3fdff4),
173 costab20 = MAD_F(0x471cece7),
174 costab21 = MAD_F(0x41ce1e65),
175 costab22 = MAD_F(0x3c56ba70),
176 costab23 = MAD_F(0x36ba2014),
177 costab24 = MAD_F(0x30fbc54d),
178 costab25 = MAD_F(0x2b1f34eb),
179 costab26 = MAD_F(0x25280c5e),
180 costab27 = MAD_F(0x1f19f97b),
181 costab28 = MAD_F(0x18f8b83c),
182 costab29 = MAD_F(0x12c8106f),
183 costab30 = MAD_F(0x0c8bd35e),
184 costab31 = MAD_F(0x0647d97c)
185 };
186# else
187 enum {
188 costab1 = MAD_F(0x0ffb10f2), /* 0.998795456 */
189 costab2 = MAD_F(0x0fec46d2), /* 0.995184727 */
190 costab3 = MAD_F(0x0fd3aac0), /* 0.989176510 */
191 costab4 = MAD_F(0x0fb14be8), /* 0.980785280 */
192 costab5 = MAD_F(0x0f853f7e), /* 0.970031253 */
193 costab6 = MAD_F(0x0f4fa0ab), /* 0.956940336 */
194 costab7 = MAD_F(0x0f109082), /* 0.941544065 */
195 costab8 = MAD_F(0x0ec835e8), /* 0.923879533 */
196 costab9 = MAD_F(0x0e76bd7a), /* 0.903989293 */
197 costab10 = MAD_F(0x0e1c5979), /* 0.881921264 */
198 costab11 = MAD_F(0x0db941a3), /* 0.857728610 */
199 costab12 = MAD_F(0x0d4db315), /* 0.831469612 */
200 costab13 = MAD_F(0x0cd9f024), /* 0.803207531 */
201 costab14 = MAD_F(0x0c5e4036), /* 0.773010453 */
202 costab15 = MAD_F(0x0bdaef91), /* 0.740951125 */
203 costab16 = MAD_F(0x0b504f33), /* 0.707106781 */
204 costab17 = MAD_F(0x0abeb49a), /* 0.671558955 */
205 costab18 = MAD_F(0x0a267993), /* 0.634393284 */
206 costab19 = MAD_F(0x0987fbfe), /* 0.595699304 */
207 costab20 = MAD_F(0x08e39d9d), /* 0.555570233 */
208 costab21 = MAD_F(0x0839c3cd), /* 0.514102744 */
209 costab22 = MAD_F(0x078ad74e), /* 0.471396737 */
210 costab23 = MAD_F(0x06d74402), /* 0.427555093 */
211 costab24 = MAD_F(0x061f78aa), /* 0.382683432 */
212 costab25 = MAD_F(0x0563e69d), /* 0.336889853 */
213 costab26 = MAD_F(0x04a5018c), /* 0.290284677 */
214 costab27 = MAD_F(0x03e33f2f), /* 0.242980180 */
215 costab28 = MAD_F(0x031f1708), /* 0.195090322 */
216 costab29 = MAD_F(0x0259020e), /* 0.146730474 */
217 costab30 = MAD_F(0x01917a6c), /* 0.098017140 */
218 costab31 = MAD_F(0x00c8fb30) /* 0.049067674 */
219 };
220# endif
221
222 t0 = in[0] + in[31]; t16 = MUL(in[0] - in[31], costab1);
223 t1 = in[15] + in[16]; t17 = MUL(in[15] - in[16], costab31);
224
225 t41 = t16 + t17;
226 t59 = MUL(t16 - t17, costab2);
227 t33 = t0 + t1;
228 t50 = MUL(t0 - t1, costab2);
229
230 t2 = in[7] + in[24]; t18 = MUL(in[7] - in[24], costab15);
231 t3 = in[8] + in[23]; t19 = MUL(in[8] - in[23], costab17);
232
233 t42 = t18 + t19;
234 t60 = MUL(t18 - t19, costab30);
235 t34 = t2 + t3;
236 t51 = MUL(t2 - t3, costab30);
237
238 t4 = in[3] + in[28]; t20 = MUL(in[3] - in[28], costab7);
239 t5 = in[12] + in[19]; t21 = MUL(in[12] - in[19], costab25);
240
241 t43 = t20 + t21;
242 t61 = MUL(t20 - t21, costab14);
243 t35 = t4 + t5;
244 t52 = MUL(t4 - t5, costab14);
245
246 t6 = in[4] + in[27]; t22 = MUL(in[4] - in[27], costab9);
247 t7 = in[11] + in[20]; t23 = MUL(in[11] - in[20], costab23);
248
249 t44 = t22 + t23;
250 t62 = MUL(t22 - t23, costab18);
251 t36 = t6 + t7;
252 t53 = MUL(t6 - t7, costab18);
253
254 t8 = in[1] + in[30]; t24 = MUL(in[1] - in[30], costab3);
255 t9 = in[14] + in[17]; t25 = MUL(in[14] - in[17], costab29);
256
257 t45 = t24 + t25;
258 t63 = MUL(t24 - t25, costab6);
259 t37 = t8 + t9;
260 t54 = MUL(t8 - t9, costab6);
261
262 t10 = in[6] + in[25]; t26 = MUL(in[6] - in[25], costab13);
263 t11 = in[9] + in[22]; t27 = MUL(in[9] - in[22], costab19);
264
265 t46 = t26 + t27;
266 t64 = MUL(t26 - t27, costab26);
267 t38 = t10 + t11;
268 t55 = MUL(t10 - t11, costab26);
269
270 t12 = in[2] + in[29]; t28 = MUL(in[2] - in[29], costab5);
271 t13 = in[13] + in[18]; t29 = MUL(in[13] - in[18], costab27);
272
273 t47 = t28 + t29;
274 t65 = MUL(t28 - t29, costab10);
275 t39 = t12 + t13;
276 t56 = MUL(t12 - t13, costab10);
277
278 t14 = in[5] + in[26]; t30 = MUL(in[5] - in[26], costab11);
279 t15 = in[10] + in[21]; t31 = MUL(in[10] - in[21], costab21);
280
281 t48 = t30 + t31;
282 t66 = MUL(t30 - t31, costab22);
283 t40 = t14 + t15;
284 t57 = MUL(t14 - t15, costab22);
285
286 t69 = t33 + t34; t89 = MUL(t33 - t34, costab4);
287 t70 = t35 + t36; t90 = MUL(t35 - t36, costab28);
288 t71 = t37 + t38; t91 = MUL(t37 - t38, costab12);
289 t72 = t39 + t40; t92 = MUL(t39 - t40, costab20);
290 t73 = t41 + t42; t94 = MUL(t41 - t42, costab4);
291 t74 = t43 + t44; t95 = MUL(t43 - t44, costab28);
292 t75 = t45 + t46; t96 = MUL(t45 - t46, costab12);
293 t76 = t47 + t48; t97 = MUL(t47 - t48, costab20);
294
295 t78 = t50 + t51; t100 = MUL(t50 - t51, costab4);
296 t79 = t52 + t53; t101 = MUL(t52 - t53, costab28);
297 t80 = t54 + t55; t102 = MUL(t54 - t55, costab12);
298 t81 = t56 + t57; t103 = MUL(t56 - t57, costab20);
299
300 t83 = t59 + t60; t106 = MUL(t59 - t60, costab4);
301 t84 = t61 + t62; t107 = MUL(t61 - t62, costab28);
302 t85 = t63 + t64; t108 = MUL(t63 - t64, costab12);
303 t86 = t65 + t66; t109 = MUL(t65 - t66, costab20);
304
305 t113 = t69 + t70;
306 t114 = t71 + t72;
307
308 /* 0 */ hi[15][slot] = SHIFT(t113 + t114);
309 /* 16 */ lo[ 0][slot] = SHIFT(MUL(t113 - t114, costab16));
310
311 t115 = t73 + t74;
312 t116 = t75 + t76;
313
314 t32 = t115 + t116;
315
316 /* 1 */ hi[14][slot] = SHIFT(t32);
317
318 t118 = t78 + t79;
319 t119 = t80 + t81;
320
321 t58 = t118 + t119;
322
323 /* 2 */ hi[13][slot] = SHIFT(t58);
324
325 t121 = t83 + t84;
326 t122 = t85 + t86;
327
328 t67 = t121 + t122;
329
330 t49 = (t67 << 1) - t32;
331
332 /* 3 */ hi[12][slot] = SHIFT(t49);
333
334 t125 = t89 + t90;
335 t126 = t91 + t92;
336
337 t93 = t125 + t126;
338
339 /* 4 */ hi[11][slot] = SHIFT(t93);
340
341 t128 = t94 + t95;
342 t129 = t96 + t97;
343
344 t98 = t128 + t129;
345
346 t68 = (t98 << 1) - t49;
347
348 /* 5 */ hi[10][slot] = SHIFT(t68);
349
350 t132 = t100 + t101;
351 t133 = t102 + t103;
352
353 t104 = t132 + t133;
354
355 t82 = (t104 << 1) - t58;
356
357 /* 6 */ hi[ 9][slot] = SHIFT(t82);
358
359 t136 = t106 + t107;
360 t137 = t108 + t109;
361
362 t110 = t136 + t137;
363
364 t87 = (t110 << 1) - t67;
365
366 t77 = (t87 << 1) - t68;
367
368 /* 7 */ hi[ 8][slot] = SHIFT(t77);
369
370 t141 = MUL(t69 - t70, costab8);
371 t142 = MUL(t71 - t72, costab24);
372 t143 = t141 + t142;
373
374 /* 8 */ hi[ 7][slot] = SHIFT(t143);
375 /* 24 */ lo[ 8][slot] =
376 SHIFT((MUL(t141 - t142, costab16) << 1) - t143);
377
378 t144 = MUL(t73 - t74, costab8);
379 t145 = MUL(t75 - t76, costab24);
380 t146 = t144 + t145;
381
382 t88 = (t146 << 1) - t77;
383
384 /* 9 */ hi[ 6][slot] = SHIFT(t88);
385
386 t148 = MUL(t78 - t79, costab8);
387 t149 = MUL(t80 - t81, costab24);
388 t150 = t148 + t149;
389
390 t105 = (t150 << 1) - t82;
391
392 /* 10 */ hi[ 5][slot] = SHIFT(t105);
393
394 t152 = MUL(t83 - t84, costab8);
395 t153 = MUL(t85 - t86, costab24);
396 t154 = t152 + t153;
397
398 t111 = (t154 << 1) - t87;
399
400 t99 = (t111 << 1) - t88;
401
402 /* 11 */ hi[ 4][slot] = SHIFT(t99);
403
404 t157 = MUL(t89 - t90, costab8);
405 t158 = MUL(t91 - t92, costab24);
406 t159 = t157 + t158;
407
408 t127 = (t159 << 1) - t93;
409
410 /* 12 */ hi[ 3][slot] = SHIFT(t127);
411
412 t160 = (MUL(t125 - t126, costab16) << 1) - t127;
413
414 /* 20 */ lo[ 4][slot] = SHIFT(t160);
415 /* 28 */ lo[12][slot] =
416 SHIFT((((MUL(t157 - t158, costab16) << 1) - t159) << 1) - t160);
417
418 t161 = MUL(t94 - t95, costab8);
419 t162 = MUL(t96 - t97, costab24);
420 t163 = t161 + t162;
421
422 t130 = (t163 << 1) - t98;
423
424 t112 = (t130 << 1) - t99;
425
426 /* 13 */ hi[ 2][slot] = SHIFT(t112);
427
428 t164 = (MUL(t128 - t129, costab16) << 1) - t130;
429
430 t166 = MUL(t100 - t101, costab8);
431 t167 = MUL(t102 - t103, costab24);
432 t168 = t166 + t167;
433
434 t134 = (t168 << 1) - t104;
435
436 t120 = (t134 << 1) - t105;
437
438 /* 14 */ hi[ 1][slot] = SHIFT(t120);
439
440 t135 = (MUL(t118 - t119, costab16) << 1) - t120;
441
442 /* 18 */ lo[ 2][slot] = SHIFT(t135);
443
444 t169 = (MUL(t132 - t133, costab16) << 1) - t134;
445
446 t151 = (t169 << 1) - t135;
447
448 /* 22 */ lo[ 6][slot] = SHIFT(t151);
449
450 t170 = (((MUL(t148 - t149, costab16) << 1) - t150) << 1) - t151;
451
452 /* 26 */ lo[10][slot] = SHIFT(t170);
453 /* 30 */ lo[14][slot] =
454 SHIFT((((((MUL(t166 - t167, costab16) << 1) -
455 t168) << 1) - t169) << 1) - t170);
456
457 t171 = MUL(t106 - t107, costab8);
458 t172 = MUL(t108 - t109, costab24);
459 t173 = t171 + t172;
460
461 t138 = (t173 << 1) - t110;
462
463 t123 = (t138 << 1) - t111;
464
465 t139 = (MUL(t121 - t122, costab16) << 1) - t123;
466
467 t117 = (t123 << 1) - t112;
468
469 /* 15 */ hi[ 0][slot] = SHIFT(t117);
470
471 t124 = (MUL(t115 - t116, costab16) << 1) - t117;
472
473 /* 17 */ lo[ 1][slot] = SHIFT(t124);
474
475 t131 = (t139 << 1) - t124;
476
477 /* 19 */ lo[ 3][slot] = SHIFT(t131);
478
479 t140 = (t164 << 1) - t131;
480
481 /* 21 */ lo[ 5][slot] = SHIFT(t140);
482
483 t174 = (MUL(t136 - t137, costab16) << 1) - t138;
484
485 t155 = (t174 << 1) - t139;
486
487 t147 = (t155 << 1) - t140;
488
489 /* 23 */ lo[ 7][slot] = SHIFT(t147);
490
491 t156 = (((MUL(t144 - t145, costab16) << 1) - t146) << 1) - t147;
492
493 /* 25 */ lo[ 9][slot] = SHIFT(t156);
494
495 t175 = (((MUL(t152 - t153, costab16) << 1) - t154) << 1) - t155;
496
497 t165 = (t175 << 1) - t156;
498
499 /* 27 */ lo[11][slot] = SHIFT(t165);
500
501 t176 = (((((MUL(t161 - t162, costab16) << 1) -
502 t163) << 1) - t164) << 1) - t165;
503
504 /* 29 */ lo[13][slot] = SHIFT(t176);
505 /* 31 */ lo[15][slot] =
506 SHIFT((((((((MUL(t171 - t172, costab16) << 1) -
507 t173) << 1) - t174) << 1) - t175) << 1) - t176);
508
509 /*
510 * Totals:
511 * 80 multiplies
512 * 80 additions
513 * 119 subtractions
514 * 49 shifts (not counting SSO)
515 */
516}
517
518# undef MUL
519# undef SHIFT
520
521/* third SSO shift and/or D[] optimization preshift */
522
523# if defined(OPT_SSO)
524# if MAD_F_FRACBITS != 28
525# error "MAD_F_FRACBITS must be 28 to use OPT_SSO"
526# endif
527 # define ML0(hi, lo, x, y)((lo) = (x) * (y))
528 # define MLA(hi, lo, x, y)((lo) += (x) * (y))
529 # define MLZ(hi, lo) ((void) (hi), (mad_fixed_t) (lo))
530 # define SHIFT(x) ((x) >> 2)
531 # define PRESHIFT(x) ((MAD_F(x) + (1L << 13)) >> 14)
532# else
533 # define ML0(hi, lo, x, y)MAD_F_ML0((hi), (lo), (x), (y))
534 # define MLA(hi, lo, x, y)MAD_F_MLA((hi), (lo), (x), (y))
535 # define MLZ(hi, lo) MAD_F_MLZ((hi), (lo))
536 # define SHIFT(x) (x)
537# if defined(MAD_F_SCALEBITS)
538# undef MAD_F_SCALEBITS
539 # define MAD_F_SCALEBITS(MAD_F_FRACBITS - 12)
540 # define PRESHIFT(x) (MAD_F(x) >> 12)
541# else
542 # define PRESHIFT(x) MAD_F(x)
543# endif
544# endif
545
546static
547mad_fixed_t const D[17][32] = {
548# include "D.dat"
549};
550
551# if defined(ASO_SYNTH)
552void synth_full(struct mad_synth *, struct mad_frame const *,
553 unsigned int, unsigned int);
554# else
555/*
556 * NAME:synth->full()
557 * DESCRIPTION:perform full frequency PCM synthesis
558 */
559static
560void synth_full(struct mad_synth *synth, struct mad_frame const *frame,
561 unsigned int nch, unsigned int ns)
562{
563 unsigned int phase, ch, s, sb, pe, po;
564 mad_fixed_t *pcm1, *pcm2, (*filter)[2][2][16][8];
565 mad_fixed_t const (*sbsample)[36][32];
566 register mad_fixed_t (*fe)[8], (*fx)[8], (*fo)[8];
567 register mad_fixed_t const (*Dptr)[32], *ptr;
568 register mad_fixed64hi_t hi;
569 register mad_fixed64lo_t lo;
570
571 for (ch = 0; ch < nch; ++ch) {
572 sbsample = &frame->sbsample[ch];
573 filter = &synth->filter[ch];
574 phase = synth->phase;
575 pcm1 = synth->pcm.samples[ch];
576
577 for (s = 0; s < ns; ++s) {
578 dct32((*sbsample)[s], phase >> 1,
579 (*filter)[0][phase & 1], (*filter)[1][phase & 1]);
580
581 pe = phase & ~1;
582 po = ((phase - 1) & 0xf) | 1;
583
584 /* calculate 32 samples */
585
586 fe = &(*filter)[0][ phase & 1][0];
587 fx = &(*filter)[0][~phase & 1][0];
588 fo = &(*filter)[1][~phase & 1][0];
589
590 Dptr = &D[0];
591
592 ptr = *Dptr + pe;
593 ML0(hi, lo, (*fe)[0], ptr[ 0]);
594 MLA(hi, lo, (*fe)[1], ptr[14]);
595 MLA(hi, lo, (*fe)[2], ptr[12]);
596 MLA(hi, lo, (*fe)[3], ptr[10]);
597 MLA(hi, lo, (*fe)[4], ptr[ 8]);
598 MLA(hi, lo, (*fe)[5], ptr[ 6]);
599 MLA(hi, lo, (*fe)[6], ptr[ 4]);
600 MLA(hi, lo, (*fe)[7], ptr[ 2]);
601
602 ptr = *Dptr + po;
603 MLA(hi, lo, (*fx)[0], -ptr[ 0]);
604 MLA(hi, lo, (*fx)[1], -ptr[14]);
605 MLA(hi, lo, (*fx)[2], -ptr[12]);
606 MLA(hi, lo, (*fx)[3], -ptr[10]);
607 MLA(hi, lo, (*fx)[4], -ptr[ 8]);
608 MLA(hi, lo, (*fx)[5], -ptr[ 6]);
609 MLA(hi, lo, (*fx)[6], -ptr[ 4]);
610 MLA(hi, lo, (*fx)[7], -ptr[ 2]);
611
612 *pcm1++ = SHIFT(MLZ(hi, lo));
613
614 pcm2 = pcm1 + 30;
615
616 for (sb = 1; sb < 16; ++sb) {
617 ++fe;
618 ++Dptr;
619
620 /* D[32 - sb][i] == -D[sb][31 - i] */
621
622 ptr = *Dptr + pe;
623 ML0(hi, lo, (*fe)[7], ptr[ 2]);
624 MLA(hi, lo, (*fe)[6], ptr[ 4]);
625 MLA(hi, lo, (*fe)[5], ptr[ 6]);
626 MLA(hi, lo, (*fe)[4], ptr[ 8]);
627 MLA(hi, lo, (*fe)[3], ptr[10]);
628 MLA(hi, lo, (*fe)[2], ptr[12]);
629 MLA(hi, lo, (*fe)[1], ptr[14]);
630 MLA(hi, lo, (*fe)[0], ptr[ 0]);
631
632 ptr = *Dptr + po;
633 MLA(hi, lo, (*fo)[0], -ptr[ 0]);
634 MLA(hi, lo, (*fo)[1], -ptr[14]);
635 MLA(hi, lo, (*fo)[2], -ptr[12]);
636 MLA(hi, lo, (*fo)[3], -ptr[10]);
637 MLA(hi, lo, (*fo)[4], -ptr[ 8]);
638 MLA(hi, lo, (*fo)[5], -ptr[ 6]);
639 MLA(hi, lo, (*fo)[6], -ptr[ 4]);
640 MLA(hi, lo, (*fo)[7], -ptr[ 2]);
641
642 *pcm1++ = SHIFT(MLZ(hi, lo));
643
644 ptr = *Dptr - po;
645 ML0(hi, lo, (*fo)[7], ptr[31 - 2]);
646 MLA(hi, lo, (*fo)[6], ptr[31 - 4]);
647 MLA(hi, lo, (*fo)[5], ptr[31 - 6]);
648 MLA(hi, lo, (*fo)[4], ptr[31 - 8]);
649 MLA(hi, lo, (*fo)[3], ptr[31 - 10]);
650 MLA(hi, lo, (*fo)[2], ptr[31 - 12]);
651 MLA(hi, lo, (*fo)[1], ptr[31 - 14]);
652 MLA(hi, lo, (*fo)[0], ptr[31 - 16]);
653
654 ptr = *Dptr - pe;
655 MLA(hi, lo, (*fe)[0], ptr[31 - 16]);
656 MLA(hi, lo, (*fe)[1], ptr[31 - 14]);
657 MLA(hi, lo, (*fe)[2], ptr[31 - 12]);
658 MLA(hi, lo, (*fe)[3], ptr[31 - 10]);
659 MLA(hi, lo, (*fe)[4], ptr[31 - 8]);
660 MLA(hi, lo, (*fe)[5], ptr[31 - 6]);
661 MLA(hi, lo, (*fe)[6], ptr[31 - 4]);
662 MLA(hi, lo, (*fe)[7], ptr[31 - 2]);
663
664 *pcm2-- = SHIFT(MLZ(hi, lo));
665
666 ++fo;
667 }
668
669 ++Dptr;
670
671 ptr = *Dptr + po;
672 ML0(hi, lo, (*fo)[0], ptr[ 0]);
673 MLA(hi, lo, (*fo)[1], ptr[14]);
674 MLA(hi, lo, (*fo)[2], ptr[12]);
675 MLA(hi, lo, (*fo)[3], ptr[10]);
676 MLA(hi, lo, (*fo)[4], ptr[ 8]);
677 MLA(hi, lo, (*fo)[5], ptr[ 6]);
678 MLA(hi, lo, (*fo)[6], ptr[ 4]);
679 MLA(hi, lo, (*fo)[7], ptr[ 2]);
680
681 *pcm1 = SHIFT(-MLZ(hi, lo));
682 pcm1 += 16;
683
684 phase = (phase + 1) % 16;
685 }
686 }
687}
688# endif
689
690/*
691 * NAME:synth->half()
692 * DESCRIPTION:perform half frequency PCM synthesis
693 */
694static
695void synth_half(struct mad_synth *synth, struct mad_frame const *frame,
696 unsigned int nch, unsigned int ns)
697{
698 unsigned int phase, ch, s, sb, pe, po;
699 mad_fixed_t *pcm1, *pcm2, (*filter)[2][2][16][8];
700 mad_fixed_t const (*sbsample)[36][32];
701 register mad_fixed_t (*fe)[8], (*fx)[8], (*fo)[8];
702 register mad_fixed_t const (*Dptr)[32], *ptr;
703 register mad_fixed64hi_t hi;
704 register mad_fixed64lo_t lo;
705
706 for (ch = 0; ch < nch; ++ch) {
707 sbsample = &frame->sbsample[ch];
708 filter = &synth->filter[ch];
709 phase = synth->phase;
710 pcm1 = synth->pcm.samples[ch];
711
712 for (s = 0; s < ns; ++s) {
713 dct32((*sbsample)[s], phase >> 1,
714 (*filter)[0][phase & 1], (*filter)[1][phase & 1]);
715
716 pe = phase & ~1;
717 po = ((phase - 1) & 0xf) | 1;
718
719 /* calculate 16 samples */
720
721 fe = &(*filter)[0][ phase & 1][0];
722 fx = &(*filter)[0][~phase & 1][0];
723 fo = &(*filter)[1][~phase & 1][0];
724
725 Dptr = &D[0];
726
727 ptr = *Dptr + pe;
728 ML0(hi, lo, (*fe)[0], ptr[ 0]);
729 MLA(hi, lo, (*fe)[1], ptr[14]);
730 MLA(hi, lo, (*fe)[2], ptr[12]);
731 MLA(hi, lo, (*fe)[3], ptr[10]);
732 MLA(hi, lo, (*fe)[4], ptr[ 8]);
733 MLA(hi, lo, (*fe)[5], ptr[ 6]);
734 MLA(hi, lo, (*fe)[6], ptr[ 4]);
735 MLA(hi, lo, (*fe)[7], ptr[ 2]);
736
737 ptr = *Dptr + po;
738 MLA(hi, lo, (*fx)[0], -ptr[ 0]);
739 MLA(hi, lo, (*fx)[1], -ptr[14]);
740 MLA(hi, lo, (*fx)[2], -ptr[12]);
741 MLA(hi, lo, (*fx)[3], -ptr[10]);
742 MLA(hi, lo, (*fx)[4], -ptr[ 8]);
743 MLA(hi, lo, (*fx)[5], -ptr[ 6]);
744 MLA(hi, lo, (*fx)[6], -ptr[ 4]);
745 MLA(hi, lo, (*fx)[7], -ptr[ 2]);
746
747 *pcm1++ = SHIFT(MLZ(hi, lo));
748
749 pcm2 = pcm1 + 14;
750
751 for (sb = 1; sb < 16; ++sb) {
752 ++fe;
753 ++Dptr;
754
755 /* D[32 - sb][i] == -D[sb][31 - i] */
756
757 if (!(sb & 1)) {
758 ptr = *Dptr + pe;
759 ML0(hi, lo, (*fe)[7], ptr[ 2]);
760 MLA(hi, lo, (*fe)[6], ptr[ 4]);
761 MLA(hi, lo, (*fe)[5], ptr[ 6]);
762 MLA(hi, lo, (*fe)[4], ptr[ 8]);
763 MLA(hi, lo, (*fe)[3], ptr[10]);
764 MLA(hi, lo, (*fe)[2], ptr[12]);
765 MLA(hi, lo, (*fe)[1], ptr[14]);
766 MLA(hi, lo, (*fe)[0], ptr[ 0]);
767
768 ptr = *Dptr + po;
769 MLA(hi, lo, (*fo)[0], -ptr[ 0]);
770 MLA(hi, lo, (*fo)[1], -ptr[14]);
771 MLA(hi, lo, (*fo)[2], -ptr[12]);
772 MLA(hi, lo, (*fo)[3], -ptr[10]);
773 MLA(hi, lo, (*fo)[4], -ptr[ 8]);
774 MLA(hi, lo, (*fo)[5], -ptr[ 6]);
775 MLA(hi, lo, (*fo)[6], -ptr[ 4]);
776 MLA(hi, lo, (*fo)[7], -ptr[ 2]);
777
778 *pcm1++ = SHIFT(MLZ(hi, lo));
779
780 ptr = *Dptr - po;
781 ML0(hi, lo, (*fo)[7], ptr[31 - 2]);
782 MLA(hi, lo, (*fo)[6], ptr[31 - 4]);
783 MLA(hi, lo, (*fo)[5], ptr[31 - 6]);
784 MLA(hi, lo, (*fo)[4], ptr[31 - 8]);
785 MLA(hi, lo, (*fo)[3], ptr[31 - 10]);
786 MLA(hi, lo, (*fo)[2], ptr[31 - 12]);
787 MLA(hi, lo, (*fo)[1], ptr[31 - 14]);
788 MLA(hi, lo, (*fo)[0], ptr[31 - 16]);
789
790 ptr = *Dptr - pe;
791 MLA(hi, lo, (*fe)[0], ptr[31 - 16]);
792 MLA(hi, lo, (*fe)[1], ptr[31 - 14]);
793 MLA(hi, lo, (*fe)[2], ptr[31 - 12]);
794 MLA(hi, lo, (*fe)[3], ptr[31 - 10]);
795 MLA(hi, lo, (*fe)[4], ptr[31 - 8]);
796 MLA(hi, lo, (*fe)[5], ptr[31 - 6]);
797 MLA(hi, lo, (*fe)[6], ptr[31 - 4]);
798 MLA(hi, lo, (*fe)[7], ptr[31 - 2]);
799
800 *pcm2-- = SHIFT(MLZ(hi, lo));
801 }
802
803 ++fo;
804 }
805
806 ++Dptr;
807
808 ptr = *Dptr + po;
809 ML0(hi, lo, (*fo)[0], ptr[ 0]);
810 MLA(hi, lo, (*fo)[1], ptr[14]);
811 MLA(hi, lo, (*fo)[2], ptr[12]);
812 MLA(hi, lo, (*fo)[3], ptr[10]);
813 MLA(hi, lo, (*fo)[4], ptr[ 8]);
814 MLA(hi, lo, (*fo)[5], ptr[ 6]);
815 MLA(hi, lo, (*fo)[6], ptr[ 4]);
816 MLA(hi, lo, (*fo)[7], ptr[ 2]);
817
818 *pcm1 = SHIFT(-MLZ(hi, lo));
819 pcm1 += 8;
820
821 phase = (phase + 1) % 16;
822 }
823 }
824}
825
826/*
827 * NAME:synth->frame()
828 * DESCRIPTION:perform PCM synthesis of frame subband samples
829 */
830void mad_synth_frame(struct mad_synth *synth, struct mad_frame const *frame)
831{
832 unsigned int nch, ns;
833 void (*synth_frame)(struct mad_synth *, struct mad_frame const *,
834 unsigned int, unsigned int);
835
836 nch = MAD_NCHANNELS(&frame->header);
837 ns = MAD_NSBSAMPLES(&frame->header);
838
839 synth->pcm.samplerate = frame->header.samplerate;
840 synth->pcm.channels = nch;
841 synth->pcm.length = 32 * ns;
842
843 synth_frame = synth_full;
844
845 if (frame->options & MAD_OPTION_HALFSAMPLERATE) {
846 synth->pcm.samplerate /= 2;
847 synth->pcm.length /= 2;
848
849 synth_frame = synth_half;
850 }
851
852 synth_frame(synth, frame, nch, ns);
853
854 synth->phase = (synth->phase + ns) % 16;
855}
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 @@
1/*
2 * mad - MPEG audio decoder
3 * Copyright (C) 2000-2001 Robert Leslie
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * $Id$
20 */
21
22# ifndef LIBMAD_SYNTH_H
23# define LIBMAD_SYNTH_H
24
25# include "fixed.h"
26# include "frame.h"
27
28struct mad_synth {
29 mad_fixed_t filter[2][2][2][16][8];/* polyphase filterbank outputs */
30 /* [ch][eo][peo][s][v] */
31
32 unsigned int phase; /* current processing phase */
33
34 struct mad_pcm {
35 unsigned int samplerate; /* sampling frequency (Hz) */
36 unsigned short channels; /* number of channels */
37 unsigned short length; /* number of samples per channel */
38 mad_fixed_t samples[2][1152];/* PCM output samples */
39 } pcm;
40};
41
42void mad_synth_init(struct mad_synth *);
43
44# define mad_synth_finish(synth) /* nothing */
45
46void mad_synth_mute(struct mad_synth *);
47
48void mad_synth_frame(struct mad_synth *, struct mad_frame const *);
49
50# 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 @@
1/*
2 * mad - MPEG audio decoder
3 * Copyright (C) 2000-2001 Robert Leslie
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * $Id$
20 */
21
22# ifdef HAVE_CONFIG_H
23# include "libmad_config.h"
24# endif
25
26# include "libmad_global.h"
27
28# include <stdio.h>
29# include <assert.h>
30
31# include "timer.h"
32
33mad_timer_t const mad_timer_zero = { 0, 0 };
34
35/*
36 * NAME:timer->compare()
37 * DESCRIPTION:indicate relative order of two timers
38 */
39int mad_timer_compare(mad_timer_t timer1, mad_timer_t timer2)
40{
41 signed long diff;
42
43 diff = timer1.seconds - timer2.seconds;
44 if (diff < 0)
45 return -1;
46 else if (diff > 0)
47 return +1;
48
49 diff = timer1.fraction - timer2.fraction;
50 if (diff < 0)
51 return -1;
52 else if (diff > 0)
53 return +1;
54
55 return 0;
56}
57
58/*
59 * NAME:timer->negate()
60 * DESCRIPTION:invert the sign of a timer
61 */
62void mad_timer_negate(mad_timer_t *timer)
63{
64 timer->seconds = -timer->seconds;
65
66 if (timer->fraction) {
67 timer->seconds -= 1;
68 timer->fraction = MAD_TIMER_RESOLUTION - timer->fraction;
69 }
70}
71
72/*
73 * NAME:timer->abs()
74 * DESCRIPTION:return the absolute value of a timer
75 */
76mad_timer_t mad_timer_abs(mad_timer_t timer)
77{
78 if (mad_timer_sign(timer) < 0)
79 mad_timer_negate(&timer);
80
81 return timer;
82}
83
84/*
85 * NAME:reduce_timer()
86 * DESCRIPTION:carry timer fraction into seconds
87 */
88static
89void reduce_timer(mad_timer_t *timer)
90{
91 timer->seconds += timer->fraction / MAD_TIMER_RESOLUTION;
92 timer->fraction %= MAD_TIMER_RESOLUTION;
93}
94
95/*
96 * NAME:gcd()
97 * DESCRIPTION:compute greatest common denominator
98 */
99static
100unsigned long gcd(unsigned long num1, unsigned long num2)
101{
102 unsigned long tmp;
103
104 while (num2) {
105 tmp = num2;
106 num2 = num1 % num2;
107 num1 = tmp;
108 }
109
110 return num1;
111}
112
113/*
114 * NAME:reduce_rational()
115 * DESCRIPTION:convert rational expression to lowest terms
116 */
117static
118void reduce_rational(unsigned long *numer, unsigned long *denom)
119{
120 unsigned long factor;
121
122 factor = gcd(*numer, *denom);
123
124 assert(factor != 0);
125
126 *numer /= factor;
127 *denom /= factor;
128}
129
130/*
131 * NAME:scale_rational()
132 * DESCRIPTION:solve numer/denom == ?/scale avoiding overflowing
133 */
134static
135unsigned long scale_rational(unsigned long numer, unsigned long denom,
136 unsigned long scale)
137{
138 reduce_rational(&numer, &denom);
139 reduce_rational(&scale, &denom);
140
141 assert(denom != 0);
142
143 if (denom < scale)
144 return numer * (scale / denom) + numer * (scale % denom) / denom;
145 if (denom < numer)
146 return scale * (numer / denom) + scale * (numer % denom) / denom;
147
148 return numer * scale / denom;
149}
150
151/*
152 * NAME:timer->set()
153 * DESCRIPTION:set timer to specific value
154 */
155void mad_timer_set(mad_timer_t *timer, unsigned long seconds,
156 unsigned long fraction, unsigned long fracparts)
157{
158 timer->seconds = seconds;
159
160 if (fraction == 0)
161 fracparts = 0;
162 else if (fracparts == 0) {
163 fracparts = fraction;
164 fraction = 1;
165 }
166
167 switch (fracparts) {
168 case 0:
169 timer->fraction = 0;
170 break;
171
172 case MAD_TIMER_RESOLUTION:
173 timer->fraction = fraction;
174 break;
175
176 case 8000:
177 timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 8000);
178 break;
179
180 case 11025:
181 timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 11025);
182 break;
183
184 case 12000:
185 timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 12000);
186 break;
187
188 case 16000:
189 timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 16000);
190 break;
191
192 case 22050:
193 timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 22050);
194 break;
195
196 case 24000:
197 timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 24000);
198 break;
199
200 case 32000:
201 timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 32000);
202 break;
203
204 case 44100:
205 timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 44100);
206 break;
207
208 case 48000:
209 timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 48000);
210 break;
211
212 default:
213 timer->fraction =
214 scale_rational(fraction, fracparts, MAD_TIMER_RESOLUTION);
215 break;
216 }
217
218 if (timer->fraction >= MAD_TIMER_RESOLUTION)
219 reduce_timer(timer);
220}
221
222/*
223 * NAME:timer->add()
224 * DESCRIPTION:add one timer to another
225 */
226void mad_timer_add(mad_timer_t *timer, mad_timer_t incr)
227{
228 timer->seconds += incr.seconds;
229 timer->fraction += incr.fraction;
230
231 if (timer->fraction >= MAD_TIMER_RESOLUTION)
232 reduce_timer(timer);
233}
234
235/*
236 * NAME:timer->multiply()
237 * DESCRIPTION:multiply a timer by a scalar value
238 */
239void mad_timer_multiply(mad_timer_t *timer, signed long scalar)
240{
241 mad_timer_t addend;
242 unsigned long factor;
243
244 factor = scalar;
245 if (scalar < 0) {
246 mad_timer_negate(timer);
247 factor = -scalar;
248 }
249
250 addend = *timer;
251 *timer = mad_timer_zero;
252
253 while (factor) {
254 if (factor & 1)
255 mad_timer_add(timer, addend);
256
257 mad_timer_add(&addend, addend);
258 factor >>= 1;
259 }
260}
261
262/*
263 * NAME:timer->count()
264 * DESCRIPTION:return timer value in selected units
265 */
266signed long mad_timer_count(mad_timer_t timer, enum mad_units units)
267{
268 switch (units) {
269 case MAD_UNITS_HOURS:
270 return timer.seconds / 60 / 60;
271
272 case MAD_UNITS_MINUTES:
273 return timer.seconds / 60;
274
275 case MAD_UNITS_SECONDS:
276 return timer.seconds;
277
278 case MAD_UNITS_DECISECONDS:
279 case MAD_UNITS_CENTISECONDS:
280 case MAD_UNITS_MILLISECONDS:
281
282 case MAD_UNITS_8000_HZ:
283 case MAD_UNITS_11025_HZ:
284 case MAD_UNITS_12000_HZ:
285 case MAD_UNITS_16000_HZ:
286 case MAD_UNITS_22050_HZ:
287 case MAD_UNITS_24000_HZ:
288 case MAD_UNITS_32000_HZ:
289 case MAD_UNITS_44100_HZ:
290 case MAD_UNITS_48000_HZ:
291
292 case MAD_UNITS_24_FPS:
293 case MAD_UNITS_25_FPS:
294 case MAD_UNITS_30_FPS:
295 case MAD_UNITS_48_FPS:
296 case MAD_UNITS_50_FPS:
297 case MAD_UNITS_60_FPS:
298 case MAD_UNITS_75_FPS:
299 return timer.seconds * (signed long) units +
300 (signed long) scale_rational(timer.fraction, MAD_TIMER_RESOLUTION,
301 units);
302
303 case MAD_UNITS_23_976_FPS:
304 case MAD_UNITS_24_975_FPS:
305 case MAD_UNITS_29_97_FPS:
306 case MAD_UNITS_47_952_FPS:
307 case MAD_UNITS_49_95_FPS:
308 case MAD_UNITS_59_94_FPS:
309 return (mad_timer_count(timer, -units) + 1) * 1000 / 1001;
310 }
311
312 /* unsupported units */
313 return 0;
314}
315
316/*
317 * NAME:timer->fraction()
318 * DESCRIPTION:return fractional part of timer in arbitrary terms
319 */
320unsigned long mad_timer_fraction(mad_timer_t timer, unsigned long fracparts)
321{
322 timer = mad_timer_abs(timer);
323
324 switch (fracparts) {
325 case 0:
326 return MAD_TIMER_RESOLUTION / timer.fraction;
327
328 case MAD_TIMER_RESOLUTION:
329 return timer.fraction;
330
331 default:
332 return scale_rational(timer.fraction, MAD_TIMER_RESOLUTION, fracparts);
333 }
334}
335
336/*
337 * NAME:timer->string()
338 * DESCRIPTION:write a string representation of a timer using a template
339 */
340void mad_timer_string(mad_timer_t timer,
341 char *dest, char const *format, enum mad_units units,
342 enum mad_units fracunits, unsigned long subparts)
343{
344 unsigned long hours, minutes, seconds, sub;
345 unsigned int frac;
346
347 timer = mad_timer_abs(timer);
348
349 seconds = timer.seconds;
350 frac = sub = 0;
351
352 switch (fracunits) {
353 case MAD_UNITS_HOURS:
354 case MAD_UNITS_MINUTES:
355 case MAD_UNITS_SECONDS:
356 break;
357
358 case MAD_UNITS_DECISECONDS:
359 case MAD_UNITS_CENTISECONDS:
360 case MAD_UNITS_MILLISECONDS:
361
362 case MAD_UNITS_8000_HZ:
363 case MAD_UNITS_11025_HZ:
364 case MAD_UNITS_12000_HZ:
365 case MAD_UNITS_16000_HZ:
366 case MAD_UNITS_22050_HZ:
367 case MAD_UNITS_24000_HZ:
368 case MAD_UNITS_32000_HZ:
369 case MAD_UNITS_44100_HZ:
370 case MAD_UNITS_48000_HZ:
371
372 case MAD_UNITS_24_FPS:
373 case MAD_UNITS_25_FPS:
374 case MAD_UNITS_30_FPS:
375 case MAD_UNITS_48_FPS:
376 case MAD_UNITS_50_FPS:
377 case MAD_UNITS_60_FPS:
378 case MAD_UNITS_75_FPS:
379 {
380 unsigned long fracparts;
381
382 fracparts = MAD_TIMER_RESOLUTION / fracunits;
383
384 frac = timer.fraction / fracparts;
385 sub = scale_rational(timer.fraction % fracparts, fracparts, subparts);
386 }
387 break;
388
389 case MAD_UNITS_23_976_FPS:
390 case MAD_UNITS_24_975_FPS:
391 case MAD_UNITS_29_97_FPS:
392 case MAD_UNITS_47_952_FPS:
393 case MAD_UNITS_49_95_FPS:
394 case MAD_UNITS_59_94_FPS:
395 /* drop-frame encoding */
396 /* N.B. this is only well-defined for MAD_UNITS_29_97_FPS */
397 {
398 unsigned long frame, cycle, d, m;
399
400 frame = mad_timer_count(timer, fracunits);
401
402 cycle = -fracunits * 60 * 10 - (10 - 1) * 2;
403
404 d = frame / cycle;
405 m = frame % cycle;
406 frame += (10 - 1) * 2 * d;
407 if (m > 2)
408 frame += 2 * ((m - 2) / (cycle / 10));
409
410 frac = frame % -fracunits;
411 seconds = frame / -fracunits;
412 }
413 break;
414 }
415
416 switch (units) {
417 case MAD_UNITS_HOURS:
418 minutes = seconds / 60;
419 hours = minutes / 60;
420
421 sprintf(dest, format,
422 hours,
423 (unsigned int) (minutes % 60),
424 (unsigned int) (seconds % 60),
425 frac, sub);
426 break;
427
428 case MAD_UNITS_MINUTES:
429 minutes = seconds / 60;
430
431 sprintf(dest, format,
432 minutes,
433 (unsigned int) (seconds % 60),
434 frac, sub);
435 break;
436
437 case MAD_UNITS_SECONDS:
438 sprintf(dest, format,
439 seconds,
440 frac, sub);
441 break;
442
443 case MAD_UNITS_23_976_FPS:
444 case MAD_UNITS_24_975_FPS:
445 case MAD_UNITS_29_97_FPS:
446 case MAD_UNITS_47_952_FPS:
447 case MAD_UNITS_49_95_FPS:
448 case MAD_UNITS_59_94_FPS:
449 if (fracunits < 0) {
450 /* not yet implemented */
451 sub = 0;
452 }
453
454 /* fall through */
455
456 case MAD_UNITS_DECISECONDS:
457 case MAD_UNITS_CENTISECONDS:
458 case MAD_UNITS_MILLISECONDS:
459
460 case MAD_UNITS_8000_HZ:
461 case MAD_UNITS_11025_HZ:
462 case MAD_UNITS_12000_HZ:
463 case MAD_UNITS_16000_HZ:
464 case MAD_UNITS_22050_HZ:
465 case MAD_UNITS_24000_HZ:
466 case MAD_UNITS_32000_HZ:
467 case MAD_UNITS_44100_HZ:
468 case MAD_UNITS_48000_HZ:
469
470 case MAD_UNITS_24_FPS:
471 case MAD_UNITS_25_FPS:
472 case MAD_UNITS_30_FPS:
473 case MAD_UNITS_48_FPS:
474 case MAD_UNITS_50_FPS:
475 case MAD_UNITS_60_FPS:
476 case MAD_UNITS_75_FPS:
477 sprintf(dest, format, mad_timer_count(timer, units), sub);
478 break;
479 }
480}
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 @@
1/*
2 * mad - MPEG audio decoder
3 * Copyright (C) 2000-2001 Robert Leslie
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * $Id$
20 */
21
22# ifndef LIBMAD_TIMER_H
23# define LIBMAD_TIMER_H
24
25typedef struct {
26 signed long seconds; /* whole seconds */
27 unsigned long fraction;/* 1/MAD_TIMER_RESOLUTION seconds */
28} mad_timer_t;
29
30extern mad_timer_t const mad_timer_zero;
31
32 # define MAD_TIMER_RESOLUTION352800000UL
33
34enum mad_units {
35 MAD_UNITS_HOURS = -2,
36 MAD_UNITS_MINUTES = -1,
37 MAD_UNITS_SECONDS = 0,
38
39 /* metric units */
40
41 MAD_UNITS_DECISECONDS = 10,
42 MAD_UNITS_CENTISECONDS = 100,
43 MAD_UNITS_MILLISECONDS = 1000,
44
45 /* audio sample units */
46
47 MAD_UNITS_8000_HZ = 8000,
48 MAD_UNITS_11025_HZ = 11025,
49 MAD_UNITS_12000_HZ = 12000,
50
51 MAD_UNITS_16000_HZ = 16000,
52 MAD_UNITS_22050_HZ = 22050,
53 MAD_UNITS_24000_HZ = 24000,
54
55 MAD_UNITS_32000_HZ = 32000,
56 MAD_UNITS_44100_HZ = 44100,
57 MAD_UNITS_48000_HZ = 48000,
58
59 /* video frame/field units */
60
61 MAD_UNITS_24_FPS = 24,
62 MAD_UNITS_25_FPS = 25,
63 MAD_UNITS_30_FPS = 30,
64 MAD_UNITS_48_FPS = 48,
65 MAD_UNITS_50_FPS = 50,
66 MAD_UNITS_60_FPS = 60,
67
68 /* CD audio frames */
69
70 MAD_UNITS_75_FPS = 75,
71
72 /* video drop-frame units */
73
74 MAD_UNITS_23_976_FPS = -24,
75 MAD_UNITS_24_975_FPS = -25,
76 MAD_UNITS_29_97_FPS = -30,
77 MAD_UNITS_47_952_FPS = -48,
78 MAD_UNITS_49_95_FPS = -50,
79 MAD_UNITS_59_94_FPS = -60
80};
81
82 # define mad_timer_reset(timer)(*(timer) = mad_timer_zero)
83
84int mad_timer_compare(mad_timer_t, mad_timer_t);
85
86 # define mad_timer_sign(timer)mad_timer_compare((timer), mad_timer_zero)
87
88void mad_timer_negate(mad_timer_t *);
89mad_timer_t mad_timer_abs(mad_timer_t);
90
91void mad_timer_set(mad_timer_t *, unsigned long, unsigned long, unsigned long);
92void mad_timer_add(mad_timer_t *, mad_timer_t);
93void mad_timer_multiply(mad_timer_t *, signed long);
94
95signed long mad_timer_count(mad_timer_t, enum mad_units);
96unsigned long mad_timer_fraction(mad_timer_t, unsigned long);
97void mad_timer_string(mad_timer_t, char *, char const *,
98 enum mad_units, enum mad_units, unsigned long);
99
100# 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 @@
1/*
2 * mad - MPEG audio decoder
3 * Copyright (C) 2000-2001 Robert Leslie
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * $Id$
20 */
21
22# ifdef HAVE_CONFIG_H
23# include "libmad_config.h"
24# endif
25
26# include "libmad_global.h"
27
28# include "libmad_version.h"
29
30char const mad_version[] = "MPEG Audio Decoder version " MAD_VERSION;
31char const mad_copyright[] = "Copyright (C) " MAD_PUBLISHYEAR " " MAD_AUTHOR;
32char const mad_author[] = MAD_AUTHOR " <" MAD_EMAIL ">";
33
34char const mad_build[] =
35# if defined(FPM_64BIT)
36 "FPM_64BIT "
37# elif defined(FPM_INTEL)
38 "FPM_INTEL "
39# elif defined(FPM_ARM)
40 "FPM_ARM "
41# elif defined(FPM_MIPS)
42 "FPM_MIPS "
43# elif defined(FPM_SPARC)
44 "FPM_SPARC "
45# elif defined(FPM_PPC)
46 "FPM_PPC "
47# elif defined(FPM_DEFAULT)
48 "FPM_DEFAULT "
49# endif
50
51# if defined(ASO_IMDCT)
52 "ASO_IMDCT "
53# endif
54# if defined(ASO_INTERLEAVE1)
55 "ASO_INTERLEAVE1 "
56# endif
57# if defined(ASO_INTERLEAVE2)
58 "ASO_INTERLEAVE2 "
59# endif
60# if defined(ASO_ZEROCHECK)
61 "ASO_ZEROCHECK "
62# endif
63
64# if defined(OPT_SPEED)
65 "OPT_SPEED "
66# elif defined(OPT_ACCURACY)
67 "OPT_ACCURACY "
68# endif
69
70# if defined(OPT_SSO)
71 "OPT_SSO "
72# endif
73
74# if defined(OPT_DCTO) /* never defined here */
75 "OPT_DCTO "
76# endif
77
78# if defined(OPT_STRICT)
79 "OPT_STRICT "
80# endif
81
82# if defined(EXPERIMENTAL)
83 "EXPERIMENTAL "
84# endif
85
86# if defined(DEBUG)
87 "DEBUG "
88# elif defined(NDEBUG)
89 "NDEBUG "
90# endif
91;
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 @@
1global_config
2dump
3mpeg3toc
4mpeg3cat
5Makefile
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 @@
1 GNU GENERAL PUBLIC LICENSE
2 Version 2, June 1991
3
4 Copyright (C) 1989, 1991 Free Software Foundation, Inc.
5 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
6 Everyone is permitted to copy and distribute verbatim copies
7 of this license document, but changing it is not allowed.
8
9 Preamble
10
11 The licenses for most software are designed to take away your
12freedom to share and change it. By contrast, the GNU General Public
13License is intended to guarantee your freedom to share and change free
14software--to make sure the software is free for all its users. This
15General Public License applies to most of the Free Software
16Foundation's software and to any other program whose authors commit to
17using it. (Some other Free Software Foundation software is covered by
18the GNU Library General Public License instead.) You can apply it to
19your programs, too.
20
21 When we speak of free software, we are referring to freedom, not
22price. Our General Public Licenses are designed to make sure that you
23have the freedom to distribute copies of free software (and charge for
24this service if you wish), that you receive source code or can get it
25if you want it, that you can change the software or use pieces of it
26in new free programs; and that you know you can do these things.
27
28 To protect your rights, we need to make restrictions that forbid
29anyone to deny you these rights or to ask you to surrender the rights.
30These restrictions translate to certain responsibilities for you if you
31distribute copies of the software, or if you modify it.
32
33 For example, if you distribute copies of such a program, whether
34gratis or for a fee, you must give the recipients all the rights that
35you have. You must make sure that they, too, receive or can get the
36source code. And you must show them these terms so they know their
37rights.
38
39 We protect your rights with two steps: (1) copyright the software, and
40(2) offer you this license which gives you legal permission to copy,
41distribute and/or modify the software.
42
43 Also, for each author's protection and ours, we want to make certain
44that everyone understands that there is no warranty for this free
45software. If the software is modified by someone else and passed on, we
46want its recipients to know that what they have is not the original, so
47that any problems introduced by others will not reflect on the original
48authors' reputations.
49
50 Finally, any free program is threatened constantly by software
51patents. We wish to avoid the danger that redistributors of a free
52program will individually obtain patent licenses, in effect making the
53program proprietary. To prevent this, we have made it clear that any
54patent must be licensed for everyone's free use or not licensed at all.
55
56 The precise terms and conditions for copying, distribution and
57modification follow.
58
59 GNU GENERAL PUBLIC LICENSE
60 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61
62 0. This License applies to any program or other work which contains
63a notice placed by the copyright holder saying it may be distributed
64under the terms of this General Public License. The "Program", below,
65refers to any such program or work, and a "work based on the Program"
66means either the Program or any derivative work under copyright law:
67that is to say, a work containing the Program or a portion of it,
68either verbatim or with modifications and/or translated into another
69language. (Hereinafter, translation is included without limitation in
70the term "modification".) Each licensee is addressed as "you".
71
72Activities other than copying, distribution and modification are not
73covered by this License; they are outside its scope. The act of
74running the Program is not restricted, and the output from the Program
75is covered only if its contents constitute a work based on the
76Program (independent of having been made by running the Program).
77Whether that is true depends on what the Program does.
78
79 1. You may copy and distribute verbatim copies of the Program's
80source code as you receive it, in any medium, provided that you
81conspicuously and appropriately publish on each copy an appropriate
82copyright notice and disclaimer of warranty; keep intact all the
83notices that refer to this License and to the absence of any warranty;
84and give any other recipients of the Program a copy of this License
85along with the Program.
86
87You may charge a fee for the physical act of transferring a copy, and
88you may at your option offer warranty protection in exchange for a fee.
89
90 2. You may modify your copy or copies of the Program or any portion
91of it, thus forming a work based on the Program, and copy and
92distribute such modifications or work under the terms of Section 1
93above, provided that you also meet all of these conditions:
94
95 a) You must cause the modified files to carry prominent notices
96 stating that you changed the files and the date of any change.
97
98 b) You must cause any work that you distribute or publish, that in
99 whole or in part contains or is derived from the Program or any
100 part thereof, to be licensed as a whole at no charge to all third
101 parties under the terms of this License.
102
103 c) If the modified program normally reads commands interactively
104 when run, you must cause it, when started running for such
105 interactive use in the most ordinary way, to print or display an
106 announcement including an appropriate copyright notice and a
107 notice that there is no warranty (or else, saying that you provide
108 a warranty) and that users may redistribute the program under
109 these conditions, and telling the user how to view a copy of this
110 License. (Exception: if the Program itself is interactive but
111 does not normally print such an announcement, your work based on
112 the Program is not required to print an announcement.)
113
114These requirements apply to the modified work as a whole. If
115identifiable sections of that work are not derived from the Program,
116and can be reasonably considered independent and separate works in
117themselves, then this License, and its terms, do not apply to those
118sections when you distribute them as separate works. But when you
119distribute the same sections as part of a whole which is a work based
120on the Program, the distribution of the whole must be on the terms of
121this License, whose permissions for other licensees extend to the
122entire whole, and thus to each and every part regardless of who wrote it.
123
124Thus, it is not the intent of this section to claim rights or contest
125your rights to work written entirely by you; rather, the intent is to
126exercise the right to control the distribution of derivative or
127collective works based on the Program.
128
129In addition, mere aggregation of another work not based on the Program
130with the Program (or with a work based on the Program) on a volume of
131a storage or distribution medium does not bring the other work under
132the scope of this License.
133
134 3. You may copy and distribute the Program (or a work based on it,
135under Section 2) in object code or executable form under the terms of
136Sections 1 and 2 above provided that you also do one of the following:
137
138 a) Accompany it with the complete corresponding machine-readable
139 source code, which must be distributed under the terms of Sections
140 1 and 2 above on a medium customarily used for software interchange; or,
141
142 b) Accompany it with a written offer, valid for at least three
143 years, to give any third party, for a charge no more than your
144 cost of physically performing source distribution, a complete
145 machine-readable copy of the corresponding source code, to be
146 distributed under the terms of Sections 1 and 2 above on a medium
147 customarily used for software interchange; or,
148
149 c) Accompany it with the information you received as to the offer
150 to distribute corresponding source code. (This alternative is
151 allowed only for noncommercial distribution and only if you
152 received the program in object code or executable form with such
153 an offer, in accord with Subsection b above.)
154
155The source code for a work means the preferred form of the work for
156making modifications to it. For an executable work, complete source
157code means all the source code for all modules it contains, plus any
158associated interface definition files, plus the scripts used to
159control compilation and installation of the executable. However, as a
160special exception, the source code distributed need not include
161anything that is normally distributed (in either source or binary
162form) with the major components (compiler, kernel, and so on) of the
163operating system on which the executable runs, unless that component
164itself accompanies the executable.
165
166If distribution of executable or object code is made by offering
167access to copy from a designated place, then offering equivalent
168access to copy the source code from the same place counts as
169distribution of the source code, even though third parties are not
170compelled to copy the source along with the object code.
171
172 4. You may not copy, modify, sublicense, or distribute the Program
173except as expressly provided under this License. Any attempt
174otherwise to copy, modify, sublicense or distribute the Program is
175void, and will automatically terminate your rights under this License.
176However, parties who have received copies, or rights, from you under
177this License will not have their licenses terminated so long as such
178parties remain in full compliance.
179
180 5. You are not required to accept this License, since you have not
181signed it. However, nothing else grants you permission to modify or
182distribute the Program or its derivative works. These actions are
183prohibited by law if you do not accept this License. Therefore, by
184modifying or distributing the Program (or any work based on the
185Program), you indicate your acceptance of this License to do so, and
186all its terms and conditions for copying, distributing or modifying
187the Program or works based on it.
188
189 6. Each time you redistribute the Program (or any work based on the
190Program), the recipient automatically receives a license from the
191original licensor to copy, distribute or modify the Program subject to
192these terms and conditions. You may not impose any further
193restrictions on the recipients' exercise of the rights granted herein.
194You are not responsible for enforcing compliance by third parties to
195this License.
196
197 7. If, as a consequence of a court judgment or allegation of patent
198infringement or for any other reason (not limited to patent issues),
199conditions are imposed on you (whether by court order, agreement or
200otherwise) that contradict the conditions of this License, they do not
201excuse you from the conditions of this License. If you cannot
202distribute so as to satisfy simultaneously your obligations under this
203License and any other pertinent obligations, then as a consequence you
204may not distribute the Program at all. For example, if a patent
205license would not permit royalty-free redistribution of the Program by
206all those who receive copies directly or indirectly through you, then
207the only way you could satisfy both it and this License would be to
208refrain entirely from distribution of the Program.
209
210If any portion of this section is held invalid or unenforceable under
211any particular circumstance, the balance of the section is intended to
212apply and the section as a whole is intended to apply in other
213circumstances.
214
215It is not the purpose of this section to induce you to infringe any
216patents or other property right claims or to contest validity of any
217such claims; this section has the sole purpose of protecting the
218integrity of the free software distribution system, which is
219implemented by public license practices. Many people have made
220generous contributions to the wide range of software distributed
221through that system in reliance on consistent application of that
222system; it is up to the author/donor to decide if he or she is willing
223to distribute software through any other system and a licensee cannot
224impose that choice.
225
226This section is intended to make thoroughly clear what is believed to
227be a consequence of the rest of this License.
228
229 8. If the distribution and/or use of the Program is restricted in
230certain countries either by patents or by copyrighted interfaces, the
231original copyright holder who places the Program under this License
232may add an explicit geographical distribution limitation excluding
233those countries, so that distribution is permitted only in or among
234countries not thus excluded. In such case, this License incorporates
235the limitation as if written in the body of this License.
236
237 9. The Free Software Foundation may publish revised and/or new versions
238of the General Public License from time to time. Such new versions will
239be similar in spirit to the present version, but may differ in detail to
240address new problems or concerns.
241
242Each version is given a distinguishing version number. If the Program
243specifies a version number of this License which applies to it and "any
244later version", you have the option of following the terms and conditions
245either of that version or of any later version published by the Free
246Software Foundation. If the Program does not specify a version number of
247this License, you may choose any version ever published by the Free Software
248Foundation.
249
250 10. If you wish to incorporate parts of the Program into other free
251programs whose distribution conditions are different, write to the author
252to ask for permission. For software which is copyrighted by the Free
253Software Foundation, write to the Free Software Foundation; we sometimes
254make exceptions for this. Our decision will be guided by the two goals
255of preserving the free status of all derivatives of our free software and
256of promoting the sharing and reuse of software generally.
257
258 NO WARRANTY
259
260 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268REPAIR OR CORRECTION.
269
270 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278POSSIBILITY OF SUCH DAMAGES.
279
280 END OF TERMS AND CONDITIONS
281
282 How to Apply These Terms to Your New Programs
283
284 If you develop a new program, and you want it to be of the greatest
285possible use to the public, the best way to achieve this is to make it
286free software which everyone can redistribute and change under these terms.
287
288 To do so, attach the following notices to the program. It is safest
289to attach them to the start of each source file to most effectively
290convey the exclusion of warranty; and each file should have at least
291the "copyright" line and a pointer to where the full notice is found.
292
293 <one line to give the program's name and a brief idea of what it does.>
294 Copyright (C) 19yy <name of author>
295
296 This program is free software; you can redistribute it and/or modify
297 it under the terms of the GNU General Public License as published by
298 the Free Software Foundation; either version 2 of the License, or
299 (at your option) any later version.
300
301 This program is distributed in the hope that it will be useful,
302 but WITHOUT ANY WARRANTY; without even the implied warranty of
303 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304 GNU General Public License for more details.
305
306 You should have received a copy of the GNU General Public License
307 along with this program; if not, write to the Free Software
308 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
309
310
311Also add information on how to contact you by electronic and paper mail.
312
313If the program is interactive, make it output a short notice like this
314when it starts in an interactive mode:
315
316 Gnomovision version 69, Copyright (C) 19yy name of author
317 Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
318 This is free software, and you are welcome to redistribute it
319 under certain conditions; type `show c' for details.
320
321The hypothetical commands `show w' and `show c' should show the appropriate
322parts of the General Public License. Of course, the commands you use may
323be called something other than `show w' and `show c'; they could even be
324mouse-clicks or menu items--whatever suits your program.
325
326You should also get your employer (if you work as a programmer) or your
327school, if any, to sign a "copyright disclaimer" for the program, if
328necessary. Here is a sample; alter the names:
329
330 Yoyodyne, Inc., hereby disclaims all copyright interest in the program
331 `Gnomovision' (which makes passes at compilers) written by James Hacker.
332
333 <signature of Ty Coon>, 1 April 1989
334 Ty Coon, President of Vice
335
336This General Public License does not permit incorporating your program into
337proprietary programs. If your program is a subroutine library, you may
338consider it more useful to permit linking proprietary applications with the
339library. If this is what you want to do, use the GNU Library General
340Public 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 @@
1#############################################################################
2
3####### Compiler, tools and options
4
5 CXX =$(SYSCONF_CXX) $(QT_CXX_MT)
6 CXXFLAGS=$(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS) $(SYSCONF_CXXFLAGS_LIB) -DQCONFIG=\"qpe\"
7 CC =$(SYSCONF_CC) $(QT_C_MT)
8 CFLAGS =$(SYSCONF_CFLAGS) $(SYSCONF_CFLAGS_LIB) -DQCONFIG=\"qpe\"
9 INCPATH =-I$(QPEDIR)/include -I..
10 LFLAGS =$(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
11 LIBS =$(SUBLIBS) -lqpe -lpthread -lm $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS_QTAPP)
12 MOC =$(SYSCONF_MOC)
13 UIC =$(SYSCONF_UIC)
14
15####### Target
16
17DESTDIR = ../../plugins/codecs/
18VER_MAJ = 1
19VER_MIN = 0
20VER_PATCH = 0
21 TARGET= mpeg3plugin
22TARGET1 = lib$(TARGET).so.$(VER_MAJ)
23
24####### Files
25
26 HEADERS =libmpeg3plugin.h \
27 libmpeg3pluginimpl.h
28 SOURCES =libmpeg3plugin.cpp \
29 libmpeg3pluginimpl.cpp \
30 bitstream.c \
31 libmpeg3.c \
32 mpeg3atrack.c \
33 mpeg3css.c \
34 mpeg3demux.c \
35 mpeg3io.c \
36 mpeg3title.c \
37 mpeg3vtrack.c \
38 audio/ac3.c \
39 audio/bit_allocation.c \
40 audio/dct.c \
41 audio/exponents.c \
42 audio/header.c \
43 audio/layer2.c \
44 audio/layer3.c \
45 audio/mantissa.c \
46 audio/mpeg3audio.c \
47 audio/pcm.c \
48 audio/synthesizers.c \
49 audio/tables.c \
50 video/getpicture.c \
51 video/headers.c \
52 video/idct.c \
53 video/macroblocks.c \
54 video/mmxtest.c \
55 video/motion.c \
56 video/mpeg3video.c \
57 video/output.c \
58 video/reconstruct.c \
59 video/seek.c \
60 video/slice.c \
61 video/vlc.c
62 OBJECTS =libmpeg3plugin.o \
63 libmpeg3pluginimpl.o \
64 bitstream.o \
65 libmpeg3.o \
66 mpeg3atrack.o \
67 mpeg3css.o \
68 mpeg3demux.o \
69 mpeg3io.o \
70 mpeg3title.o \
71 mpeg3vtrack.o \
72 audio/ac3.o \
73 audio/bit_allocation.o \
74 audio/dct.o \
75 audio/exponents.o \
76 audio/header.o \
77 audio/layer2.o \
78 audio/layer3.o \
79 audio/mantissa.o \
80 audio/mpeg3audio.o \
81 audio/pcm.o \
82 audio/synthesizers.o \
83 audio/tables.o \
84 video/getpicture.o \
85 video/headers.o \
86 video/idct.o \
87 video/macroblocks.o \
88 video/mmxtest.o \
89 video/motion.o \
90 video/mpeg3video.o \
91 video/output.o \
92 video/reconstruct.o \
93 video/seek.o \
94 video/slice.o \
95 video/vlc.o
96INTERFACES =
97UICDECLS =
98UICIMPLS =
99 SRCMOC =
100 OBJMOC =
101
102
103####### Implicit rules
104
105.SUFFIXES: .cpp .cxx .cc .C .c
106
107.cpp.o:
108 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
109
110.cxx.o:
111 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
112
113.cc.o:
114 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
115
116.C.o:
117 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
118
119.c.o:
120 $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
121
122####### Build rules
123
124
125all: $(DESTDIR)$(SYSCONF_LINK_TARGET)
126
127$(DESTDIR)$(SYSCONF_LINK_TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
128 $(SYSCONF_LINK_LIB)
129
130moc: $(SRCMOC)
131
132tmake:
133 tmake libmpeg3.pro
134
135clean:
136 -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
137 -rm -f *~ core
138 -rm -f allmoc.cpp
139
140####### Extension Modules
141
142listpromodules:
143 @echo
144
145listallmodules:
146 @echo
147
148listaddonpromodules:
149 @echo
150
151listaddonentmodules:
152 @echo
153
154
155REQUIRES=
156
157####### Sub-libraries
158
159
160###### Combined headers
161
162
163
164####### Compile
165
166libmpeg3plugin.o: libmpeg3plugin.cpp \
167 libmpeg3plugin.h \
168 libmpeg3.h \
169 mpeg3private.h \
170 mpeg3atrack.h \
171 mpeg3demux.h \
172 mpeg3title.h \
173 mpeg3io.h \
174 mpeg3css.h \
175 mpeg3private.inc \
176 audio/mpeg3audio.h \
177 mpeg3vtrack.h \
178 video/mpeg3video.h \
179 mpeg3protos.h \
180 ../mediaplayerplugininterface.h
181
182libmpeg3pluginimpl.o: libmpeg3pluginimpl.cpp \
183 libmpeg3plugin.h \
184 libmpeg3.h \
185 mpeg3private.h \
186 mpeg3atrack.h \
187 mpeg3demux.h \
188 mpeg3title.h \
189 mpeg3io.h \
190 mpeg3css.h \
191 mpeg3private.inc \
192 audio/mpeg3audio.h \
193 mpeg3vtrack.h \
194 video/mpeg3video.h \
195 mpeg3protos.h \
196 ../mediaplayerplugininterface.h \
197 libmpeg3pluginimpl.h \
198 ../mediaplayerplugininterface.h
199
200bitstream.o: bitstream.c \
201 mpeg3private.h \
202 mpeg3atrack.h \
203 mpeg3demux.h \
204 mpeg3title.h \
205 mpeg3io.h \
206 mpeg3css.h \
207 mpeg3private.inc \
208 audio/mpeg3audio.h \
209 mpeg3vtrack.h \
210 video/mpeg3video.h \
211 mpeg3protos.h
212
213libmpeg3.o: libmpeg3.c \
214 libmpeg3.h \
215 mpeg3private.h \
216 mpeg3atrack.h \
217 mpeg3demux.h \
218 mpeg3title.h \
219 mpeg3io.h \
220 mpeg3css.h \
221 mpeg3private.inc \
222 audio/mpeg3audio.h \
223 mpeg3vtrack.h \
224 video/mpeg3video.h \
225 mpeg3protos.h
226
227mpeg3atrack.o: mpeg3atrack.c \
228 libmpeg3.h \
229 mpeg3private.h \
230 mpeg3atrack.h \
231 mpeg3demux.h \
232 mpeg3title.h \
233 mpeg3io.h \
234 mpeg3css.h \
235 mpeg3private.inc \
236 audio/mpeg3audio.h \
237 mpeg3vtrack.h \
238 video/mpeg3video.h \
239 mpeg3protos.h
240
241mpeg3css.o: mpeg3css.c \
242 mpeg3css.h \
243 mpeg3private.h \
244 mpeg3atrack.h \
245 mpeg3demux.h \
246 mpeg3title.h \
247 mpeg3io.h \
248 mpeg3private.inc \
249 audio/mpeg3audio.h \
250 mpeg3vtrack.h \
251 video/mpeg3video.h
252
253mpeg3demux.o: mpeg3demux.c \
254 libmpeg3.h \
255 mpeg3private.h \
256 mpeg3atrack.h \
257 mpeg3demux.h \
258 mpeg3title.h \
259 mpeg3io.h \
260 mpeg3css.h \
261 mpeg3private.inc \
262 audio/mpeg3audio.h \
263 mpeg3vtrack.h \
264 video/mpeg3video.h \
265 mpeg3protos.h
266
267mpeg3io.o: mpeg3io.c \
268 mpeg3private.h \
269 mpeg3atrack.h \
270 mpeg3demux.h \
271 mpeg3title.h \
272 mpeg3io.h \
273 mpeg3css.h \
274 mpeg3private.inc \
275 audio/mpeg3audio.h \
276 mpeg3vtrack.h \
277 video/mpeg3video.h \
278 mpeg3protos.h
279
280mpeg3title.o: mpeg3title.c \
281 mpeg3private.h \
282 mpeg3atrack.h \
283 mpeg3demux.h \
284 mpeg3title.h \
285 mpeg3io.h \
286 mpeg3css.h \
287 mpeg3private.inc \
288 audio/mpeg3audio.h \
289 mpeg3vtrack.h \
290 video/mpeg3video.h \
291 mpeg3protos.h
292
293mpeg3vtrack.o: mpeg3vtrack.c \
294 libmpeg3.h \
295 mpeg3private.h \
296 mpeg3atrack.h \
297 mpeg3demux.h \
298 mpeg3title.h \
299 mpeg3io.h \
300 mpeg3css.h \
301 mpeg3private.inc \
302 audio/mpeg3audio.h \
303 mpeg3vtrack.h \
304 video/mpeg3video.h \
305 mpeg3protos.h
306
307audio/ac3.o: audio/ac3.c \
308 audio/mpeg3audio.h \
309 audio/ac3.h \
310 audio/mpeg3real.h \
311 audio/../bitstream.h \
312 mpeg3demux.h \
313 mpeg3title.h \
314 mpeg3io.h \
315 mpeg3css.h \
316 mpeg3private.inc \
317 audio/../libmpeg3.h \
318 mpeg3private.h \
319 mpeg3atrack.h \
320 audio/mpeg3audio.h \
321 mpeg3vtrack.h \
322 video/mpeg3video.h \
323 audio/../mpeg3protos.h
324
325audio/bit_allocation.o: audio/bit_allocation.c \
326 audio/mpeg3audio.h \
327 audio/ac3.h \
328 audio/mpeg3real.h \
329 audio/../bitstream.h \
330 mpeg3demux.h \
331 mpeg3title.h \
332 mpeg3io.h \
333 mpeg3css.h \
334 mpeg3private.inc \
335 audio/../libmpeg3.h \
336 mpeg3private.h \
337 mpeg3atrack.h \
338 audio/mpeg3audio.h \
339 mpeg3vtrack.h \
340 video/mpeg3video.h \
341 audio/../mpeg3protos.h
342
343audio/dct.o: audio/dct.c \
344 audio/mpeg3audio.h \
345 audio/ac3.h \
346 audio/mpeg3real.h \
347 audio/../bitstream.h \
348 mpeg3demux.h \
349 mpeg3title.h \
350 mpeg3io.h \
351 mpeg3css.h \
352 mpeg3private.inc \
353 audio/../libmpeg3.h \
354 mpeg3private.h \
355 mpeg3atrack.h \
356 audio/mpeg3audio.h \
357 mpeg3vtrack.h \
358 video/mpeg3video.h \
359 audio/../mpeg3protos.h \
360 audio/tables.h \
361 audio/fptables.h
362
363audio/exponents.o: audio/exponents.c \
364 audio/mpeg3audio.h \
365 audio/ac3.h \
366 audio/mpeg3real.h \
367 audio/../bitstream.h \
368 mpeg3demux.h \
369 mpeg3title.h \
370 mpeg3io.h \
371 mpeg3css.h \
372 mpeg3private.inc \
373 audio/../libmpeg3.h \
374 mpeg3private.h \
375 mpeg3atrack.h \
376 audio/mpeg3audio.h \
377 mpeg3vtrack.h \
378 video/mpeg3video.h \
379 audio/../mpeg3protos.h
380
381audio/header.o: audio/header.c \
382 audio/mpeg3audio.h \
383 audio/ac3.h \
384 audio/mpeg3real.h \
385 audio/../bitstream.h \
386 mpeg3demux.h \
387 mpeg3title.h \
388 mpeg3io.h \
389 mpeg3css.h \
390 mpeg3private.inc \
391 audio/tables.h \
392 audio/../libmpeg3.h \
393 mpeg3private.h \
394 mpeg3atrack.h \
395 audio/mpeg3audio.h \
396 mpeg3vtrack.h \
397 video/mpeg3video.h \
398 audio/../mpeg3protos.h
399
400audio/layer2.o: audio/layer2.c \
401 audio/mpeg3audio.h \
402 audio/ac3.h \
403 audio/mpeg3real.h \
404 audio/../bitstream.h \
405 mpeg3demux.h \
406 mpeg3title.h \
407 mpeg3io.h \
408 mpeg3css.h \
409 mpeg3private.inc \
410 audio/../libmpeg3.h \
411 mpeg3private.h \
412 mpeg3atrack.h \
413 audio/mpeg3audio.h \
414 mpeg3vtrack.h \
415 video/mpeg3video.h \
416 audio/../mpeg3protos.h \
417 audio/tables.h
418
419audio/layer3.o: audio/layer3.c \
420 audio/huffman.h \
421 audio/mpeg3audio.h \
422 audio/ac3.h \
423 audio/mpeg3real.h \
424 audio/../bitstream.h \
425 mpeg3demux.h \
426 mpeg3title.h \
427 mpeg3io.h \
428 mpeg3css.h \
429 mpeg3private.inc \
430 audio/../libmpeg3.h \
431 mpeg3private.h \
432 mpeg3atrack.h \
433 audio/mpeg3audio.h \
434 mpeg3vtrack.h \
435 video/mpeg3video.h \
436 audio/../mpeg3protos.h \
437 audio/tables.h
438
439audio/mantissa.o: audio/mantissa.c \
440 audio/mpeg3audio.h \
441 audio/ac3.h \
442 audio/mpeg3real.h \
443 audio/../bitstream.h \
444 mpeg3demux.h \
445 mpeg3title.h \
446 mpeg3io.h \
447 mpeg3css.h \
448 mpeg3private.inc \
449 audio/../libmpeg3.h \
450 mpeg3private.h \
451 mpeg3atrack.h \
452 audio/mpeg3audio.h \
453 mpeg3vtrack.h \
454 video/mpeg3video.h \
455 audio/../mpeg3protos.h
456
457audio/mpeg3audio.o: audio/mpeg3audio.c \
458 audio/../libmpeg3.h \
459 mpeg3private.h \
460 mpeg3atrack.h \
461 mpeg3demux.h \
462 mpeg3title.h \
463 mpeg3io.h \
464 mpeg3css.h \
465 mpeg3private.inc \
466 audio/mpeg3audio.h \
467 audio/ac3.h \
468 audio/mpeg3real.h \
469 audio/../bitstream.h \
470 mpeg3vtrack.h \
471 video/mpeg3video.h \
472 audio/../mpeg3protos.h \
473 audio/mpeg3audio.h \
474 audio/tables.h
475
476audio/pcm.o: audio/pcm.c \
477 audio/mpeg3audio.h \
478 audio/ac3.h \
479 audio/mpeg3real.h \
480 audio/../bitstream.h \
481 mpeg3demux.h \
482 mpeg3title.h \
483 mpeg3io.h \
484 mpeg3css.h \
485 mpeg3private.inc \
486 audio/../libmpeg3.h \
487 mpeg3private.h \
488 mpeg3atrack.h \
489 audio/mpeg3audio.h \
490 mpeg3vtrack.h \
491 video/mpeg3video.h \
492 audio/../mpeg3protos.h
493
494audio/synthesizers.o: audio/synthesizers.c \
495 audio/mpeg3audio.h \
496 audio/ac3.h \
497 audio/mpeg3real.h \
498 audio/../bitstream.h \
499 mpeg3demux.h \
500 mpeg3title.h \
501 mpeg3io.h \
502 mpeg3css.h \
503 mpeg3private.inc \
504 audio/../libmpeg3.h \
505 mpeg3private.h \
506 mpeg3atrack.h \
507 audio/mpeg3audio.h \
508 mpeg3vtrack.h \
509 video/mpeg3video.h \
510 audio/../mpeg3protos.h \
511 audio/tables.h
512
513audio/tables.o: audio/tables.c \
514 audio/mpeg3audio.h \
515 audio/ac3.h \
516 audio/mpeg3real.h \
517 audio/../bitstream.h \
518 mpeg3demux.h \
519 mpeg3title.h \
520 mpeg3io.h \
521 mpeg3css.h \
522 mpeg3private.inc \
523 audio/../libmpeg3.h \
524 mpeg3private.h \
525 mpeg3atrack.h \
526 audio/mpeg3audio.h \
527 mpeg3vtrack.h \
528 video/mpeg3video.h \
529 audio/../mpeg3protos.h \
530 audio/tables.h \
531 audio/fptables.h
532
533video/getpicture.o: video/getpicture.c \
534 audio/../libmpeg3.h \
535 mpeg3private.h \
536 mpeg3atrack.h \
537 mpeg3demux.h \
538 mpeg3title.h \
539 mpeg3io.h \
540 mpeg3css.h \
541 mpeg3private.inc \
542 audio/mpeg3audio.h \
543 audio/ac3.h \
544 audio/mpeg3real.h \
545 audio/../bitstream.h \
546 mpeg3vtrack.h \
547 video/mpeg3video.h \
548 video/../mpeg3private.inc \
549 video/idct.h \
550 video/slice.h \
551 video/../timecode.h \
552 video/../mpeg3protos.h \
553 video/mpeg3video.h \
554 video/vlc.h
555
556video/headers.o: video/headers.c \
557 video/../mpeg3demux.h \
558 mpeg3title.h \
559 mpeg3io.h \
560 mpeg3css.h \
561 mpeg3private.inc \
562 audio/../libmpeg3.h \
563 mpeg3private.h \
564 mpeg3atrack.h \
565 mpeg3demux.h \
566 audio/mpeg3audio.h \
567 audio/ac3.h \
568 audio/mpeg3real.h \
569 audio/../bitstream.h \
570 mpeg3vtrack.h \
571 video/mpeg3video.h \
572 video/../mpeg3private.inc \
573 video/idct.h \
574 video/slice.h \
575 video/../timecode.h \
576 video/../mpeg3protos.h \
577 video/mpeg3video.h
578
579video/idct.o: video/idct.c \
580 video/idct.h
581
582video/macroblocks.o: video/macroblocks.c \
583 audio/../libmpeg3.h \
584 mpeg3private.h \
585 mpeg3atrack.h \
586 mpeg3demux.h \
587 mpeg3title.h \
588 mpeg3io.h \
589 mpeg3css.h \
590 mpeg3private.inc \
591 audio/mpeg3audio.h \
592 audio/ac3.h \
593 audio/mpeg3real.h \
594 audio/../bitstream.h \
595 mpeg3vtrack.h \
596 video/mpeg3video.h \
597 video/../mpeg3private.inc \
598 video/idct.h \
599 video/slice.h \
600 video/../timecode.h \
601 video/../mpeg3protos.h \
602 video/mpeg3video.h \
603 video/vlc.h
604
605video/mmxtest.o: video/mmxtest.c \
606 audio/../libmpeg3.h \
607 mpeg3private.h \
608 mpeg3atrack.h \
609 mpeg3demux.h \
610 mpeg3title.h \
611 mpeg3io.h \
612 mpeg3css.h \
613 mpeg3private.inc \
614 audio/mpeg3audio.h \
615 audio/ac3.h \
616 audio/mpeg3real.h \
617 audio/../bitstream.h \
618 mpeg3vtrack.h \
619 video/mpeg3video.h \
620 video/../mpeg3private.inc \
621 video/idct.h \
622 video/slice.h \
623 video/../timecode.h \
624 video/../mpeg3protos.h
625
626video/motion.o: video/motion.c \
627 video/mpeg3video.h \
628 audio/../bitstream.h \
629 mpeg3demux.h \
630 mpeg3title.h \
631 mpeg3io.h \
632 mpeg3css.h \
633 mpeg3private.inc \
634 video/../mpeg3private.inc \
635 video/idct.h \
636 video/slice.h \
637 video/../timecode.h \
638 audio/../libmpeg3.h \
639 mpeg3private.h \
640 mpeg3atrack.h \
641 audio/mpeg3audio.h \
642 audio/ac3.h \
643 audio/mpeg3real.h \
644 mpeg3vtrack.h \
645 video/mpeg3video.h \
646 video/../mpeg3protos.h \
647 video/vlc.h
648
649video/mpeg3video.o: video/mpeg3video.c \
650 audio/../libmpeg3.h \
651 mpeg3private.h \
652 mpeg3atrack.h \
653 mpeg3demux.h \
654 mpeg3title.h \
655 mpeg3io.h \
656 mpeg3css.h \
657 mpeg3private.inc \
658 audio/mpeg3audio.h \
659 audio/ac3.h \
660 audio/mpeg3real.h \
661 audio/../bitstream.h \
662 mpeg3vtrack.h \
663 video/mpeg3video.h \
664 video/../mpeg3private.inc \
665 video/idct.h \
666 video/slice.h \
667 video/../timecode.h \
668 video/../mpeg3protos.h \
669 video/mpeg3video.h \
670 video/mpeg3videoprotos.h
671
672video/output.o: video/output.c \
673 audio/../libmpeg3.h \
674 mpeg3private.h \
675 mpeg3atrack.h \
676 mpeg3demux.h \
677 mpeg3title.h \
678 mpeg3io.h \
679 mpeg3css.h \
680 mpeg3private.inc \
681 audio/mpeg3audio.h \
682 audio/ac3.h \
683 audio/mpeg3real.h \
684 audio/../bitstream.h \
685 mpeg3vtrack.h \
686 video/mpeg3video.h \
687 video/../mpeg3private.inc \
688 video/idct.h \
689 video/slice.h \
690 video/../timecode.h \
691 video/../mpeg3protos.h \
692 video/mpeg3video.h
693
694video/reconstruct.o: video/reconstruct.c \
695 audio/../libmpeg3.h \
696 mpeg3private.h \
697 mpeg3atrack.h \
698 mpeg3demux.h \
699 mpeg3title.h \
700 mpeg3io.h \
701 mpeg3css.h \
702 mpeg3private.inc \
703 audio/mpeg3audio.h \
704 audio/ac3.h \
705 audio/mpeg3real.h \
706 audio/../bitstream.h \
707 mpeg3vtrack.h \
708 video/mpeg3video.h \
709 video/../mpeg3private.inc \
710 video/idct.h \
711 video/slice.h \
712 video/../timecode.h \
713 video/../mpeg3protos.h \
714 video/mpeg3video.h
715
716video/seek.o: video/seek.c \
717 video/../mpeg3private.h \
718 mpeg3atrack.h \
719 mpeg3demux.h \
720 mpeg3title.h \
721 mpeg3io.h \
722 mpeg3css.h \
723 mpeg3private.inc \
724 audio/mpeg3audio.h \
725 audio/ac3.h \
726 audio/mpeg3real.h \
727 audio/../bitstream.h \
728 mpeg3vtrack.h \
729 video/mpeg3video.h \
730 video/../mpeg3private.inc \
731 video/idct.h \
732 video/slice.h \
733 video/../timecode.h \
734 video/../mpeg3protos.h \
735 video/mpeg3video.h
736
737video/slice.o: video/slice.c \
738 audio/../libmpeg3.h \
739 mpeg3private.h \
740 mpeg3atrack.h \
741 mpeg3demux.h \
742 mpeg3title.h \
743 mpeg3io.h \
744 mpeg3css.h \
745 mpeg3private.inc \
746 audio/mpeg3audio.h \
747 audio/ac3.h \
748 audio/mpeg3real.h \
749 audio/../bitstream.h \
750 mpeg3vtrack.h \
751 video/mpeg3video.h \
752 video/../mpeg3private.inc \
753 video/idct.h \
754 video/slice.h \
755 video/../timecode.h \
756 video/../mpeg3protos.h \
757 video/mpeg3video.h \
758 video/mpeg3videoprotos.h
759
760video/vlc.o: video/vlc.c \
761 video/mpeg3video.h \
762 audio/../bitstream.h \
763 mpeg3demux.h \
764 mpeg3title.h \
765 mpeg3io.h \
766 mpeg3css.h \
767 mpeg3private.inc \
768 video/../mpeg3private.inc \
769 video/idct.h \
770 video/slice.h \
771 video/../timecode.h \
772 video/vlc.h
773
774
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 @@
1/********************************************************
2 * LibMPEG3
3 * Author: Adam Williams <broadcast@earthling.net>
4 * Page: heroine.linuxbox.com
5 *
6 * libmpeg3 is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * libmpeg3 is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Make; see the file COPYING. If not, write to
18 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 *******************************************************/
21
22
23/**********************************************************
24 * Credits:
25 *********************************************************/
26
27AC3 decoder:
28
29 Written by Aaron Holtzman (aholtzma@engr.uvic.ca)
30
31
32
33Problems:
34
35 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 @@
1include ../global_config
2export CFLAGS
3export CFLAGS_lessopt
4
5OBJS = \
6 ac3.o \
7 bit_allocation.o \
8 dct.o \
9 exponents.o \
10 header.o \
11 layer2.o \
12 layer3.o \
13 mantissa.o \
14 mpeg3audio.o \
15 pcm.o \
16 synthesizers.o \
17 tables.o
18
19all: $(OBJS)
20
21dct.o: dct.c
22 $(CC) -c `./c_flags dct.c` -o $@ $<
23
24synthesizers.o: synthesizers.c
25 $(CC) -c `./c_flags synthesizers.c` -o $@ $<
26
27
28.c.o:
29 $(CC) -c `./c_flags` -o $@ $<
30
31.s.o:
32 $(CC) -f elf $*.s
33
34clean:
35 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 @@
1/*
2 *
3 *ac3.c Copyright (C) Aaron Holtzman - May 1999
4 *
5 *
6 * This file is part of libmpeg3
7 *
8 * libmpeg3 is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * libmpeg3 is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with GNU Make; see the file COPYING. If not, write to
20 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 */
23
24#include "mpeg3audio.h"
25#include "../libmpeg3.h"
26#include "../mpeg3protos.h"
27
28#include <math.h>
29#include <stdlib.h>
30#include <stdio.h>
31#include <string.h>
32
33#define MPEG3AC3_MAGIC_NUMBER 0xdeadbeef
34
35
36int mpeg3_ac3_samplerates[] = { 48000, 44100, 32000 };
37
38struct mpeg3_framesize_s
39{
40 unsigned short bit_rate;
41 unsigned short frm_size[3];
42};
43
44struct mpeg3_framesize_s framesize_codes[] =
45{
46 { 32 ,{64 ,69 ,96 } },
47 { 32 ,{64 ,70 ,96 } },
48 { 40 ,{80 ,87 ,120 } },
49 { 40 ,{80 ,88 ,120 } },
50 { 48 ,{96 ,104 ,144 } },
51 { 48 ,{96 ,105 ,144 } },
52 { 56 ,{112 ,121 ,168 } },
53 { 56 ,{112 ,122 ,168 } },
54 { 64 ,{128 ,139 ,192 } },
55 { 64 ,{128 ,140 ,192 } },
56 { 80 ,{160 ,174 ,240 } },
57 { 80 ,{160 ,175 ,240 } },
58 { 96 ,{192 ,208 ,288 } },
59 { 96 ,{192 ,209 ,288 } },
60 { 112 ,{224 ,243 ,336 } },
61 { 112 ,{224 ,244 ,336 } },
62 { 128 ,{256 ,278 ,384 } },
63 { 128 ,{256 ,279 ,384 } },
64 { 160 ,{320 ,348 ,480 } },
65 { 160 ,{320 ,349 ,480 } },
66 { 192 ,{384 ,417 ,576 } },
67 { 192 ,{384 ,418 ,576 } },
68 { 224 ,{448 ,487 ,672 } },
69 { 224 ,{448 ,488 ,672 } },
70 { 256 ,{512 ,557 ,768 } },
71 { 256 ,{512 ,558 ,768 } },
72 { 320 ,{640 ,696 ,960 } },
73 { 320 ,{640 ,697 ,960 } },
74 { 384 ,{768 ,835 ,1152 } },
75 { 384 ,{768 ,836 ,1152 } },
76 { 448 ,{896 ,975 ,1344 } },
77 { 448 ,{896 ,976 ,1344 } },
78 { 512 ,{1024 ,1114 ,1536 } },
79 { 512 ,{1024 ,1115 ,1536 } },
80 { 576 ,{1152 ,1253 ,1728 } },
81 { 576 ,{1152 ,1254 ,1728 } },
82 { 640 ,{1280 ,1393 ,1920 } },
83 { 640 ,{1280 ,1394 ,1920 } }
84};
85
86/* Audio channel modes */
87short mpeg3_ac3_acmodes[] = {2, 1, 2, 3, 3, 4, 4, 5};
88
89/* Rematrix tables */
90struct rematrix_band_s
91{
92 int start;
93 int end;
94};
95
96struct rematrix_band_s mpeg3_rematrix_band[] =
97{
98 {13, 24},
99 {25, 36},
100 {37, 60},
101 {61, 252}
102};
103
104int mpeg3_min(int x, int y)
105{
106 return (x < y) ? x : y;
107}
108
109int mpeg3_max(int x, int y)
110{
111 return (x > y) ? x : y;
112}
113
114int mpeg3audio_read_ac3_header(mpeg3audio_t *audio)
115{
116 unsigned int code, crc;
117 unsigned int i;
118 mpeg3_ac3bsi_t *bsi = &(audio->ac3_bsi);
119
120/* Get the sync code */
121 code = mpeg3bits_getbits(audio->astream, 16);
122 while(!mpeg3bits_eof(audio->astream) && code != MPEG3_AC3_START_CODE)
123 {
124 code <<= 8;
125 code &= 0xffff;
126 code |= mpeg3bits_getbits(audio->astream, 8);
127 }
128
129 if(mpeg3bits_eof(audio->astream)) return 1;
130
131/* Get crc1 - we don't actually use this data though */
132/* The crc can be the same as the sync code or come after a sync code repeated twice */
133 crc = mpeg3bits_getbits(audio->astream, 16);
134
135/* Got the sync code. Read the entire frame into a buffer if possible. */
136 if(audio->avg_framesize > 0)
137 {
138 if(mpeg3bits_read_buffer(audio->astream, audio->ac3_buffer, audio->framesize - 4))
139 return 1;
140 mpeg3bits_use_ptr(audio->astream, audio->ac3_buffer);
141 }
142
143/* Get the sampling rate code */
144 audio->sampling_frequency_code = mpeg3bits_getbits(audio->astream, 2);
145
146/* Get the frame size code */
147 audio->ac3_framesize_code = mpeg3bits_getbits(audio->astream, 6);
148
149 audio->bitrate = framesize_codes[audio->ac3_framesize_code].bit_rate;
150 audio->avg_framesize = audio->framesize = 2 * framesize_codes[audio->ac3_framesize_code].frm_size[audio->sampling_frequency_code];
151
152/* Check the AC-3 version number */
153 bsi->bsid = mpeg3bits_getbits(audio->astream, 5);
154
155/* Get the audio service provided by the steram */
156 bsi->bsmod = mpeg3bits_getbits(audio->astream, 3);
157
158/* Get the audio coding mode (ie how many channels)*/
159 bsi->acmod = mpeg3bits_getbits(audio->astream, 3);
160
161/* Predecode the number of full bandwidth channels as we use this
162 * number a lot */
163 bsi->nfchans = mpeg3_ac3_acmodes[bsi->acmod];
164 audio->channels = bsi->nfchans;
165
166/* If it is in use, get the centre channel mix level */
167 if((bsi->acmod & 0x1) && (bsi->acmod != 0x1))
168 bsi->cmixlev = mpeg3bits_getbits(audio->astream, 2);
169
170/* If it is in use, get the surround channel mix level */
171 if(bsi->acmod & 0x4)
172 bsi->surmixlev = mpeg3bits_getbits(audio->astream, 2);
173
174/* Get the dolby surround mode if in 2/0 mode */
175 if(bsi->acmod == 0x2)
176 bsi->dsurmod= mpeg3bits_getbits(audio->astream, 2);
177
178/* Is the low frequency effects channel on? */
179 bsi->lfeon = mpeg3bits_getbits(audio->astream, 1);
180
181/* Get the dialogue normalization level */
182 bsi->dialnorm = mpeg3bits_getbits(audio->astream, 5);
183
184/* Does compression gain exist? */
185 bsi->compre = mpeg3bits_getbits(audio->astream, 1);
186 if (bsi->compre)
187 {
188/* Get compression gain */
189 bsi->compr = mpeg3bits_getbits(audio->astream, 8);
190 }
191
192/* Does language code exist? */
193 bsi->langcode = mpeg3bits_getbits(audio->astream, 1);
194 if (bsi->langcode)
195 {
196/* Get langauge code */
197 bsi->langcod = mpeg3bits_getbits(audio->astream, 8);
198 }
199
200/* Does audio production info exist? */
201 bsi->audprodie = mpeg3bits_getbits(audio->astream, 1);
202 if (bsi->audprodie)
203 {
204/* Get mix level */
205 bsi->mixlevel = mpeg3bits_getbits(audio->astream, 5);
206
207/* Get room type */
208 bsi->roomtyp = mpeg3bits_getbits(audio->astream, 2);
209 }
210
211/* If we're in dual mono mode then get some extra info */
212 if (bsi->acmod == 0)
213 {
214/* Get the dialogue normalization level two */
215 bsi->dialnorm2 = mpeg3bits_getbits(audio->astream, 5);
216
217/* Does compression gain two exist? */
218 bsi->compr2e = mpeg3bits_getbits(audio->astream, 1);
219 if (bsi->compr2e)
220 {
221/* Get compression gain two */
222 bsi->compr2 = mpeg3bits_getbits(audio->astream, 8);
223 }
224
225/* Does language code two exist? */
226 bsi->langcod2e = mpeg3bits_getbits(audio->astream, 1);
227 if (bsi->langcod2e)
228 {
229/* Get langauge code two */
230 bsi->langcod2 = mpeg3bits_getbits(audio->astream, 8);
231 }
232
233/* Does audio production info two exist? */
234 bsi->audprodi2e = mpeg3bits_getbits(audio->astream, 1);
235 if (bsi->audprodi2e)
236 {
237/* Get mix level two */
238 bsi->mixlevel2 = mpeg3bits_getbits(audio->astream, 5);
239
240/* Get room type two */
241 bsi->roomtyp2 = mpeg3bits_getbits(audio->astream, 2);
242 }
243 }
244
245/* Get the copyright bit */
246 bsi->copyrightb = mpeg3bits_getbits(audio->astream, 1);
247
248/* Get the original bit */
249 bsi->origbs = mpeg3bits_getbits(audio->astream, 1);
250
251/* Does timecode one exist? */
252 bsi->timecod1e = mpeg3bits_getbits(audio->astream, 1);
253
254 if(bsi->timecod1e)
255 bsi->timecod1 = mpeg3bits_getbits(audio->astream, 14);
256
257/* Does timecode two exist? */
258 bsi->timecod2e = mpeg3bits_getbits(audio->astream, 1);
259
260 if(bsi->timecod2e)
261 bsi->timecod2 = mpeg3bits_getbits(audio->astream, 14);
262
263/* Does addition info exist? */
264 bsi->addbsie = mpeg3bits_getbits(audio->astream, 1);
265
266 if(bsi->addbsie)
267 {
268/* Get how much info is there */
269 bsi->addbsil = mpeg3bits_getbits(audio->astream, 6);
270
271/* Get the additional info */
272 for(i = 0; i < (bsi->addbsil + 1); i++)
273 bsi->addbsi[i] = mpeg3bits_getbits(audio->astream, 8);
274 }
275
276 if(mpeg3bits_eof(audio->astream))
277 {
278 mpeg3bits_use_demuxer(audio->astream);
279 return 1;
280 }
281 //return mpeg3bits_error(audio->astream);
282}
283
284int mpeg3audio_read_ac3_audblk(mpeg3audio_t *audio)
285{
286 int i, j;
287 mpeg3_ac3bsi_t *bsi = &(audio->ac3_bsi);
288 mpeg3_ac3audblk_t *audblk = &(audio->ac3_audblk);
289
290 for(i = 0; i < bsi->nfchans; i++)
291 {
292/* Is this channel an interleaved 256 + 256 block ? */
293 audblk->blksw[i] = mpeg3bits_getbits(audio->astream, 1);
294 }
295
296 for(i = 0; i < bsi->nfchans; i++)
297 {
298/* Should we dither this channel? */
299 audblk->dithflag[i] = mpeg3bits_getbits(audio->astream, 1);
300 }
301
302/* Does dynamic range control exist? */
303 audblk->dynrnge = mpeg3bits_getbits(audio->astream, 1);
304 if(audblk->dynrnge)
305 {
306/* Get dynamic range info */
307 audblk->dynrng = mpeg3bits_getbits(audio->astream, 8);
308 }
309
310/* If we're in dual mono mode then get the second channel DR info */
311 if(bsi->acmod == 0)
312 {
313/* Does dynamic range control two exist? */
314 audblk->dynrng2e = mpeg3bits_getbits(audio->astream, 1);
315 if (audblk->dynrng2e)
316 {
317/* Get dynamic range info */
318 audblk->dynrng2 = mpeg3bits_getbits(audio->astream, 8);
319 }
320 }
321
322/* Does coupling strategy exist? */
323 audblk->cplstre = mpeg3bits_getbits(audio->astream, 1);
324 if(audblk->cplstre)
325 {
326/* Is coupling turned on? */
327 audblk->cplinu = mpeg3bits_getbits(audio->astream, 1);
328 if(audblk->cplinu)
329 {
330 for(i = 0; i < bsi->nfchans; i++)
331 audblk->chincpl[i] = mpeg3bits_getbits(audio->astream, 1);
332
333 if(bsi->acmod == 0x2)
334 audblk->phsflginu = mpeg3bits_getbits(audio->astream, 1);
335
336 audblk->cplbegf = mpeg3bits_getbits(audio->astream, 4);
337 audblk->cplendf = mpeg3bits_getbits(audio->astream, 4);
338 audblk->ncplsubnd = (audblk->cplendf + 2) - audblk->cplbegf + 1;
339
340/* Calculate the start and end bins of the coupling channel */
341 audblk->cplstrtmant = (audblk->cplbegf * 12) + 37 ;
342 audblk->cplendmant = ((audblk->cplendf + 3) * 12) + 37;
343
344/* The number of combined subbands is ncplsubnd minus each combined band */
345 audblk->ncplbnd = audblk->ncplsubnd;
346
347 for(i = 1; i < audblk->ncplsubnd; i++)
348 {
349 audblk->cplbndstrc[i] = mpeg3bits_getbits(audio->astream, 1);
350 audblk->ncplbnd -= audblk->cplbndstrc[i];
351 }
352 }
353 }
354
355 if(audblk->cplinu)
356 {
357 /* Loop through all the channels and get their coupling co-ords */
358 for(i = 0; i < bsi->nfchans; i++)
359 {
360 if(!audblk->chincpl[i])
361 continue;
362
363/* Is there new coupling co-ordinate info? */
364 audblk->cplcoe[i] = mpeg3bits_getbits(audio->astream, 1);
365
366 if(audblk->cplcoe[i])
367 {
368 audblk->mstrcplco[i] = mpeg3bits_getbits(audio->astream, 2);
369 for(j = 0; j < audblk->ncplbnd; j++)
370 {
371 audblk->cplcoexp[i][j] = mpeg3bits_getbits(audio->astream, 4);
372 audblk->cplcomant[i][j] = mpeg3bits_getbits(audio->astream, 4);
373 }
374 }
375 }
376
377/* If we're in dual mono mode, there's going to be some phase info */
378 if((bsi->acmod == 0x2) && audblk->phsflginu &&
379 (audblk->cplcoe[0] || audblk->cplcoe[1]))
380 {
381 for(j = 0; j < audblk->ncplbnd; j++)
382 {
383 audblk->phsflg[j] = mpeg3bits_getbits(audio->astream, 1);
384 }
385 }
386 }
387
388/* If we're in dual mono mode, there may be a rematrix strategy */
389 if(bsi->acmod == 0x2)
390 {
391 audblk->rematstr = mpeg3bits_getbits(audio->astream, 1);
392 if(audblk->rematstr)
393 {
394 if (audblk->cplinu == 0)
395 {
396 for(i = 0; i < 4; i++)
397 audblk->rematflg[i] = mpeg3bits_getbits(audio->astream, 1);
398 }
399 if((audblk->cplbegf > 2) && audblk->cplinu)
400 {
401 for(i = 0; i < 4; i++)
402 audblk->rematflg[i] = mpeg3bits_getbits(audio->astream, 1);
403 }
404 if((audblk->cplbegf <= 2) && audblk->cplinu)
405 {
406 for(i = 0; i < 3; i++)
407 audblk->rematflg[i] = mpeg3bits_getbits(audio->astream, 1);
408 }
409 if((audblk->cplbegf == 0) && audblk->cplinu)
410 for(i = 0; i < 2; i++)
411 audblk->rematflg[i] = mpeg3bits_getbits(audio->astream, 1);
412
413 }
414 }
415
416 if (audblk->cplinu)
417 {
418/* Get the coupling channel exponent strategy */
419 audblk->cplexpstr = mpeg3bits_getbits(audio->astream, 2);
420
421 if(audblk->cplexpstr == 0)
422 audblk->ncplgrps = 0;
423 else
424 audblk->ncplgrps = (audblk->cplendmant - audblk->cplstrtmant) /
425 (3 << (audblk->cplexpstr - 1));
426
427 }
428
429 for(i = 0; i < bsi->nfchans; i++)
430 {
431 audblk->chexpstr[i] = mpeg3bits_getbits(audio->astream, 2);
432 }
433
434/* Get the exponent strategy for lfe channel */
435 if(bsi->lfeon)
436 audblk->lfeexpstr = mpeg3bits_getbits(audio->astream, 1);
437
438/* Determine the bandwidths of all the fbw channels */
439 for(i = 0; i < bsi->nfchans; i++)
440 {
441 unsigned short grp_size;
442
443 if(audblk->chexpstr[i] != MPEG3_EXP_REUSE)
444 {
445 if (audblk->cplinu && audblk->chincpl[i])
446 {
447 audblk->endmant[i] = audblk->cplstrtmant;
448 }
449 else
450 {
451 audblk->chbwcod[i] = mpeg3bits_getbits(audio->astream, 6);
452 audblk->endmant[i] = ((audblk->chbwcod[i] + 12) * 3) + 37;
453 }
454
455/* Calculate the number of exponent groups to fetch */
456 grp_size = 3 * (1 << (audblk->chexpstr[i] - 1));
457 audblk->nchgrps[i] = (audblk->endmant[i] - 1 + (grp_size - 3)) / grp_size;
458 }
459 }
460
461/* Get the coupling exponents if they exist */
462 if(audblk->cplinu && (audblk->cplexpstr != MPEG3_EXP_REUSE))
463 {
464 audblk->cplabsexp = mpeg3bits_getbits(audio->astream, 4);
465 for(i = 0; i< audblk->ncplgrps; i++)
466 audblk->cplexps[i] = mpeg3bits_getbits(audio->astream, 7);
467 }
468
469/* Get the fwb channel exponents */
470 for(i = 0; i < bsi->nfchans; i++)
471 {
472 if(audblk->chexpstr[i] != MPEG3_EXP_REUSE)
473 {
474 audblk->exps[i][0] = mpeg3bits_getbits(audio->astream, 4);
475 for(j = 1; j <= audblk->nchgrps[i]; j++)
476 audblk->exps[i][j] = mpeg3bits_getbits(audio->astream, 7);
477 audblk->gainrng[i] = mpeg3bits_getbits(audio->astream, 2);
478 }
479 }
480
481/* Get the lfe channel exponents */
482 if(bsi->lfeon && (audblk->lfeexpstr != MPEG3_EXP_REUSE))
483 {
484 audblk->lfeexps[0] = mpeg3bits_getbits(audio->astream, 4);
485 audblk->lfeexps[1] = mpeg3bits_getbits(audio->astream, 7);
486 audblk->lfeexps[2] = mpeg3bits_getbits(audio->astream, 7);
487 }
488
489/* Get the parametric bit allocation parameters */
490 audblk->baie = mpeg3bits_getbits(audio->astream, 1);
491
492 if(audblk->baie)
493 {
494 audblk->sdcycod = mpeg3bits_getbits(audio->astream, 2);
495 audblk->fdcycod = mpeg3bits_getbits(audio->astream, 2);
496 audblk->sgaincod = mpeg3bits_getbits(audio->astream, 2);
497 audblk->dbpbcod = mpeg3bits_getbits(audio->astream, 2);
498 audblk->floorcod = mpeg3bits_getbits(audio->astream, 3);
499 }
500
501
502/* Get the SNR off set info if it exists */
503 audblk->snroffste = mpeg3bits_getbits(audio->astream, 1);
504
505 if(audblk->snroffste)
506 {
507 audblk->csnroffst = mpeg3bits_getbits(audio->astream, 6);
508
509 if(audblk->cplinu)
510 {
511 audblk->cplfsnroffst = mpeg3bits_getbits(audio->astream, 4);
512 audblk->cplfgaincod = mpeg3bits_getbits(audio->astream, 3);
513 }
514
515 for(i = 0; i < bsi->nfchans; i++)
516 {
517 audblk->fsnroffst[i] = mpeg3bits_getbits(audio->astream, 4);
518 audblk->fgaincod[i] = mpeg3bits_getbits(audio->astream, 3);
519 }
520 if(bsi->lfeon)
521 {
522
523 audblk->lfefsnroffst = mpeg3bits_getbits(audio->astream, 4);
524 audblk->lfefgaincod = mpeg3bits_getbits(audio->astream, 3);
525 }
526 }
527
528/* Get coupling leakage info if it exists */
529 if(audblk->cplinu)
530 {
531 audblk->cplleake = mpeg3bits_getbits(audio->astream, 1);
532
533 if(audblk->cplleake)
534 {
535 audblk->cplfleak = mpeg3bits_getbits(audio->astream, 3);
536 audblk->cplsleak = mpeg3bits_getbits(audio->astream, 3);
537 }
538 }
539
540/* Get the delta bit alloaction info */
541 audblk->deltbaie = mpeg3bits_getbits(audio->astream, 1);
542
543 if(audblk->deltbaie)
544 {
545 if(audblk->cplinu)
546 audblk->cpldeltbae = mpeg3bits_getbits(audio->astream, 2);
547
548 for(i = 0; i < bsi->nfchans; i++)
549 audblk->deltbae[i] = mpeg3bits_getbits(audio->astream, 2);
550
551 if (audblk->cplinu && (audblk->cpldeltbae == DELTA_BIT_NEW))
552 {
553 audblk->cpldeltnseg = mpeg3bits_getbits(audio->astream, 3);
554 for(i = 0; i < audblk->cpldeltnseg + 1; i++)
555 {
556 audblk->cpldeltoffst[i] = mpeg3bits_getbits(audio->astream, 5);
557 audblk->cpldeltlen[i] = mpeg3bits_getbits(audio->astream, 4);
558 audblk->cpldeltba[i] = mpeg3bits_getbits(audio->astream, 3);
559 }
560 }
561
562 for(i = 0; i < bsi->nfchans; i++)
563 {
564 if (audblk->deltbae[i] == DELTA_BIT_NEW)
565 {
566 audblk->deltnseg[i] = mpeg3bits_getbits(audio->astream, 3);
567 for(j = 0; j < audblk->deltnseg[i] + 1; j++)
568 {
569 audblk->deltoffst[i][j] = mpeg3bits_getbits(audio->astream, 5);
570 audblk->deltlen[i][j] = mpeg3bits_getbits(audio->astream, 4);
571 audblk->deltba[i][j] = mpeg3bits_getbits(audio->astream, 3);
572 }
573 }
574 }
575 }
576
577/* Check to see if there's any dummy info to get */
578 if((audblk->skiple = mpeg3bits_getbits(audio->astream, 1)))
579 {
580 unsigned int skip_data;
581 audblk->skipl = mpeg3bits_getbits(audio->astream, 9);
582 for(i = 0; i < audblk->skipl ; i++)
583 {
584 skip_data = mpeg3bits_getbits(audio->astream, 8);
585 }
586 }
587
588 return mpeg3bits_error(audio->astream);
589}
590
591
592/* This routine simply does stereo rematrixing for the 2 channel
593 * stereo mode */
594int mpeg3audio_ac3_rematrix(mpeg3_ac3audblk_t *audblk,
595 mpeg3ac3_stream_samples_t samples)
596{
597 int num_bands;
598 int start;
599 int end;
600 int i, j;
601 mpeg3_real_t left, right;
602
603 if(audblk->cplinu || audblk->cplbegf > 2)
604 num_bands = 4;
605 else if (audblk->cplbegf > 0)
606 num_bands = 3;
607 else
608 num_bands = 2;
609
610 for(i = 0; i < num_bands; i++)
611 {
612 if(!audblk->rematflg[i])
613 continue;
614
615 start = mpeg3_rematrix_band[i].start;
616 end = mpeg3_min(mpeg3_rematrix_band[i].end, 12 * audblk->cplbegf + 36);
617
618 for(j = start; j < end; j++)
619 {
620 left = samples[0][j] + samples[1][j];
621 right = samples[0][j] - samples[1][j];
622 samples[0][j] = left;
623 samples[1][j] = right;
624 }
625 }
626 return 0;
627}
628
629
630int mpeg3audio_ac3_reset_frame(mpeg3audio_t *audio)
631{
632 memset(&audio->ac3_bit_allocation, 0, sizeof(mpeg3_ac3_bitallocation_t));
633 memset(&audio->ac3_mantissa, 0, sizeof(mpeg3_ac3_mantissa_t));
634 memset(&audio->ac3_audblk, 0, sizeof(mpeg3_ac3audblk_t));
635
636 return 0;
637}
638
639int mpeg3audio_do_ac3(mpeg3audio_t *audio)
640{
641 int result = 0, i;
642
643/* Reset the coefficients and exponents */
644 mpeg3audio_ac3_reset_frame(audio);
645
646 for(i = 0; i < 6 && !result; i++)
647 {
648 memset(audio->ac3_samples, 0, sizeof(mpeg3_real_t) * 256 * (audio->ac3_bsi.nfchans + audio->ac3_bsi.lfeon));
649/* Extract most of the audblk info from the bitstream
650 * (minus the mantissas */
651 result |= mpeg3audio_read_ac3_audblk(audio);
652
653/* Take the differential exponent data and turn it into
654 * absolute exponents */
655 if(!result) result |= mpeg3audio_ac3_exponent_unpack(audio,
656 &(audio->ac3_bsi),
657 &(audio->ac3_audblk));
658
659/* Figure out how many bits per mantissa */
660 if(!result) result |= mpeg3audio_ac3_bit_allocate(audio,
661 audio->sampling_frequency_code,
662 &(audio->ac3_bsi),
663 &(audio->ac3_audblk));
664
665/* Extract the mantissas from the data stream */
666 if(!result) result |= mpeg3audio_ac3_coeff_unpack(audio,
667 &(audio->ac3_bsi),
668 &(audio->ac3_audblk),
669 audio->ac3_samples);
670
671 if(audio->ac3_bsi.acmod == 0x2)
672 if(!result) result |= mpeg3audio_ac3_rematrix(&(audio->ac3_audblk),
673 audio->ac3_samples);
674
675/* Convert the frequency data into time samples */
676 if(!result) result |= mpeg3audio_ac3_imdct(audio,
677 &(audio->ac3_bsi),
678 &(audio->ac3_audblk),
679 audio->ac3_samples);
680
681 if(audio->pcm_point / audio->channels >= audio->pcm_allocated - MPEG3AUDIO_PADDING * audio->channels)
682 {
683/* Need more room */
684 mpeg3audio_replace_buffer(audio, audio->pcm_allocated + MPEG3AUDIO_PADDING * audio->channels);
685 }
686 }
687
688 mpeg3bits_use_demuxer(audio->astream);
689
690 return result;
691}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef AC3_H
21#define AC3_H
22
23#include "mpeg3real.h"
24
25#define MAX_AC3_FRAMESIZE 1920 * 2 + 512
26
27extern int mpeg3_ac3_samplerates[3];
28
29/* Exponent strategy constants */
30#define MPEG3_EXP_REUSE (0)
31#define MPEG3_EXP_D15 (1)
32#define MPEG3_EXP_D25 (2)
33#define MPEG3_EXP_D45 (3)
34
35/* Delta bit allocation constants */
36#define DELTA_BIT_REUSE (0)
37#define DELTA_BIT_NEW (1)
38#define DELTA_BIT_NONE (2)
39#define DELTA_BIT_RESERVED (3)
40
41
42typedef mpeg3_real_t mpeg3ac3_stream_samples_t[6][256];
43
44typedef struct
45{
46/* Bit stream identification == 0x8 */
47 int bsid;
48/* Bit stream mode */
49 int bsmod;
50/* Audio coding mode */
51 int acmod;
52/* If we're using the centre channel then */
53/* centre mix level */
54 int cmixlev;
55/* If we're using the surround channel then */
56/* surround mix level */
57 int surmixlev;
58/* If we're in 2/0 mode then */
59/* Dolby surround mix level - NOT USED - */
60 int dsurmod;
61/* Low frequency effects on */
62 int lfeon;
63/* Dialogue Normalization level */
64 int dialnorm;
65/* Compression exists */
66 int compre;
67/* Compression level */
68 int compr;
69/* Language code exists */
70 int langcode;
71/* Language code */
72 int langcod;
73/* Audio production info exists*/
74 unsigned int audprodie;
75 int mixlevel;
76 int roomtyp;
77/* If we're in dual mono mode (acmod == 0) then extra stuff */
78 int dialnorm2;
79 int compr2e;
80 int compr2;
81 int langcod2e;
82 int langcod2;
83 int audprodi2e;
84 int mixlevel2;
85 int roomtyp2;
86/* Copyright bit */
87 int copyrightb;
88/* Original bit */
89 int origbs;
90/* Timecode 1 exists */
91 int timecod1e;
92/* Timecode 1 */
93 unsigned int timecod1;
94/* Timecode 2 exists */
95 int timecod2e;
96/* Timecode 2 */
97 unsigned int timecod2;
98/* Additional bit stream info exists */
99 int addbsie;
100/* Additional bit stream length - 1 (in bytes) */
101 int addbsil;
102/* Additional bit stream information (max 64 bytes) */
103 unsigned char addbsi[64];
104
105/* Information not in the AC-3 bitstream, but derived */
106/* Number of channels (excluding LFE)
107 * Derived from acmod */
108 int nfchans;
109} mpeg3_ac3bsi_t;
110
111typedef struct
112{
113/* block switch bit indexed by channel num */
114 unsigned short blksw[5];
115/* dither enable bit indexed by channel num */
116 unsigned short dithflag[5];
117/* dynamic range gain exists */
118 int dynrnge;
119/* dynamic range gain */
120 int dynrng;
121/* if acmod==0 then */
122/* dynamic range 2 gain exists */
123 int dynrng2e;
124/* dynamic range 2 gain */
125 int dynrng2;
126/* coupling strategy exists */
127 int cplstre;
128/* coupling in use */
129 int cplinu;
130/* channel coupled */
131 unsigned short chincpl[5];
132/* if acmod==2 then */
133/* Phase flags in use */
134 int phsflginu;
135/* coupling begin frequency code */
136 int cplbegf;
137/* coupling end frequency code */
138 int cplendf;
139/* coupling band structure bits */
140 unsigned short cplbndstrc[18];
141/* Do coupling co-ords exist for this channel? */
142 unsigned short cplcoe[5];
143/* Master coupling co-ordinate */
144 unsigned short mstrcplco[5];
145/* Per coupling band coupling co-ordinates */
146 unsigned short cplcoexp[5][18];
147 unsigned short cplcomant[5][18];
148/* Phase flags for dual mono */
149 unsigned short phsflg[18];
150/* Is there a rematrixing strategy */
151 unsigned int rematstr;
152/* Rematrixing bits */
153 unsigned short rematflg[4];
154/* Coupling exponent strategy */
155 int cplexpstr;
156/* Exponent strategy for full bandwidth channels */
157 unsigned short chexpstr[5];
158/* Exponent strategy for lfe channel */
159 int lfeexpstr;
160/* Channel bandwidth for independent channels */
161 unsigned short chbwcod[5];
162/* The absolute coupling exponent */
163 int cplabsexp;
164/* Coupling channel exponents (D15 mode gives 18 * 12 /3 encoded exponents */
165 unsigned short cplexps[18 * 12 / 3];
166/* fbw channel exponents */
167 unsigned short exps[5][252 / 3];
168/* channel gain range */
169 unsigned short gainrng[5];
170/* low frequency exponents */
171 unsigned short lfeexps[3];
172
173/* Bit allocation info */
174 int baie;
175/* Slow decay code */
176 int sdcycod;
177/* Fast decay code */
178 int fdcycod;
179/* Slow gain code */
180 int sgaincod;
181/* dB per bit code */
182 int dbpbcod;
183/* masking floor code */
184 int floorcod;
185
186/* SNR offset info */
187 int snroffste;
188/* coarse SNR offset */
189 int csnroffst;
190/* coupling fine SNR offset */
191 int cplfsnroffst;
192/* coupling fast gain code */
193 int cplfgaincod;
194/* fbw fine SNR offset */
195 unsigned short fsnroffst[5];
196/* fbw fast gain code */
197 unsigned short fgaincod[5];
198/* lfe fine SNR offset */
199 int lfefsnroffst;
200/* lfe fast gain code */
201 int lfefgaincod;
202
203/* Coupling leak info */
204 int cplleake;
205/* coupling fast leak initialization */
206 int cplfleak;
207/* coupling slow leak initialization */
208 int cplsleak;
209
210/* delta bit allocation info */
211 int deltbaie;
212/* coupling delta bit allocation exists */
213 int cpldeltbae;
214/* fbw delta bit allocation exists */
215 unsigned short deltbae[5];
216/* number of cpl delta bit segments */
217 int cpldeltnseg;
218/* coupling delta bit allocation offset */
219 short cpldeltoffst[8];
220/* coupling delta bit allocation length */
221 short cpldeltlen[8];
222/* coupling delta bit allocation length */
223 short cpldeltba[8];
224/* number of delta bit segments */
225 unsigned short deltnseg[5];
226/* fbw delta bit allocation offset */
227 short deltoffst[5][8];
228/* fbw delta bit allocation length */
229 short deltlen[5][8];
230/* fbw delta bit allocation length */
231 short deltba[5][8];
232
233/* skip length exists */
234 int skiple;
235/* skip length */
236 int skipl;
237
238/* channel mantissas */
239 short chmant[5][256];
240
241/* coupling mantissas */
242 unsigned short cplmant[256];
243
244/* coupling mantissas */
245 unsigned short lfemant[7];
246
247/* -- Information not in the bitstream, but derived thereof -- */
248
249/* Number of coupling sub-bands */
250 int ncplsubnd;
251
252/* Number of combined coupling sub-bands
253 * Derived from ncplsubnd and cplbndstrc */
254 int ncplbnd;
255
256/* Number of exponent groups by channel
257 * Derived from strmant, endmant */
258 int nchgrps[5];
259
260/* Number of coupling exponent groups
261 * Derived from cplbegf, cplendf, cplexpstr */
262 int ncplgrps;
263
264/* End mantissa numbers of fbw channels */
265 unsigned short endmant[5];
266
267/* Start and end mantissa numbers for the coupling channel */
268 int cplstrtmant;
269 int cplendmant;
270
271/* Decoded exponent info */
272 unsigned short fbw_exp[5][256];
273 unsigned short cpl_exp[256];
274 unsigned short lfe_exp[7];
275
276/* Bit allocation pointer results */
277 short fbw_bap[5][256];
278/*FIXME figure out exactly how many entries there should be (253-37?) */
279 short cpl_bap[256];
280 short lfe_bap[7];
281} mpeg3_ac3audblk_t;
282
283/* Bit allocation data */
284typedef struct
285{
286 int sdecay;
287 int fdecay;
288 int sgain;
289 int dbknee;
290 int floor;
291 short psd[256];
292 short bndpsd[256];
293 short excite[256];
294 short mask[256];
295} mpeg3_ac3_bitallocation_t;
296
297/* Mantissa data */
298typedef struct
299{
300 unsigned short m_1[3];
301 unsigned short m_2[3];
302 unsigned short m_4[2];
303 unsigned short m_1_pointer;
304 unsigned short m_2_pointer;
305 unsigned short m_4_pointer;
306} mpeg3_ac3_mantissa_t;
307
308#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 @@
1/*
2 *
3 *Copyright (C) Aaron Holtzman - May 1999
4 *
5 *
6 * This file is part of libmpeg3
7 *
8 * libmpeg3 is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * libmpeg3 is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with GNU Make; see the file COPYING. If not, write to
20 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 */
23
24#include "mpeg3audio.h"
25#include "../libmpeg3.h"
26#include "../mpeg3protos.h"
27#include <string.h>
28#include <stdlib.h>
29
30/* Bit allocation tables */
31
32static short mpeg3_slowdec[] = { 0x0f, 0x11, 0x13, 0x15 };
33static short mpeg3_fastdec[] = { 0x3f, 0x53, 0x67, 0x7b };
34static short mpeg3_slowgain[] = { 0x540, 0x4d8, 0x478, 0x410 };
35static short mpeg3_dbpbtab[] = { 0x000, 0x700, 0x900, 0xb00 };
36
37static unsigned short mpeg3_floortab[] = { 0x2f0, 0x2b0, 0x270, 0x230, 0x1f0, 0x170, 0x0f0, 0xf800 };
38static short mpeg3_fastgain[] = { 0x080, 0x100, 0x180, 0x200, 0x280, 0x300, 0x380, 0x400 };
39
40
41static short mpeg3_bndtab[] =
42{
43 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
44 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
45 20, 21, 22, 23, 24, 25, 26, 27, 28, 31,
46 34, 37, 40, 43, 46, 49, 55, 61, 67, 73,
47 79, 85, 97, 109, 121, 133, 157, 181, 205, 229
48};
49
50static short mpeg3_bndsz[] =
51{
52 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
53 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
54 1, 1, 1, 1, 1, 1, 1, 1, 3, 3,
55 3, 3, 3, 3, 3, 6, 6, 6, 6, 6,
56 6, 12, 12, 12, 12, 24, 24, 24, 24, 24
57};
58
59static short mpeg3_masktab[] =
60{
61 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
62 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 28, 28, 29,
63 29, 29, 30, 30, 30, 31, 31, 31, 32, 32, 32, 33, 33, 33, 34, 34,
64 34, 35, 35, 35, 35, 35, 35, 36, 36, 36, 36, 36, 36, 37, 37, 37,
65 37, 37, 37, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 40,
66 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
67 41, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43,
68 43, 43, 43, 43, 43, 43, 43, 43, 43, 44, 44, 44, 44, 44, 44, 44,
69 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
70 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 46, 46,
71 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
72 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
73 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48,
74 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
75 48, 48, 48, 48, 48, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
76 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0
77};
78
79
80static short mpeg3_latab[] =
81{
82 0x0040, 0x003f, 0x003e, 0x003d, 0x003c, 0x003b, 0x003a, 0x0039,
83 0x0038, 0x0037, 0x0036, 0x0035, 0x0034, 0x0034, 0x0033, 0x0032,
84 0x0031, 0x0030, 0x002f, 0x002f, 0x002e, 0x002d, 0x002c, 0x002c,
85 0x002b, 0x002a, 0x0029, 0x0029, 0x0028, 0x0027, 0x0026, 0x0026,
86 0x0025, 0x0024, 0x0024, 0x0023, 0x0023, 0x0022, 0x0021, 0x0021,
87 0x0020, 0x0020, 0x001f, 0x001e, 0x001e, 0x001d, 0x001d, 0x001c,
88 0x001c, 0x001b, 0x001b, 0x001a, 0x001a, 0x0019, 0x0019, 0x0018,
89 0x0018, 0x0017, 0x0017, 0x0016, 0x0016, 0x0015, 0x0015, 0x0015,
90 0x0014, 0x0014, 0x0013, 0x0013, 0x0013, 0x0012, 0x0012, 0x0012,
91 0x0011, 0x0011, 0x0011, 0x0010, 0x0010, 0x0010, 0x000f, 0x000f,
92 0x000f, 0x000e, 0x000e, 0x000e, 0x000d, 0x000d, 0x000d, 0x000d,
93 0x000c, 0x000c, 0x000c, 0x000c, 0x000b, 0x000b, 0x000b, 0x000b,
94 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x0009, 0x0009, 0x0009,
95 0x0009, 0x0009, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
96 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0006, 0x0006,
97 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0005, 0x0005,
98 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0004, 0x0004,
99 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
100 0x0004, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003,
101 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0002,
102 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
103 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
104 0x0002, 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
105 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
106 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
107 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
108 0x0001, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
109 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
110 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
111 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
112 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
113 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
114 0x0000, 0x0000, 0x0000, 0x0000
115};
116
117static short mpeg3_hth[][50] =
118{
119 {
120 0x04d0, 0x04d0, 0x0440, 0x0400, 0x03e0, 0x03c0, 0x03b0, 0x03b0,
121 0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x0390, 0x0390, 0x0390,
122 0x0380, 0x0380, 0x0370, 0x0370, 0x0360, 0x0360, 0x0350, 0x0350,
123 0x0340, 0x0340, 0x0330, 0x0320, 0x0310, 0x0300, 0x02f0, 0x02f0,
124 0x02f0, 0x02f0, 0x0300, 0x0310, 0x0340, 0x0390, 0x03e0, 0x0420,
125 0x0460, 0x0490, 0x04a0, 0x0460, 0x0440, 0x0440, 0x0520, 0x0800,
126 0x0840, 0x0840
127 },
128
129 {
130 0x04f0, 0x04f0, 0x0460, 0x0410, 0x03e0, 0x03d0, 0x03c0, 0x03b0,
131 0x03b0, 0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x0390, 0x0390,
132 0x0390, 0x0380, 0x0380, 0x0380, 0x0370, 0x0370, 0x0360, 0x0360,
133 0x0350, 0x0350, 0x0340, 0x0340, 0x0320, 0x0310, 0x0300, 0x02f0,
134 0x02f0, 0x02f0, 0x02f0, 0x0300, 0x0320, 0x0350, 0x0390, 0x03e0,
135 0x0420, 0x0450, 0x04a0, 0x0490, 0x0460, 0x0440, 0x0480, 0x0630,
136 0x0840, 0x0840
137 },
138
139 {
140 0x0580, 0x0580, 0x04b0, 0x0450, 0x0420, 0x03f0, 0x03e0, 0x03d0,
141 0x03c0, 0x03b0, 0x03b0, 0x03b0, 0x03a0, 0x03a0, 0x03a0, 0x03a0,
142 0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x0390, 0x0390, 0x0390, 0x0390,
143 0x0380, 0x0380, 0x0380, 0x0370, 0x0360, 0x0350, 0x0340, 0x0330,
144 0x0320, 0x0310, 0x0300, 0x02f0, 0x02f0, 0x02f0, 0x0300, 0x0310,
145 0x0330, 0x0350, 0x03c0, 0x0410, 0x0470, 0x04a0, 0x0460, 0x0440,
146 0x0450, 0x04e0
147 }
148};
149
150
151static short mpeg3_baptab[] =
152{
153 0, 1, 1, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6,
154 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 10,
155 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14,
156 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15
157};
158
159
160inline int logadd(int a, int b)
161{
162 int c;
163 int address;
164
165 c = a - b;
166 address = mpeg3_min((abs(c) >> 1), 255);
167
168 if(c >= 0)
169 return(a + mpeg3_latab[address]);
170 else
171 return(b + mpeg3_latab[address]);
172}
173
174
175int mpeg3audio_ac3_calc_lowcomp(int a, int b0, int b1, int bin)
176{
177 if(bin < 7)
178 {
179 if((b0 + 256) == b1)
180 a = 384;
181 else
182 if(b0 > b1)
183 a = mpeg3_max(0, a - 64);
184 }
185 else if(bin < 20)
186 {
187 if((b0 + 256) == b1)
188 a = 320;
189 else if(b0 > b1)
190 a = mpeg3_max(0, a - 64) ;
191 }
192 else
193 a = mpeg3_max(0, a - 128);
194
195 return(a);
196}
197
198void mpeg3audio_ac3_ba_compute_psd(int start,
199 int end,
200 unsigned short exps[],
201 short psd[],
202 short bndpsd[])
203{
204 int bin,i,j,k;
205 int lastbin = 0;
206
207/* Map the exponents into dBs */
208 for (bin = start; bin < end; bin++)
209 {
210 psd[bin] = (3072 - (exps[bin] << 7));
211 }
212
213/* Integrate the psd function over each bit allocation band */
214 j = start;
215 k = mpeg3_masktab[start];
216
217 do
218 {
219 lastbin = mpeg3_min(mpeg3_bndtab[k] + mpeg3_bndsz[k], end);
220 bndpsd[k] = psd[j];
221 j++;
222
223 for(i = j; i < lastbin; i++)
224 {
225 bndpsd[k] = logadd(bndpsd[k], psd[j]);
226 j++;
227 }
228
229 k++;
230 }while(end > lastbin);
231}
232
233void mpeg3audio_ac3_ba_compute_excitation(mpeg3audio_t *audio,
234 int start,
235 int end,
236 int fgain,
237 int fastleak,
238 int slowleak,
239 int is_lfe,
240 short bndpsd[],
241 short excite[])
242{
243 int bin;
244 int bndstrt;
245 int bndend;
246 int lowcomp = 0;
247 int begin = 0;
248
249/* Compute excitation function */
250 bndstrt = mpeg3_masktab[start];
251 bndend = mpeg3_masktab[end - 1] + 1;
252
253 if(bndstrt == 0) /* For fbw and lfe channels */
254 {
255 lowcomp = mpeg3audio_ac3_calc_lowcomp(lowcomp, bndpsd[0], bndpsd[1], 0);
256 excite[0] = bndpsd[0] - fgain - lowcomp;
257 lowcomp = mpeg3audio_ac3_calc_lowcomp(lowcomp, bndpsd[1], bndpsd[2], 1);
258 excite[1] = bndpsd[1] - fgain - lowcomp;
259 begin = 7 ;
260
261/* Note: Do not call mpeg3audio_ac3_calc_lowcomp() for the last band of the lfe channel, (bin = 6) */
262 for (bin = 2; bin < 7; bin++)
263 {
264 if(!(is_lfe && (bin == 6)))
265 lowcomp = mpeg3audio_ac3_calc_lowcomp(lowcomp, bndpsd[bin], bndpsd[bin+1], bin);
266 fastleak = bndpsd[bin] - fgain;
267 slowleak = bndpsd[bin] - audio->ac3_bit_allocation.sgain;
268 excite[bin] = fastleak - lowcomp;
269
270 if(!(is_lfe && (bin == 6)))
271 {
272 if(bndpsd[bin] <= bndpsd[bin+1])
273 {
274 begin = bin + 1 ;
275 break;
276 }
277 }
278 }
279
280 for (bin = begin; bin < mpeg3_min(bndend, 22); bin++)
281 {
282 if (!(is_lfe && (bin == 6)))
283 lowcomp = mpeg3audio_ac3_calc_lowcomp(lowcomp, bndpsd[bin], bndpsd[bin+1], bin);
284 fastleak -= audio->ac3_bit_allocation.fdecay;
285 fastleak = mpeg3_max(fastleak, bndpsd[bin] - fgain);
286 slowleak -= audio->ac3_bit_allocation.sdecay;
287 slowleak = mpeg3_max(slowleak, bndpsd[bin] - audio->ac3_bit_allocation.sgain);
288 excite[bin] = mpeg3_max(fastleak - lowcomp, slowleak);
289 }
290 begin = 22;
291 }
292 else /* For coupling channel */
293 {
294 begin = bndstrt;
295 }
296
297 for (bin = begin; bin < bndend; bin++)
298 {
299 fastleak -= audio->ac3_bit_allocation.fdecay;
300 fastleak = mpeg3_max(fastleak, bndpsd[bin] - fgain);
301 slowleak -= audio->ac3_bit_allocation.sdecay;
302 slowleak = mpeg3_max(slowleak, bndpsd[bin] - audio->ac3_bit_allocation.sgain);
303 excite[bin] = mpeg3_max(fastleak, slowleak) ;
304 }
305}
306
307void mpeg3audio_ac3_ba_compute_mask(mpeg3audio_t *audio,
308 int start,
309 int end,
310 int fscod,
311 int deltbae,
312 int deltnseg,
313 short deltoffst[],
314 short deltba[],
315 short deltlen[],
316 short excite[],
317 short mask[])
318{
319 int bin, k;
320 int bndstrt;
321 int bndend;
322 int delta;
323
324 bndstrt = mpeg3_masktab[start];
325 bndend = mpeg3_masktab[end - 1] + 1;
326
327/* Compute the masking curve */
328
329 for (bin = bndstrt; bin < bndend; bin++)
330 {
331 if (audio->ac3_bit_allocation.bndpsd[bin] < audio->ac3_bit_allocation.dbknee)
332 {
333 excite[bin] += ((audio->ac3_bit_allocation.dbknee - audio->ac3_bit_allocation.bndpsd[bin]) >> 2);
334 }
335 mask[bin] = mpeg3_max(excite[bin], mpeg3_hth[fscod][bin]);
336 }
337
338/* Perform delta bit modulation if necessary */
339 if ((deltbae == DELTA_BIT_REUSE) || (deltbae == DELTA_BIT_NEW))
340 {
341 int band = 0;
342 int seg = 0;
343
344 for (seg = 0; seg < deltnseg + 1; seg++)
345 {
346 band += deltoffst[seg];
347 if (deltba[seg] >= 4)
348 {
349 delta = (deltba[seg] - 3) << 7;
350 }
351 else
352 {
353 delta = (deltba[seg] - 4) << 7;
354 }
355
356 for (k = 0; k < deltlen[seg]; k++)
357 {
358 mask[band] += delta;
359 band++;
360 }
361 }
362 }
363}
364
365void mpeg3audio_ac3_ba_compute_bap(mpeg3audio_t *audio,
366 int start,
367 int end,
368 int snroffset,
369 short psd[],
370 short mask[],
371 short bap[])
372{
373 int i, j, k;
374 short lastbin = 0;
375 short address = 0;
376
377/* Compute the bit allocation pointer for each bin */
378 i = start;
379 j = mpeg3_masktab[start];
380
381 do
382 {
383 lastbin = mpeg3_min(mpeg3_bndtab[j] + mpeg3_bndsz[j], end);
384 mask[j] -= snroffset;
385 mask[j] -= audio->ac3_bit_allocation.floor;
386
387 if(mask[j] < 0)
388 mask[j] = 0;
389
390 mask[j] &= 0x1fe0;
391 mask[j] += audio->ac3_bit_allocation.floor;
392 for(k = i; k < lastbin; k++)
393 {
394 address = (psd[i] - mask[j]) >> 5;
395 address = mpeg3_min(63, mpeg3_max(0, address));
396 bap[i] = mpeg3_baptab[address];
397 i++;
398 }
399 j++;
400 }while (end > lastbin);
401}
402
403int mpeg3audio_ac3_bit_allocate(mpeg3audio_t *audio,
404 unsigned int fscod,
405 mpeg3_ac3bsi_t *bsi,
406 mpeg3_ac3audblk_t *audblk)
407{
408 int result = 0;
409 int i;
410 int fgain;
411 int snroffset;
412 int start;
413 int end;
414 int fastleak;
415 int slowleak;
416
417/*printf("mpeg3audio_ac3_bit_allocate %d %d %d %d %d\n", audblk->sdcycod, audblk->fdcycod, audblk->sgaincod, audblk->dbpbcod, audblk->floorcod); */
418/* Only perform bit_allocation if the exponents have changed or we
419 * have new sideband information */
420 if(audblk->chexpstr[0] == 0 && audblk->chexpstr[1] == 0 &&
421 audblk->chexpstr[2] == 0 && audblk->chexpstr[3] == 0 &&
422 audblk->chexpstr[4] == 0 && audblk->cplexpstr == 0 &&
423 audblk->lfeexpstr == 0 && audblk->baie == 0 &&
424 audblk->snroffste == 0 && audblk->deltbaie == 0)
425 return 0;
426
427/* Do some setup before we do the bit alloc */
428 audio->ac3_bit_allocation.sdecay = mpeg3_slowdec[audblk->sdcycod];
429 audio->ac3_bit_allocation.fdecay = mpeg3_fastdec[audblk->fdcycod];
430 audio->ac3_bit_allocation.sgain = mpeg3_slowgain[audblk->sgaincod];
431 audio->ac3_bit_allocation.dbknee = mpeg3_dbpbtab[audblk->dbpbcod];
432 audio->ac3_bit_allocation.floor = mpeg3_floortab[audblk->floorcod];
433
434/* if all the SNR offset constants are zero then the whole block is zero */
435 if(!audblk->csnroffst && !audblk->fsnroffst[0] &&
436 !audblk->fsnroffst[1] && !audblk->fsnroffst[2] &&
437 !audblk->fsnroffst[3] && !audblk->fsnroffst[4] &&
438 !audblk->cplfsnroffst && !audblk->lfefsnroffst)
439 {
440 memset(audblk->fbw_bap, 0, sizeof(short) * 256 * 5);
441 memset(audblk->cpl_bap, 0, sizeof(short) * 256);
442 memset(audblk->lfe_bap, 0, sizeof(short) * 7);
443 return 0;
444 }
445
446 for(i = 0; i < bsi->nfchans; i++)
447 {
448 start = 0;
449 end = audblk->endmant[i];
450 fgain = mpeg3_fastgain[audblk->fgaincod[i]];
451 snroffset = (((audblk->csnroffst - 15) << 4) + audblk->fsnroffst[i]) << 2 ;
452 fastleak = 0;
453 slowleak = 0;
454
455 mpeg3audio_ac3_ba_compute_psd(start,
456 end,
457 audblk->fbw_exp[i],
458 audio->ac3_bit_allocation.psd,
459 audio->ac3_bit_allocation.bndpsd);
460
461 mpeg3audio_ac3_ba_compute_excitation(audio,
462 start,
463 end ,
464 fgain,
465 fastleak,
466 slowleak,
467 0,
468 audio->ac3_bit_allocation.bndpsd,
469 audio->ac3_bit_allocation.excite);
470
471 mpeg3audio_ac3_ba_compute_mask(audio,
472 start,
473 end,
474 fscod,
475 audblk->deltbae[i],
476 audblk->deltnseg[i],
477 audblk->deltoffst[i],
478 audblk->deltba[i],
479 audblk->deltlen[i],
480 audio->ac3_bit_allocation.excite,
481 audio->ac3_bit_allocation.mask);
482
483 mpeg3audio_ac3_ba_compute_bap(audio,
484 start,
485 end,
486 snroffset,
487 audio->ac3_bit_allocation.psd,
488 audio->ac3_bit_allocation.mask,
489 audblk->fbw_bap[i]);
490 }
491
492 if(audblk->cplinu)
493 {
494 start = audblk->cplstrtmant;
495 end = audblk->cplendmant;
496 fgain = mpeg3_fastgain[audblk->cplfgaincod];
497 snroffset = (((audblk->csnroffst - 15) << 4) + audblk->cplfsnroffst) << 2 ;
498 fastleak = (audblk->cplfleak << 8) + 768;
499 slowleak = (audblk->cplsleak << 8) + 768;
500
501 mpeg3audio_ac3_ba_compute_psd(start,
502 end,
503 audblk->cpl_exp,
504 audio->ac3_bit_allocation.psd,
505 audio->ac3_bit_allocation.bndpsd);
506
507 mpeg3audio_ac3_ba_compute_excitation(audio,
508 start,
509 end ,
510 fgain,
511 fastleak,
512 slowleak,
513 0,
514 audio->ac3_bit_allocation.bndpsd,
515 audio->ac3_bit_allocation.excite);
516
517 mpeg3audio_ac3_ba_compute_mask(audio,
518 start,
519 end,
520 fscod,
521 audblk->cpldeltbae,
522 audblk->cpldeltnseg,
523 audblk->cpldeltoffst,
524 audblk->cpldeltba,
525 audblk->cpldeltlen,
526 audio->ac3_bit_allocation.excite,
527 audio->ac3_bit_allocation.mask);
528
529 mpeg3audio_ac3_ba_compute_bap(audio,
530 start,
531 end,
532 snroffset,
533 audio->ac3_bit_allocation.psd,
534 audio->ac3_bit_allocation.mask,
535 audblk->cpl_bap);
536 }
537
538 if(bsi->lfeon)
539 {
540 start = 0;
541 end = 7;
542 fgain = mpeg3_fastgain[audblk->lfefgaincod];
543 snroffset = (((audblk->csnroffst - 15) << 4) + audblk->lfefsnroffst) << 2 ;
544 fastleak = 0;
545 slowleak = 0;
546
547 mpeg3audio_ac3_ba_compute_psd(start,
548 end,
549 audblk->lfe_exp,
550 audio->ac3_bit_allocation.psd,
551 audio->ac3_bit_allocation.bndpsd);
552
553 mpeg3audio_ac3_ba_compute_excitation(audio,
554 start,
555 end ,
556 fgain,
557 fastleak,
558 slowleak,
559 1,
560 audio->ac3_bit_allocation.bndpsd,
561 audio->ac3_bit_allocation.excite);
562
563/* Perform no delta bit allocation for lfe */
564 mpeg3audio_ac3_ba_compute_mask(audio,
565 start,
566 end,
567 fscod,
568 2,
569 0,
570 0,
571 0,
572 0,
573 audio->ac3_bit_allocation.excite,
574 audio->ac3_bit_allocation.mask);
575
576 mpeg3audio_ac3_ba_compute_bap(audio,
577 start,
578 end,
579 snroffset,
580 audio->ac3_bit_allocation.psd,
581 audio->ac3_bit_allocation.mask,
582 audblk->lfe_bap);
583 }
584
585 return result;
586}
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 @@
1/*
2 *
3 * This file is part of libmpeg3
4 *
5 * libmpeg3 is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * libmpeg3 is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with GNU Make; see the file COPYING. If not, write to
17 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18 *
19 */
20
21/*
22 * Discrete Cosine Tansform (DCT) for subband synthesis
23 * optimized for machines with no auto-increment.
24 * The performance is highly compiler dependend. Maybe
25 * the dct64.c version for 'normal' processor may be faster
26 * even for Intel processors.
27 */
28
29#include "mpeg3audio.h"
30#include "../libmpeg3.h"
31#include "../mpeg3protos.h"
32#include "tables.h"
33
34#include <math.h>
35
36int mpeg3audio_dct64_1(mpeg3_real_t *out0, mpeg3_real_t *out1, mpeg3_real_t *b1, mpeg3_real_t *b2, mpeg3_real_t *samples)
37{
38 register mpeg3_real_t *costab = mpeg3_pnts[0];
39
40 b1[0x00] = samples[0x00] + samples[0x1F];
41 b1[0x01] = samples[0x01] + samples[0x1E];
42 b1[0x1F] = (samples[0x00] - samples[0x1F]) * costab[0x0];
43 b1[0x1E] = (samples[0x01] - samples[0x1E]) * costab[0x1];
44
45 b1[0x02] = samples[0x02] + samples[0x1D];
46 b1[0x03] = samples[0x03] + samples[0x1C];
47 b1[0x1D] = (samples[0x02] - samples[0x1D]) * costab[0x2];
48 b1[0x1C] = (samples[0x03] - samples[0x1C]) * costab[0x3];
49
50 b1[0x04] = samples[0x04] + samples[0x1B];
51 b1[0x05] = samples[0x05] + samples[0x1A];
52 b1[0x1B] = (samples[0x04] - samples[0x1B]) * costab[0x4];
53 b1[0x1A] = (samples[0x05] - samples[0x1A]) * costab[0x5];
54
55 b1[0x06] = samples[0x06] + samples[0x19];
56 b1[0x07] = samples[0x07] + samples[0x18];
57 b1[0x19] = (samples[0x06] - samples[0x19]) * costab[0x6];
58 b1[0x18] = (samples[0x07] - samples[0x18]) * costab[0x7];
59
60 b1[0x08] = samples[0x08] + samples[0x17];
61 b1[0x09] = samples[0x09] + samples[0x16];
62 b1[0x17] = (samples[0x08] - samples[0x17]) * costab[0x8];
63 b1[0x16] = (samples[0x09] - samples[0x16]) * costab[0x9];
64
65 b1[0x0A] = samples[0x0A] + samples[0x15];
66 b1[0x0B] = samples[0x0B] + samples[0x14];
67 b1[0x15] = (samples[0x0A] - samples[0x15]) * costab[0xA];
68 b1[0x14] = (samples[0x0B] - samples[0x14]) * costab[0xB];
69
70 b1[0x0C] = samples[0x0C] + samples[0x13];
71 b1[0x0D] = samples[0x0D] + samples[0x12];
72 b1[0x13] = (samples[0x0C] - samples[0x13]) * costab[0xC];
73 b1[0x12] = (samples[0x0D] - samples[0x12]) * costab[0xD];
74
75 b1[0x0E] = samples[0x0E] + samples[0x11];
76 b1[0x0F] = samples[0x0F] + samples[0x10];
77 b1[0x11] = (samples[0x0E] - samples[0x11]) * costab[0xE];
78 b1[0x10] = (samples[0x0F] - samples[0x10]) * costab[0xF];
79
80 costab = mpeg3_pnts[1];
81
82 b2[0x00] = b1[0x00] + b1[0x0F];
83 b2[0x01] = b1[0x01] + b1[0x0E];
84 b2[0x0F] = (b1[0x00] - b1[0x0F]) * costab[0];
85 b2[0x0E] = (b1[0x01] - b1[0x0E]) * costab[1];
86
87 b2[0x02] = b1[0x02] + b1[0x0D];
88 b2[0x03] = b1[0x03] + b1[0x0C];
89 b2[0x0D] = (b1[0x02] - b1[0x0D]) * costab[2];
90 b2[0x0C] = (b1[0x03] - b1[0x0C]) * costab[3];
91
92 b2[0x04] = b1[0x04] + b1[0x0B];
93 b2[0x05] = b1[0x05] + b1[0x0A];
94 b2[0x0B] = (b1[0x04] - b1[0x0B]) * costab[4];
95 b2[0x0A] = (b1[0x05] - b1[0x0A]) * costab[5];
96
97 b2[0x06] = b1[0x06] + b1[0x09];
98 b2[0x07] = b1[0x07] + b1[0x08];
99 b2[0x09] = (b1[0x06] - b1[0x09]) * costab[6];
100 b2[0x08] = (b1[0x07] - b1[0x08]) * costab[7];
101
102 /* */
103
104 b2[0x10] = b1[0x10] + b1[0x1F];
105 b2[0x11] = b1[0x11] + b1[0x1E];
106 b2[0x1F] = (b1[0x1F] - b1[0x10]) * costab[0];
107 b2[0x1E] = (b1[0x1E] - b1[0x11]) * costab[1];
108
109 b2[0x12] = b1[0x12] + b1[0x1D];
110 b2[0x13] = b1[0x13] + b1[0x1C];
111 b2[0x1D] = (b1[0x1D] - b1[0x12]) * costab[2];
112 b2[0x1C] = (b1[0x1C] - b1[0x13]) * costab[3];
113
114 b2[0x14] = b1[0x14] + b1[0x1B];
115 b2[0x15] = b1[0x15] + b1[0x1A];
116 b2[0x1B] = (b1[0x1B] - b1[0x14]) * costab[4];
117 b2[0x1A] = (b1[0x1A] - b1[0x15]) * costab[5];
118
119 b2[0x16] = b1[0x16] + b1[0x19];
120 b2[0x17] = b1[0x17] + b1[0x18];
121 b2[0x19] = (b1[0x19] - b1[0x16]) * costab[6];
122 b2[0x18] = (b1[0x18] - b1[0x17]) * costab[7];
123
124 costab = mpeg3_pnts[2];
125
126 b1[0x00] = b2[0x00] + b2[0x07];
127 b1[0x07] = (b2[0x00] - b2[0x07]) * costab[0];
128 b1[0x01] = b2[0x01] + b2[0x06];
129 b1[0x06] = (b2[0x01] - b2[0x06]) * costab[1];
130 b1[0x02] = b2[0x02] + b2[0x05];
131 b1[0x05] = (b2[0x02] - b2[0x05]) * costab[2];
132 b1[0x03] = b2[0x03] + b2[0x04];
133 b1[0x04] = (b2[0x03] - b2[0x04]) * costab[3];
134
135 b1[0x08] = b2[0x08] + b2[0x0F];
136 b1[0x0F] = (b2[0x0F] - b2[0x08]) * costab[0];
137 b1[0x09] = b2[0x09] + b2[0x0E];
138 b1[0x0E] = (b2[0x0E] - b2[0x09]) * costab[1];
139 b1[0x0A] = b2[0x0A] + b2[0x0D];
140 b1[0x0D] = (b2[0x0D] - b2[0x0A]) * costab[2];
141 b1[0x0B] = b2[0x0B] + b2[0x0C];
142 b1[0x0C] = (b2[0x0C] - b2[0x0B]) * costab[3];
143
144 b1[0x10] = b2[0x10] + b2[0x17];
145 b1[0x17] = (b2[0x10] - b2[0x17]) * costab[0];
146 b1[0x11] = b2[0x11] + b2[0x16];
147 b1[0x16] = (b2[0x11] - b2[0x16]) * costab[1];
148 b1[0x12] = b2[0x12] + b2[0x15];
149 b1[0x15] = (b2[0x12] - b2[0x15]) * costab[2];
150 b1[0x13] = b2[0x13] + b2[0x14];
151 b1[0x14] = (b2[0x13] - b2[0x14]) * costab[3];
152
153 b1[0x18] = b2[0x18] + b2[0x1F];
154 b1[0x1F] = (b2[0x1F] - b2[0x18]) * costab[0];
155 b1[0x19] = b2[0x19] + b2[0x1E];
156 b1[0x1E] = (b2[0x1E] - b2[0x19]) * costab[1];
157 b1[0x1A] = b2[0x1A] + b2[0x1D];
158 b1[0x1D] = (b2[0x1D] - b2[0x1A]) * costab[2];
159 b1[0x1B] = b2[0x1B] + b2[0x1C];
160 b1[0x1C] = (b2[0x1C] - b2[0x1B]) * costab[3];
161
162 {
163 register mpeg3_real_t const cos0 = mpeg3_pnts[3][0];
164 register mpeg3_real_t const cos1 = mpeg3_pnts[3][1];
165
166 b2[0x00] = b1[0x00] + b1[0x03];
167 b2[0x03] = (b1[0x00] - b1[0x03]) * cos0;
168 b2[0x01] = b1[0x01] + b1[0x02];
169 b2[0x02] = (b1[0x01] - b1[0x02]) * cos1;
170
171 b2[0x04] = b1[0x04] + b1[0x07];
172 b2[0x07] = (b1[0x07] - b1[0x04]) * cos0;
173 b2[0x05] = b1[0x05] + b1[0x06];
174 b2[0x06] = (b1[0x06] - b1[0x05]) * cos1;
175
176 b2[0x08] = b1[0x08] + b1[0x0B];
177 b2[0x0B] = (b1[0x08] - b1[0x0B]) * cos0;
178 b2[0x09] = b1[0x09] + b1[0x0A];
179 b2[0x0A] = (b1[0x09] - b1[0x0A]) * cos1;
180
181 b2[0x0C] = b1[0x0C] + b1[0x0F];
182 b2[0x0F] = (b1[0x0F] - b1[0x0C]) * cos0;
183 b2[0x0D] = b1[0x0D] + b1[0x0E];
184 b2[0x0E] = (b1[0x0E] - b1[0x0D]) * cos1;
185
186 b2[0x10] = b1[0x10] + b1[0x13];
187 b2[0x13] = (b1[0x10] - b1[0x13]) * cos0;
188 b2[0x11] = b1[0x11] + b1[0x12];
189 b2[0x12] = (b1[0x11] - b1[0x12]) * cos1;
190
191 b2[0x14] = b1[0x14] + b1[0x17];
192 b2[0x17] = (b1[0x17] - b1[0x14]) * cos0;
193 b2[0x15] = b1[0x15] + b1[0x16];
194 b2[0x16] = (b1[0x16] - b1[0x15]) * cos1;
195
196 b2[0x18] = b1[0x18] + b1[0x1B];
197 b2[0x1B] = (b1[0x18] - b1[0x1B]) * cos0;
198 b2[0x19] = b1[0x19] + b1[0x1A];
199 b2[0x1A] = (b1[0x19] - b1[0x1A]) * cos1;
200
201 b2[0x1C] = b1[0x1C] + b1[0x1F];
202 b2[0x1F] = (b1[0x1F] - b1[0x1C]) * cos0;
203 b2[0x1D] = b1[0x1D] + b1[0x1E];
204 b2[0x1E] = (b1[0x1E] - b1[0x1D]) * cos1;
205 }
206
207 {
208 register mpeg3_real_t const cos0 = mpeg3_pnts[4][0];
209
210 b1[0x00] = b2[0x00] + b2[0x01];
211 b1[0x01] = (b2[0x00] - b2[0x01]) * cos0;
212 b1[0x02] = b2[0x02] + b2[0x03];
213 b1[0x03] = (b2[0x03] - b2[0x02]) * cos0;
214 b1[0x02] += b1[0x03];
215
216 b1[0x04] = b2[0x04] + b2[0x05];
217 b1[0x05] = (b2[0x04] - b2[0x05]) * cos0;
218 b1[0x06] = b2[0x06] + b2[0x07];
219 b1[0x07] = (b2[0x07] - b2[0x06]) * cos0;
220 b1[0x06] += b1[0x07];
221 b1[0x04] += b1[0x06];
222 b1[0x06] += b1[0x05];
223 b1[0x05] += b1[0x07];
224
225 b1[0x08] = b2[0x08] + b2[0x09];
226 b1[0x09] = (b2[0x08] - b2[0x09]) * cos0;
227 b1[0x0A] = b2[0x0A] + b2[0x0B];
228 b1[0x0B] = (b2[0x0B] - b2[0x0A]) * cos0;
229 b1[0x0A] += b1[0x0B];
230
231 b1[0x0C] = b2[0x0C] + b2[0x0D];
232 b1[0x0D] = (b2[0x0C] - b2[0x0D]) * cos0;
233 b1[0x0E] = b2[0x0E] + b2[0x0F];
234 b1[0x0F] = (b2[0x0F] - b2[0x0E]) * cos0;
235 b1[0x0E] += b1[0x0F];
236 b1[0x0C] += b1[0x0E];
237 b1[0x0E] += b1[0x0D];
238 b1[0x0D] += b1[0x0F];
239
240 b1[0x10] = b2[0x10] + b2[0x11];
241 b1[0x11] = (b2[0x10] - b2[0x11]) * cos0;
242 b1[0x12] = b2[0x12] + b2[0x13];
243 b1[0x13] = (b2[0x13] - b2[0x12]) * cos0;
244 b1[0x12] += b1[0x13];
245
246 b1[0x14] = b2[0x14] + b2[0x15];
247 b1[0x15] = (b2[0x14] - b2[0x15]) * cos0;
248 b1[0x16] = b2[0x16] + b2[0x17];
249 b1[0x17] = (b2[0x17] - b2[0x16]) * cos0;
250 b1[0x16] += b1[0x17];
251 b1[0x14] += b1[0x16];
252 b1[0x16] += b1[0x15];
253 b1[0x15] += b1[0x17];
254
255 b1[0x18] = b2[0x18] + b2[0x19];
256 b1[0x19] = (b2[0x18] - b2[0x19]) * cos0;
257 b1[0x1A] = b2[0x1A] + b2[0x1B];
258 b1[0x1B] = (b2[0x1B] - b2[0x1A]) * cos0;
259 b1[0x1A] += b1[0x1B];
260
261 b1[0x1C] = b2[0x1C] + b2[0x1D];
262 b1[0x1D] = (b2[0x1C] - b2[0x1D]) * cos0;
263 b1[0x1E] = b2[0x1E] + b2[0x1F];
264 b1[0x1F] = (b2[0x1F] - b2[0x1E]) * cos0;
265 b1[0x1E] += b1[0x1F];
266 b1[0x1C] += b1[0x1E];
267 b1[0x1E] += b1[0x1D];
268 b1[0x1D] += b1[0x1F];
269 }
270
271 out0[0x10*16] = b1[0x00];
272 out0[0x10*12] = b1[0x04];
273 out0[0x10* 8] = b1[0x02];
274 out0[0x10* 4] = b1[0x06];
275 out0[0x10* 0] = b1[0x01];
276 out1[0x10* 0] = b1[0x01];
277 out1[0x10* 4] = b1[0x05];
278 out1[0x10* 8] = b1[0x03];
279 out1[0x10*12] = b1[0x07];
280
281 out0[0x10*14] = b1[0x08] + b1[0x0C];
282 out0[0x10*10] = b1[0x0C] + b1[0x0a];
283 out0[0x10* 6] = b1[0x0A] + b1[0x0E];
284 out0[0x10* 2] = b1[0x0E] + b1[0x09];
285 out1[0x10* 2] = b1[0x09] + b1[0x0D];
286 out1[0x10* 6] = b1[0x0D] + b1[0x0B];
287 out1[0x10*10] = b1[0x0B] + b1[0x0F];
288 out1[0x10*14] = b1[0x0F];
289
290 {
291 register mpeg3_real_t tmp;
292 tmp = b1[0x18] + b1[0x1C];
293 out0[0x10*15] = tmp + b1[0x10];
294 out0[0x10*13] = tmp + b1[0x14];
295 tmp = b1[0x1C] + b1[0x1A];
296 out0[0x10*11] = tmp + b1[0x14];
297 out0[0x10* 9] = tmp + b1[0x12];
298 tmp = b1[0x1A] + b1[0x1E];
299 out0[0x10* 7] = tmp + b1[0x12];
300 out0[0x10* 5] = tmp + b1[0x16];
301 tmp = b1[0x1E] + b1[0x19];
302 out0[0x10* 3] = tmp + b1[0x16];
303 out0[0x10* 1] = tmp + b1[0x11];
304 tmp = b1[0x19] + b1[0x1D];
305 out1[0x10* 1] = tmp + b1[0x11];
306 out1[0x10* 3] = tmp + b1[0x15];
307 tmp = b1[0x1D] + b1[0x1B];
308 out1[0x10* 5] = tmp + b1[0x15];
309 out1[0x10* 7] = tmp + b1[0x13];
310 tmp = b1[0x1B] + b1[0x1F];
311 out1[0x10* 9] = tmp + b1[0x13];
312 out1[0x10*11] = tmp + b1[0x17];
313 out1[0x10*13] = b1[0x17] + b1[0x1F];
314 out1[0x10*15] = b1[0x1F];
315 }
316 return 0;
317}
318
319/*
320 * the call via dct64 is a trick to force GCC to use
321 * (new) registers for the b1,b2 pointer to the bufs[xx] field
322 */
323int mpeg3audio_dct64(mpeg3_real_t *a, mpeg3_real_t *b, mpeg3_real_t *c)
324{
325 mpeg3_real_t bufs[0x40];
326 return mpeg3audio_dct64_1(a, b, bufs, bufs + 0x20, c);
327}
328
329/*//////////////////////////////////////////////////////////////// */
330/* */
331/* 9 Point Inverse Discrete Cosine Transform */
332/* */
333/* This piece of code is Copyright 1997 Mikko Tommila and is freely usable */
334/* by anybody. The algorithm itself is of course in the public domain. */
335/* */
336/* Again derived heuristically from the 9-point WFTA. */
337/* */
338/* The algorithm is optimized (?) for speed, not for small rounding errors or */
339/* good readability. */
340/* */
341/* 36 additions, 11 multiplications */
342/* */
343/* Again this is very likely sub-optimal. */
344/* */
345/* The code is optimized to use a minimum number of temporary variables, */
346/* so it should compile quite well even on 8-register Intel x86 processors. */
347/* This makes the code quite obfuscated and very difficult to understand. */
348/* */
349/* References: */
350/* [1] S. Winograd: "On Computing the Discrete Fourier Transform", */
351/* Mathematics of Computation, Volume 32, Number 141, January 1978, */
352/* Pages 175-199 */
353
354
355/*------------------------------------------------------------------*/
356/* */
357/* Function: Calculation of the inverse MDCT */
358/* */
359/*------------------------------------------------------------------*/
360
361int mpeg3audio_dct36(mpeg3_real_t *inbuf, mpeg3_real_t *o1, mpeg3_real_t *o2, mpeg3_real_t *wintab, mpeg3_real_t *tsbuf)
362{
363 mpeg3_real_t tmp[18];
364
365 {
366 register mpeg3_real_t *in = inbuf;
367
368 in[17]+=in[16]; in[16]+=in[15]; in[15]+=in[14];
369 in[14]+=in[13]; in[13]+=in[12]; in[12]+=in[11];
370 in[11]+=in[10]; in[10]+=in[9]; in[9] +=in[8];
371 in[8] +=in[7]; in[7] +=in[6]; in[6] +=in[5];
372 in[5] +=in[4]; in[4] +=in[3]; in[3] +=in[2];
373 in[2] +=in[1]; in[1] +=in[0];
374
375 in[17]+=in[15]; in[15]+=in[13]; in[13]+=in[11]; in[11]+=in[9];
376 in[9] +=in[7]; in[7] +=in[5]; in[5] +=in[3]; in[3] +=in[1];
377
378
379 {
380 mpeg3_real_t t3;
381 {
382 mpeg3_real_t t0, t1, t2;
383
384 t0 = mpeg3_COS6_2 * (in[8] + in[16] - in[4]);
385 t1 = mpeg3_COS6_2 * in[12];
386
387 t3 = in[0];
388 t2 = t3 - t1 - t1;
389 tmp[1] = tmp[7] = t2 - t0;
390 tmp[4] = t2 + t0 + t0;
391 t3 += t1;
392
393 t2 = mpeg3_COS6_1 * (in[10] + in[14] - in[2]);
394 tmp[1] -= t2;
395 tmp[7] += t2;
396 }
397 {
398 mpeg3_real_t t0, t1, t2;
399
400 t0 = mpeg3_cos9[0] * (in[4] + in[8] );
401 t1 = mpeg3_cos9[1] * (in[8] - in[16]);
402 t2 = mpeg3_cos9[2] * (in[4] + in[16]);
403
404 tmp[2] = tmp[6] = t3 - t0 - t2;
405 tmp[0] = tmp[8] = t3 + t0 + t1;
406 tmp[3] = tmp[5] = t3 - t1 + t2;
407 }
408 }
409 {
410 mpeg3_real_t t1, t2, t3;
411
412 t1 = mpeg3_cos18[0] * (in[2] + in[10]);
413 t2 = mpeg3_cos18[1] * (in[10] - in[14]);
414 t3 = mpeg3_COS6_1 * in[6];
415
416 {
417 mpeg3_real_t t0 = t1 + t2 + t3;
418 tmp[0] += t0;
419 tmp[8] -= t0;
420 }
421
422 t2 -= t3;
423 t1 -= t3;
424
425 t3 = mpeg3_cos18[2] * (in[2] + in[14]);
426
427 t1 += t3;
428 tmp[3] += t1;
429 tmp[5] -= t1;
430
431 t2 -= t3;
432 tmp[2] += t2;
433 tmp[6] -= t2;
434 }
435
436
437 {
438 mpeg3_real_t t0, t1, t2, t3, t4, t5, t6, t7;
439
440 t1 = mpeg3_COS6_2 * in[13];
441 t2 = mpeg3_COS6_2 * (in[9] + in[17] - in[5]);
442
443 t3 = in[1] + t1;
444 t4 = in[1] - t1 - t1;
445 t5 = t4 - t2;
446
447 t0 = mpeg3_cos9[0] * (in[5] + in[9]);
448 t1 = mpeg3_cos9[1] * (in[9] - in[17]);
449
450 tmp[13] = (t4 + t2 + t2) * mpeg3_tfcos36[17-13];
451 t2 = mpeg3_cos9[2] * (in[5] + in[17]);
452
453 t6 = t3 - t0 - t2;
454 t0 += t3 + t1;
455 t3 += t2 - t1;
456
457 t2 = mpeg3_cos18[0] * (in[3] + in[11]);
458 t4 = mpeg3_cos18[1] * (in[11] - in[15]);
459 t7 = mpeg3_COS6_1 * in[7];
460
461 t1 = t2 + t4 + t7;
462 tmp[17] = (t0 + t1) * mpeg3_tfcos36[17-17];
463 tmp[9] = (t0 - t1) * mpeg3_tfcos36[17-9];
464 t1 = mpeg3_cos18[2] * (in[3] + in[15]);
465 t2 += t1 - t7;
466
467 tmp[14] = (t3 + t2) * mpeg3_tfcos36[17-14];
468 t0 = mpeg3_COS6_1 * (in[11] + in[15] - in[3]);
469 tmp[12] = (t3 - t2) * mpeg3_tfcos36[17-12];
470
471 t4 -= t1 + t7;
472
473 tmp[16] = (t5 - t0) * mpeg3_tfcos36[17-16];
474 tmp[10] = (t5 + t0) * mpeg3_tfcos36[17-10];
475 tmp[15] = (t6 + t4) * mpeg3_tfcos36[17-15];
476 tmp[11] = (t6 - t4) * mpeg3_tfcos36[17-11];
477 }
478
479#define MACRO(v) \
480 { \
481 mpeg3_real_t tmpval; \
482 tmpval = tmp[(v)] + tmp[17-(v)]; \
483 out2[9+(v)] = tmpval * w[27+(v)]; \
484 out2[8-(v)] = tmpval * w[26-(v)]; \
485 tmpval = tmp[(v)] - tmp[17-(v)]; \
486 ts[SBLIMIT*(8-(v))] = out1[8-(v)] + tmpval * w[8-(v)]; \
487 ts[SBLIMIT*(9+(v))] = out1[9+(v)] + tmpval * w[9+(v)]; \
488 }
489
490 {
491 register mpeg3_real_t *out2 = o2;
492 register mpeg3_real_t *w = wintab;
493 register mpeg3_real_t *out1 = o1;
494 register mpeg3_real_t *ts = tsbuf;
495
496 MACRO(0);
497 MACRO(1);
498 MACRO(2);
499 MACRO(3);
500 MACRO(4);
501 MACRO(5);
502 MACRO(6);
503 MACRO(7);
504 MACRO(8);
505 }
506 }
507 return 0;
508}
509
510/*
511 * new DCT12
512 */
513int mpeg3audio_dct12(mpeg3_real_t *in,mpeg3_real_t *rawout1,mpeg3_real_t *rawout2,register mpeg3_real_t *wi,register mpeg3_real_t *ts)
514{
515#define DCT12_PART1 \
516 in5 = in[5*3]; \
517 in5 += (in4 = in[4*3]); \
518 in4 += (in3 = in[3*3]); \
519 in3 += (in2 = in[2*3]); \
520 in2 += (in1 = in[1*3]); \
521 in1 += (in0 = in[0*3]); \
522 \
523 in5 += in3; in3 += in1; \
524 \
525 in2 *= mpeg3_COS6_1; \
526 in3 *= mpeg3_COS6_1; \
527
528#define DCT12_PART2 \
529 in0 += in4 * mpeg3_COS6_2; \
530 \
531 in4 = in0 + in2; \
532 in0 -= in2; \
533 \
534 in1 += in5 * mpeg3_COS6_2; \
535 \
536 in5 = (in1 + in3) * mpeg3_tfcos12[0]; \
537 in1 = (in1 - in3) * mpeg3_tfcos12[2]; \
538 \
539 in3 = in4 + in5; \
540 in4 -= in5; \
541 \
542 in2 = in0 + in1; \
543 in0 -= in1;
544
545
546 {
547 mpeg3_real_t in0,in1,in2,in3,in4,in5;
548 register mpeg3_real_t *out1 = rawout1;
549 ts[SBLIMIT*0] = out1[0]; ts[SBLIMIT*1] = out1[1]; ts[SBLIMIT*2] = out1[2];
550 ts[SBLIMIT*3] = out1[3]; ts[SBLIMIT*4] = out1[4]; ts[SBLIMIT*5] = out1[5];
551
552 DCT12_PART1
553
554 {
555 mpeg3_real_t tmp0,tmp1 = (in0 - in4);
556 {
557 mpeg3_real_t tmp2 = (in1 - in5) * mpeg3_tfcos12[1];
558 tmp0 = tmp1 + tmp2;
559 tmp1 -= tmp2;
560 }
561 ts[(17-1)*SBLIMIT] = out1[17-1] + tmp0 * wi[11-1];
562 ts[(12+1)*SBLIMIT] = out1[12+1] + tmp0 * wi[6+1];
563 ts[(6 +1)*SBLIMIT] = out1[6 +1] + tmp1 * wi[1];
564 ts[(11-1)*SBLIMIT] = out1[11-1] + tmp1 * wi[5-1];
565 }
566
567 DCT12_PART2
568
569 ts[(17-0)*SBLIMIT] = out1[17-0] + in2 * wi[11-0];
570 ts[(12+0)*SBLIMIT] = out1[12+0] + in2 * wi[6+0];
571 ts[(12+2)*SBLIMIT] = out1[12+2] + in3 * wi[6+2];
572 ts[(17-2)*SBLIMIT] = out1[17-2] + in3 * wi[11-2];
573
574 ts[(6+0)*SBLIMIT] = out1[6+0] + in0 * wi[0];
575 ts[(11-0)*SBLIMIT] = out1[11-0] + in0 * wi[5-0];
576 ts[(6+2)*SBLIMIT] = out1[6+2] + in4 * wi[2];
577 ts[(11-2)*SBLIMIT] = out1[11-2] + in4 * wi[5-2];
578 }
579
580 in++;
581
582 {
583 mpeg3_real_t in0,in1,in2,in3,in4,in5;
584 register mpeg3_real_t *out2 = rawout2;
585
586 DCT12_PART1
587
588 {
589 mpeg3_real_t tmp0,tmp1 = (in0 - in4);
590 {
591 mpeg3_real_t tmp2 = (in1 - in5) * mpeg3_tfcos12[1];
592 tmp0 = tmp1 + tmp2;
593 tmp1 -= tmp2;
594 }
595 out2[5-1] = tmp0 * wi[11-1];
596 out2[0+1] = tmp0 * wi[6+1];
597 ts[(12+1)*SBLIMIT] += tmp1 * wi[1];
598 ts[(17-1)*SBLIMIT] += tmp1 * wi[5-1];
599 }
600
601 DCT12_PART2
602
603 out2[5-0] = in2 * wi[11-0];
604 out2[0+0] = in2 * wi[6+0];
605 out2[0+2] = in3 * wi[6+2];
606 out2[5-2] = in3 * wi[11-2];
607
608 ts[(12+0)*SBLIMIT] += in0 * wi[0];
609 ts[(17-0)*SBLIMIT] += in0 * wi[5-0];
610 ts[(12+2)*SBLIMIT] += in4 * wi[2];
611 ts[(17-2)*SBLIMIT] += in4 * wi[5-2];
612 }
613
614 in++;
615
616 {
617 mpeg3_real_t in0,in1,in2,in3,in4,in5;
618 register mpeg3_real_t *out2 = rawout2;
619 out2[12]=out2[13]=out2[14]=out2[15]=out2[16]=out2[17]=0.0;
620
621 DCT12_PART1
622
623 {
624 mpeg3_real_t tmp0,tmp1 = (in0 - in4);
625 {
626 mpeg3_real_t tmp2 = (in1 - in5) * mpeg3_tfcos12[1];
627 tmp0 = tmp1 + tmp2;
628 tmp1 -= tmp2;
629 }
630 out2[11-1] = tmp0 * wi[11-1];
631 out2[6 +1] = tmp0 * wi[6+1];
632 out2[0+1] += tmp1 * wi[1];
633 out2[5-1] += tmp1 * wi[5-1];
634 }
635
636 DCT12_PART2
637
638 out2[11-0] = in2 * wi[11-0];
639 out2[6 +0] = in2 * wi[6+0];
640 out2[6 +2] = in3 * wi[6+2];
641 out2[11-2] = in3 * wi[11-2];
642
643 out2[0+0] += in0 * wi[0];
644 out2[5-0] += in0 * wi[5-0];
645 out2[0+2] += in4 * wi[2];
646 out2[5-2] += in4 * wi[5-2];
647 }
648 return 0;
649}
650
651/* AC3 IMDCT tables */
652
653/* Twiddle factors for IMDCT */
654#if !defined(USE_FIXED_POINT) || defined(PRINT_FIXED_POINT_TABLES)
655static mpeg3_real_t mpeg3_xcos1[AC3_N / 4];
656static mpeg3_real_t mpeg3_xsin1[AC3_N / 4];
657static mpeg3_real_t mpeg3_xcos2[AC3_N / 8];
658static mpeg3_real_t mpeg3_xsin2[AC3_N / 8];
659#else
660#define USE_FP_TABLES
661#include "fptables.h"
662#endif
663
664/* 128 point bit-reverse LUT */
665static unsigned char mpeg3_bit_reverse_512[] =
666{
667 0x00, 0x40, 0x20, 0x60, 0x10, 0x50, 0x30, 0x70,
668 0x08, 0x48, 0x28, 0x68, 0x18, 0x58, 0x38, 0x78,
669 0x04, 0x44, 0x24, 0x64, 0x14, 0x54, 0x34, 0x74,
670 0x0c, 0x4c, 0x2c, 0x6c, 0x1c, 0x5c, 0x3c, 0x7c,
671 0x02, 0x42, 0x22, 0x62, 0x12, 0x52, 0x32, 0x72,
672 0x0a, 0x4a, 0x2a, 0x6a, 0x1a, 0x5a, 0x3a, 0x7a,
673 0x06, 0x46, 0x26, 0x66, 0x16, 0x56, 0x36, 0x76,
674 0x0e, 0x4e, 0x2e, 0x6e, 0x1e, 0x5e, 0x3e, 0x7e,
675 0x01, 0x41, 0x21, 0x61, 0x11, 0x51, 0x31, 0x71,
676 0x09, 0x49, 0x29, 0x69, 0x19, 0x59, 0x39, 0x79,
677 0x05, 0x45, 0x25, 0x65, 0x15, 0x55, 0x35, 0x75,
678 0x0d, 0x4d, 0x2d, 0x6d, 0x1d, 0x5d, 0x3d, 0x7d,
679 0x03, 0x43, 0x23, 0x63, 0x13, 0x53, 0x33, 0x73,
680 0x0b, 0x4b, 0x2b, 0x6b, 0x1b, 0x5b, 0x3b, 0x7b,
681 0x07, 0x47, 0x27, 0x67, 0x17, 0x57, 0x37, 0x77,
682 0x0f, 0x4f, 0x2f, 0x6f, 0x1f, 0x5f, 0x3f, 0x7f
683};
684
685static unsigned char mpeg3_bit_reverse_256[] =
686{
687 0x00, 0x20, 0x10, 0x30, 0x08, 0x28, 0x18, 0x38,
688 0x04, 0x24, 0x14, 0x34, 0x0c, 0x2c, 0x1c, 0x3c,
689 0x02, 0x22, 0x12, 0x32, 0x0a, 0x2a, 0x1a, 0x3a,
690 0x06, 0x26, 0x16, 0x36, 0x0e, 0x2e, 0x1e, 0x3e,
691 0x01, 0x21, 0x11, 0x31, 0x09, 0x29, 0x19, 0x39,
692 0x05, 0x25, 0x15, 0x35, 0x0d, 0x2d, 0x1d, 0x3d,
693 0x03, 0x23, 0x13, 0x33, 0x0b, 0x2b, 0x1b, 0x3b,
694 0x07, 0x27, 0x17, 0x37, 0x0f, 0x2f, 0x1f, 0x3f
695};
696
697/* Windowing function for Modified DCT - Thank you acroread */
698static mpeg3_real_t mpeg3_window[] =
699{
700 0.00014, 0.00024, 0.00037, 0.00051, 0.00067, 0.00086, 0.00107, 0.00130,
701 0.00157, 0.00187, 0.00220, 0.00256, 0.00297, 0.00341, 0.00390, 0.00443,
702 0.00501, 0.00564, 0.00632, 0.00706, 0.00785, 0.00871, 0.00962, 0.01061,
703 0.01166, 0.01279, 0.01399, 0.01526, 0.01662, 0.01806, 0.01959, 0.02121,
704 0.02292, 0.02472, 0.02662, 0.02863, 0.03073, 0.03294, 0.03527, 0.03770,
705 0.04025, 0.04292, 0.04571, 0.04862, 0.05165, 0.05481, 0.05810, 0.06153,
706 0.06508, 0.06878, 0.07261, 0.07658, 0.08069, 0.08495, 0.08935, 0.09389,
707 0.09859, 0.10343, 0.10842, 0.11356, 0.11885, 0.12429, 0.12988, 0.13563,
708 0.14152, 0.14757, 0.15376, 0.16011, 0.16661, 0.17325, 0.18005, 0.18699,
709 0.19407, 0.20130, 0.20867, 0.21618, 0.22382, 0.23161, 0.23952, 0.24757,
710 0.25574, 0.26404, 0.27246, 0.28100, 0.28965, 0.29841, 0.30729, 0.31626,
711 0.32533, 0.33450, 0.34376, 0.35311, 0.36253, 0.37204, 0.38161, 0.39126,
712 0.40096, 0.41072, 0.42054, 0.43040, 0.44030, 0.45023, 0.46020, 0.47019,
713 0.48020, 0.49022, 0.50025, 0.51028, 0.52031, 0.53033, 0.54033, 0.55031,
714 0.56026, 0.57019, 0.58007, 0.58991, 0.59970, 0.60944, 0.61912, 0.62873,
715 0.63827, 0.64774, 0.65713, 0.66643, 0.67564, 0.68476, 0.69377, 0.70269,
716 0.71150, 0.72019, 0.72877, 0.73723, 0.74557, 0.75378, 0.76186, 0.76981,
717 0.77762, 0.78530, 0.79283, 0.80022, 0.80747, 0.81457, 0.82151, 0.82831,
718 0.83496, 0.84145, 0.84779, 0.85398, 0.86001, 0.86588, 0.87160, 0.87716,
719 0.88257, 0.88782, 0.89291, 0.89785, 0.90264, 0.90728, 0.91176, 0.91610,
720 0.92028, 0.92432, 0.92822, 0.93197, 0.93558, 0.93906, 0.94240, 0.94560,
721 0.94867, 0.95162, 0.95444, 0.95713, 0.95971, 0.96217, 0.96451, 0.96674,
722 0.96887, 0.97089, 0.97281, 0.97463, 0.97635, 0.97799, 0.97953, 0.98099,
723 0.98236, 0.98366, 0.98488, 0.98602, 0.98710, 0.98811, 0.98905, 0.98994,
724 0.99076, 0.99153, 0.99225, 0.99291, 0.99353, 0.99411, 0.99464, 0.99513,
725 0.99558, 0.99600, 0.99639, 0.99674, 0.99706, 0.99736, 0.99763, 0.99788,
726 0.99811, 0.99831, 0.99850, 0.99867, 0.99882, 0.99895, 0.99908, 0.99919,
727 0.99929, 0.99938, 0.99946, 0.99953, 0.99959, 0.99965, 0.99969, 0.99974,
728 0.99978, 0.99981, 0.99984, 0.99986, 0.99988, 0.99990, 0.99992, 0.99993,
729 0.99994, 0.99995, 0.99996, 0.99997, 0.99998, 0.99998, 0.99998, 0.99999,
730 0.99999, 0.99999, 0.99999, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000,
731 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000
732};
733
734mpeg3_complex_t cmplx_mult(mpeg3_complex_t a, mpeg3_complex_t b)
735{
736 mpeg3_complex_t ret;
737
738 ret.real = a.real * b.real - a.imag * b.imag;
739 ret.imag = a.real * b.imag + a.imag * b.real;
740
741 return ret;
742}
743
744int mpeg3audio_imdct_init(mpeg3audio_t *audio)
745{
746 int i, k;
747 mpeg3_complex_t angle_step;
748 mpeg3_complex_t current_angle;
749
750/* Twiddle factors to turn IFFT into IMDCT */
751 for(i = 0; i < AC3_N / 4; i++)
752 {
753 mpeg3_xcos1[i] = -cos(2.0f * M_PI * (8 * i + 1 ) / ( 8 * AC3_N));
754 mpeg3_xsin1[i] = -sin(2.0f * M_PI * (8 * i + 1 ) / ( 8 * AC3_N));
755 }
756
757/* More twiddle factors to turn IFFT into IMDCT */
758 for(i = 0; i < AC3_N / 8; i++)
759 {
760 mpeg3_xcos2[i] = -cos(2.0f * M_PI * (8 * i + 1 ) / ( 4 * AC3_N));
761 mpeg3_xsin2[i] = -sin(2.0f * M_PI * (8 * i + 1 ) / ( 4 * AC3_N));
762 }
763
764/* Canonical twiddle factors for FFT */
765#if defined(USE_FIXED_POINT) && !defined(PRINT_FIXED_POINT_TABLES)
766 for(i = 0; i < 7; i++)
767 {
768 audio->ac3_w[i] = (mpeg3_complex_t*)ac3_w_fixedpoints[i];
769 }
770#else
771 audio->ac3_w[0] = audio->ac3_w_1;
772 audio->ac3_w[1] = audio->ac3_w_2;
773 audio->ac3_w[2] = audio->ac3_w_4;
774 audio->ac3_w[3] = audio->ac3_w_8;
775 audio->ac3_w[4] = audio->ac3_w_16;
776 audio->ac3_w[5] = audio->ac3_w_32;
777 audio->ac3_w[6] = audio->ac3_w_64;
778
779 for(i = 0; i < 7; i++)
780 {
781 angle_step.real = cos(-2.0f * M_PI / (1 << (i + 1)));
782 angle_step.imag = sin(-2.0f * M_PI / (1 << (i + 1)));
783
784 current_angle.real = 1.0f;
785 current_angle.imag = 0.0f;
786
787 for (k = 0; k < 1 << i; k++)
788 {
789 audio->ac3_w[i][k] = current_angle;
790 current_angle = cmplx_mult(current_angle, angle_step);
791 }
792 }
793
794#ifdef PRINT_FIXED_POINT_TABLES
795 printf("#ifdef USE_FP_TABLES\n");
796 printf("static long mpeg3_xcos1_fixedpoints[] = {");
797 for(i = 0; i < AC3_N / 4; i++) {
798 printf("%c0x%08x,", i%8?' ':'\n', mpeg3_xcos1[i].fixedPoint());
799 }
800 printf("\n};\nstatic mpeg3_real_t *mpeg3_xcos1 = \n"
801 "(mpeg3_real_t*)mpeg3_xcos1_fixedpoints;\n");
802
803 printf("static long mpeg3_xsin1_fixedpoints[] = {");
804 for(i = 0; i < AC3_N / 4; i++) {
805 printf("%c0x%08x,", i%8?' ':'\n', mpeg3_xsin1[i].fixedPoint());
806 }
807 printf("\n};\nstatic mpeg3_real_t *mpeg3_xsin1 = \n"
808 "(mpeg3_real_t*)mpeg3_xsin1_fixedpoints;\n");
809
810
811 printf("static long mpeg3_xcos2_fixedpoints[] = {");
812 for(i = 0; i < AC3_N / 4; i++) {
813 printf("%c0x%08x,", i%8?' ':'\n', mpeg3_xcos2[i].fixedPoint());
814 }
815 printf("\n};\nstatic mpeg3_real_t *mpeg3_xcos2 = \n"
816 "(mpeg3_real_t*)mpeg3_xcos2_fixedpoints;\n");
817
818 printf("static long mpeg3_xsin2_fixedpoints[] = {");
819 for(i = 0; i < AC3_N / 4; i++) {
820 printf("%c0x%08x,", i%8?' ':'\n', mpeg3_xsin2[i].fixedPoint());
821 }
822 printf("\n};\nstatic mpeg3_real_t *mpeg3_xsin2 = \n"
823 "(mpeg3_real_t*)mpeg3_xsin2_fixedpoints;\n");
824
825
826 printf("typedef struct { long r, i; } fixed_cmplx;\n");
827 for(i = 0; i < 7; i++)
828 {
829 printf("fixed_cmplx ac3_w_d%d[] = { ", 1<<i);
830 for (k = 0; k < 1 << i; k++)
831 {
832 printf("%s{ 0x%08x, 0x%08x },", k%4?" ":"\n ",
833 audio->ac3_w[i][k].real.fixedPoint(),
834 audio->ac3_w[i][k].imag.fixedPoint());
835 }
836 printf("};\n");
837 }
838
839 printf("fixed_cmplx *ac3_w_fixedpoints[] = {\n");
840 for(i = 0; i < 7; i++)
841 {
842 printf("ac3_w_d%d, ", 1<<i);
843 }
844 printf("};\n");
845 printf("#endif\n");
846#endif
847#endif
848
849 return 0;
850}
851
852
853inline void swap_cmplx(mpeg3_complex_t *a, mpeg3_complex_t *b)
854{
855 mpeg3_complex_t tmp;
856
857 tmp = *a;
858 *a = *b;
859 *b = tmp;
860}
861
862void mpeg3audio_ac3_imdct_do_512(mpeg3audio_t *audio,
863 mpeg3_real_t data[],
864 mpeg3_real_t *y,
865 int step,
866 mpeg3_real_t *delay)
867{
868 int i, k;
869 int p, q;
870 int m;
871 int two_m;
872 int two_m_plus_one;
873
874 mpeg3_real_t tmp_a_i;
875 mpeg3_real_t tmp_a_r;
876 mpeg3_real_t tmp_b_i;
877 mpeg3_real_t tmp_b_r;
878
879 mpeg3_real_t *y_ptr;
880 mpeg3_real_t *delay_ptr;
881 mpeg3_real_t *window_ptr;
882 mpeg3_complex_t *buf = audio->ac3_imdct_buf;
883
884/* Pre IFFT complex multiply plus IFFT cmplx conjugate */
885 for(i = 0; i < AC3_N / 4; i++)
886 {
887 buf[i].real = (data[AC3_N / 2 - 2 * i - 1] * mpeg3_xcos1[i]) - (data[2 * i] * mpeg3_xsin1[i]);
888 buf[i].imag = -((data[2 * i] * mpeg3_xcos1[i]) + (data[AC3_N / 2 - 2 * i - 1] * mpeg3_xsin1[i]));
889 }
890
891/* Bit reversed shuffling */
892 for(i = 0; i < AC3_N / 4; i++)
893 {
894 k = mpeg3_bit_reverse_512[i];
895 if(k < i)
896 swap_cmplx(&buf[i], &buf[k]);
897 }
898
899/* FFT Merge */
900 for(m = 0; m < 7; m++)
901 {
902 if(m)
903 two_m = (1 << m);
904 else
905 two_m = 1;
906
907 two_m_plus_one = (1 << (m + 1));
908
909 for(k = 0; k < two_m; k++)
910 {
911 for(i = 0; i < AC3_N / 4; i += two_m_plus_one)
912 {
913 p = k + i;
914 q = p + two_m;
915 tmp_a_r = buf[p].real;
916 tmp_a_i = buf[p].imag;
917 tmp_b_r = buf[q].real * audio->ac3_w[m][k].real - buf[q].imag * audio->ac3_w[m][k].imag;
918 tmp_b_i = buf[q].imag * audio->ac3_w[m][k].real + buf[q].real * audio->ac3_w[m][k].imag;
919 buf[p].real = tmp_a_r + tmp_b_r;
920 buf[p].imag = tmp_a_i + tmp_b_i;
921 buf[q].real = tmp_a_r - tmp_b_r;
922 buf[q].imag = tmp_a_i - tmp_b_i;
923 }
924 }
925 }
926
927/* Post IFFT complex multiply plus IFFT complex conjugate*/
928 for(i = 0; i < AC3_N / 4; i++)
929 {
930 tmp_a_r = buf[i].real;
931 tmp_a_i = -buf[i].imag;
932 buf[i].real = (tmp_a_r * mpeg3_xcos1[i]) - (tmp_a_i * mpeg3_xsin1[i]);
933 buf[i].imag = (tmp_a_r * mpeg3_xsin1[i]) + (tmp_a_i * mpeg3_xcos1[i]);
934 }
935
936 y_ptr = y;
937 delay_ptr = delay;
938 window_ptr = mpeg3_window;
939
940/* Window and convert to real valued signal */
941 for(i = 0; i < AC3_N / 8; i++)
942 {
943 *y_ptr = -buf[AC3_N / 8 + i].imag * *window_ptr++ + *delay_ptr++;
944 y_ptr += step;
945 *y_ptr = buf[AC3_N / 8 - i - 1].real * *window_ptr++ + *delay_ptr++;
946 y_ptr += step;
947 }
948
949 for(i = 0; i < AC3_N / 8; i++)
950 {
951 *y_ptr = -buf[i].real * *window_ptr++ + *delay_ptr++;
952 y_ptr += step;
953 *y_ptr = buf[AC3_N / 4 - i - 1].imag * *window_ptr++ + *delay_ptr++;
954 y_ptr += step;
955 }
956
957/* The trailing edge of the window goes into the delay line */
958 delay_ptr = delay;
959
960 for(i = 0; i < AC3_N / 8; i++)
961 {
962 *delay_ptr++ = -buf[AC3_N / 8 + i].real * *--window_ptr;
963 *delay_ptr++ = buf[AC3_N / 8 - i - 1].imag * *--window_ptr;
964 }
965
966 for(i = 0; i < AC3_N / 8; i++)
967 {
968 *delay_ptr++ = buf[i].imag * *--window_ptr;
969 *delay_ptr++ = -buf[AC3_N / 4 - i - 1].real * *--window_ptr;
970 }
971}
972
973void mpeg3audio_ac3_imdct_do_256(mpeg3audio_t *audio,
974 mpeg3_real_t data[],
975 mpeg3_real_t *y,
976 int step,
977 mpeg3_real_t *delay)
978{
979 int i, k;
980 int p, q;
981 int m;
982 int two_m;
983 int two_m_plus_one;
984 mpeg3_complex_t *buf = audio->ac3_imdct_buf;
985 mpeg3_real_t *y_ptr;
986 mpeg3_real_t *delay_ptr;
987 mpeg3_real_t *window_ptr;
988
989 mpeg3_real_t tmp_a_i;
990 mpeg3_real_t tmp_a_r;
991 mpeg3_real_t tmp_b_i;
992 mpeg3_real_t tmp_b_r;
993
994 mpeg3_complex_t *buf_1, *buf_2;
995
996 buf_1 = &buf[0];
997 buf_2 = &buf[64];
998
999/* Pre IFFT complex multiply plus IFFT cmplx conjugate */
1000 for(k = 0; k < AC3_N / 8; k++)
1001 {
1002 p = 2 * (AC3_N / 4 - 2 * k - 1);
1003 q = 2 * (2 * k);
1004
1005 buf_1[k].real = data[p] * mpeg3_xcos2[k] - data[q] * mpeg3_xsin2[k];
1006 buf_1[k].imag = - (data[q] * mpeg3_xcos2[k] + data[p] * mpeg3_xsin2[k]);
1007 buf_2[k].real = data[p + 1] * mpeg3_xcos2[k] - data[q + 1] * mpeg3_xsin2[k];
1008 buf_2[k].imag = - (data[q + 1] * mpeg3_xcos2[k] + data[p + 1] * mpeg3_xsin2[k]);
1009 }
1010
1011/* IFFT Bit reversed shuffling */
1012 for(i = 0; i < AC3_N / 8; i++)
1013 {
1014 k = mpeg3_bit_reverse_256[i];
1015 if(k < i)
1016 {
1017 swap_cmplx(&buf_1[i], &buf_1[k]);
1018 swap_cmplx(&buf_2[i], &buf_2[k]);
1019 }
1020 }
1021
1022/* FFT Merge */
1023 for(m = 0; m < 6; m++)
1024 {
1025 if(m)
1026 two_m = (1 << m);
1027 else
1028 two_m = 1;
1029
1030 two_m_plus_one = (1 << (m + 1));
1031
1032 for(k = 0; k < two_m; k++)
1033 {
1034 for(i = 0; i < AC3_N / 8; i += two_m_plus_one)
1035 {
1036 p = k + i;
1037 q = p + two_m;
1038/* Do block 1 */
1039 tmp_a_r = buf_1[p].real;
1040 tmp_a_i = buf_1[p].imag;
1041 tmp_b_r = buf_1[q].real * audio->ac3_w[m][k].real - buf_1[q].imag * audio->ac3_w[m][k].imag;
1042 tmp_b_i = buf_1[q].imag * audio->ac3_w[m][k].real + buf_1[q].real * audio->ac3_w[m][k].imag;
1043 buf_1[p].real = tmp_a_r + tmp_b_r;
1044 buf_1[p].imag = tmp_a_i + tmp_b_i;
1045 buf_1[q].real = tmp_a_r - tmp_b_r;
1046 buf_1[q].imag = tmp_a_i - tmp_b_i;
1047
1048/* Do block 2 */
1049 tmp_a_r = buf_2[p].real;
1050 tmp_a_i = buf_2[p].imag;
1051 tmp_b_r = buf_2[q].real * audio->ac3_w[m][k].real - buf_2[q].imag * audio->ac3_w[m][k].imag;
1052 tmp_b_i = buf_2[q].imag * audio->ac3_w[m][k].real + buf_2[q].real * audio->ac3_w[m][k].imag;
1053 buf_2[p].real = tmp_a_r + tmp_b_r;
1054 buf_2[p].imag = tmp_a_i + tmp_b_i;
1055 buf_2[q].real = tmp_a_r - tmp_b_r;
1056 buf_2[q].imag = tmp_a_i - tmp_b_i;
1057 }
1058 }
1059 }
1060
1061/* Post IFFT complex multiply */
1062 for(i = 0; i < AC3_N / 8; i++)
1063 {
1064 tmp_a_r = buf_1[i].real;
1065 tmp_a_i = -buf_1[i].imag;
1066 buf_1[i].real = (tmp_a_r * mpeg3_xcos2[i]) - (tmp_a_i * mpeg3_xsin2[i]);
1067 buf_1[i].imag = (tmp_a_r * mpeg3_xsin2[i]) + (tmp_a_i * mpeg3_xcos2[i]);
1068 tmp_a_r = buf_2[i].real;
1069 tmp_a_i = -buf_2[i].imag;
1070 buf_2[i].real = (tmp_a_r * mpeg3_xcos2[i]) - (tmp_a_i * mpeg3_xsin2[i]);
1071 buf_2[i].imag = (tmp_a_r * mpeg3_xsin2[i]) + (tmp_a_i * mpeg3_xcos2[i]);
1072 }
1073
1074/* Window and convert to real valued signal */
1075 y_ptr = y;
1076 delay_ptr = delay;
1077 window_ptr = mpeg3_window;
1078
1079 for(i = 0; i < AC3_N / 8; i++)
1080 {
1081 *y_ptr = -buf[AC3_N / 8 + i].imag * *window_ptr++ + *delay_ptr++;
1082 y_ptr += step;
1083 *y_ptr = buf[AC3_N / 8 - i - 1].real * *window_ptr++ + *delay_ptr++;
1084 y_ptr += step;
1085 }
1086
1087 for(i = 0; i < AC3_N / 8; i++)
1088 {
1089 *y_ptr = -buf[i].real * *window_ptr++ + *delay_ptr++;
1090 y_ptr += step;
1091 *y_ptr = buf[AC3_N / 4 - i - 1].imag * *window_ptr++ + *delay_ptr++;
1092 y_ptr += step;
1093 }
1094
1095/* The trailing edge of the window goes into the delay line */
1096 delay_ptr = delay;
1097
1098 for(i = 0; i < AC3_N / 8; i++)
1099 {
1100 *delay_ptr++ = -buf[AC3_N / 8 + i].real * *--window_ptr;
1101 *delay_ptr++ = buf[AC3_N / 8 - i - 1].imag * *--window_ptr;
1102 }
1103
1104 for(i = 0; i < AC3_N / 8; i++)
1105 {
1106 *delay_ptr++ = buf[i].imag * *--window_ptr;
1107 *delay_ptr++ = -buf[AC3_N / 4 - i - 1].real * *--window_ptr;
1108 }
1109}
1110
1111int mpeg3audio_ac3_imdct(mpeg3audio_t *audio,
1112 mpeg3_ac3bsi_t *bsi,
1113 mpeg3_ac3audblk_t *audblk,
1114 mpeg3ac3_stream_samples_t samples)
1115{
1116 int i;
1117
1118 for(i = 0; i < bsi->nfchans; i++)
1119 {
1120 if(audblk->blksw[i])
1121 mpeg3audio_ac3_imdct_do_256(audio,
1122 samples[i],
1123 audio->pcm_sample + audio->pcm_point + i,
1124 bsi->nfchans,
1125 audio->ac3_delay[i]);
1126 else
1127 mpeg3audio_ac3_imdct_do_512(audio,
1128 samples[i],
1129 audio->pcm_sample + audio->pcm_point + i,
1130 bsi->nfchans,
1131 audio->ac3_delay[i]);
1132 }
1133 audio->pcm_point += AC3_N / 2 * bsi->nfchans;
1134 return 0;
1135}
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 @@
1/*
2 *
3 *exponents.c Copyright (C) Aaron Holtzman - May 1999
4 *
5 * This file is part of libmpeg3
6 *
7 * libmpeg3 is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
10 * any later version.
11 *
12 * libmpeg3 is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Make; see the file COPYING. If not, write to
19 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 */
22
23#include "mpeg3audio.h"
24#include "../libmpeg3.h"
25#include "../mpeg3protos.h"
26#include <stdio.h>
27
28/* Exponent defines */
29#define UNPACK_FBW 1
30#define UNPACK_CPL 2
31#define UNPACK_LFE 4
32
33static inline int mpeg3audio_ac3_exp_unpack_ch(unsigned int type,
34 unsigned int expstr,
35 unsigned int ngrps,
36 unsigned int initial_exp,
37 unsigned short exps[],
38 unsigned short *dest)
39{
40 int i, j;
41 int exp_acc;
42 int exp_1, exp_2, exp_3;
43
44 if(expstr == MPEG3_EXP_REUSE)
45 return 0;
46
47/* Handle the initial absolute exponent */
48 exp_acc = initial_exp;
49 j = 0;
50
51/* In the case of a fbw channel then the initial absolute value is
52 * also an exponent */
53 if(type != UNPACK_CPL)
54 dest[j++] = exp_acc;
55
56/* Loop through the groups and fill the dest array appropriately */
57 for(i = 0; i < ngrps; i++)
58 {
59 if(exps[i] > 124)
60 {
61 fprintf(stderr, "mpeg3audio_ac3_exp_unpack_ch: Invalid exponent %d\n", exps[i]);
62 return 1;
63 }
64
65 exp_1 = exps[i] / 25;
66 exp_2 = (exps[i] % 25) / 5;
67 exp_3 = (exps[i] % 25) % 5;
68
69 exp_acc += (exp_1 - 2);
70
71 switch(expstr)
72 {
73 case MPEG3_EXP_D45:
74 dest[j++] = exp_acc;
75 dest[j++] = exp_acc;
76 case MPEG3_EXP_D25:
77 dest[j++] = exp_acc;
78 case MPEG3_EXP_D15:
79 dest[j++] = exp_acc;
80 }
81
82 exp_acc += (exp_2 - 2);
83
84 switch(expstr)
85 {
86 case MPEG3_EXP_D45:
87 dest[j++] = exp_acc;
88 dest[j++] = exp_acc;
89 case MPEG3_EXP_D25:
90 dest[j++] = exp_acc;
91 case MPEG3_EXP_D15:
92 dest[j++] = exp_acc;
93 }
94
95 exp_acc += (exp_3 - 2);
96
97 switch(expstr)
98 {
99 case MPEG3_EXP_D45:
100 dest[j++] = exp_acc;
101 dest[j++] = exp_acc;
102 case MPEG3_EXP_D25:
103 dest[j++] = exp_acc;
104 case MPEG3_EXP_D15:
105 dest[j++] = exp_acc;
106 }
107 }
108 return 0;
109}
110
111int mpeg3audio_ac3_exponent_unpack(mpeg3audio_t *audio,
112 mpeg3_ac3bsi_t *bsi,
113 mpeg3_ac3audblk_t *audblk)
114{
115 int i, result = 0;
116
117 for(i = 0; i < bsi->nfchans; i++)
118 result |= mpeg3audio_ac3_exp_unpack_ch(UNPACK_FBW,
119 audblk->chexpstr[i],
120 audblk->nchgrps[i],
121 audblk->exps[i][0],
122 &audblk->exps[i][1],
123 audblk->fbw_exp[i]);
124
125 if(audblk->cplinu && !result)
126 result |= mpeg3audio_ac3_exp_unpack_ch(UNPACK_CPL,
127 audblk->cplexpstr,
128 audblk->ncplgrps,
129 audblk->cplabsexp << 1,
130 audblk->cplexps,
131 &audblk->cpl_exp[audblk->cplstrtmant]);
132
133 if(bsi->lfeon && !result)
134 result |= mpeg3audio_ac3_exp_unpack_ch(UNPACK_LFE,
135 audblk->lfeexpstr,
136 2,
137 audblk->lfeexps[0],
138 &audblk->lfeexps[1],
139 audblk->lfe_exp);
140 return result;
141}
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 @@
1#ifdef USE_FP_TABLES
2static long mpeg3_xcos1_fixedpoints[] = {
30xffff8001, 0xffff8004, 0xffff800c, 0xffff8019, 0xffff802a, 0xffff8041, 0xffff805d, 0xffff807e,
40xffff80a3, 0xffff80ce, 0xffff80fd, 0xffff8131, 0xffff816b, 0xffff81a9, 0xffff81ec, 0xffff8233,
50xffff8280, 0xffff82d1, 0xffff8328, 0xffff8383, 0xffff83e3, 0xffff8447, 0xffff84b1, 0xffff851f,
60xffff8592, 0xffff860a, 0xffff8686, 0xffff8707, 0xffff878d, 0xffff8817, 0xffff88a6, 0xffff893a,
70xffff89d2, 0xffff8a6f, 0xffff8b10, 0xffff8bb6, 0xffff8c60, 0xffff8d0f, 0xffff8dc2, 0xffff8e7a,
80xffff8f35, 0xffff8ff6, 0xffff90ba, 0xffff9183, 0xffff9250, 0xffff9322, 0xffff93f7, 0xffff94d1,
90xffff95af, 0xffff9691, 0xffff9777, 0xffff9861, 0xffff994f, 0xffff9a41, 0xffff9b37, 0xffff9c31,
100xffff9d2e, 0xffff9e30, 0xffff9f35, 0xffffa03e, 0xffffa14b, 0xffffa25b, 0xffffa36f, 0xffffa487,
110xffffa5a2, 0xffffa6c0, 0xffffa7e2, 0xffffa907, 0xffffaa30, 0xffffab5c, 0xffffac8b, 0xffffadbe,
120xffffaef4, 0xffffb02c, 0xffffb168, 0xffffb2a7, 0xffffb3e9, 0xffffb52e, 0xffffb676, 0xffffb7c0,
130xffffb90d, 0xffffba5d, 0xffffbbb0, 0xffffbd06, 0xffffbe5e, 0xffffbfb8, 0xffffc115, 0xffffc274,
140xffffc3d6, 0xffffc53a, 0xffffc6a1, 0xffffc809, 0xffffc974, 0xffffcae1, 0xffffcc50, 0xffffcdc0,
150xffffcf33, 0xffffd0a8, 0xffffd21e, 0xffffd397, 0xffffd511, 0xffffd68c, 0xffffd80a, 0xffffd988,
160xffffdb09, 0xffffdc8a, 0xffffde0d, 0xffffdf92, 0xffffe117, 0xffffe29e, 0xffffe426, 0xffffe5af,
170xffffe739, 0xffffe8c4, 0xffffea50, 0xffffebdd, 0xffffed6a, 0xffffeef8, 0xfffff087, 0xfffff217,
180xfffff3a7, 0xfffff537, 0xfffff6c8, 0xfffff859, 0xfffff9eb, 0xfffffb7d, 0xfffffd0f, 0xfffffea1,
19};
20static mpeg3_real_t *mpeg3_xcos1 =
21(mpeg3_real_t*)mpeg3_xcos1_fixedpoints;
22static long mpeg3_xsin1_fixedpoints[] = {
230xffffffce, 0xfffffe3c, 0xfffffcaa, 0xfffffb18, 0xfffff986, 0xfffff7f5, 0xfffff664, 0xfffff4d3,
240xfffff343, 0xfffff1b3, 0xfffff023, 0xffffee95, 0xffffed07, 0xffffeb79, 0xffffe9ed, 0xffffe861,
250xffffe6d6, 0xffffe54d, 0xffffe3c4, 0xffffe23c, 0xffffe0b6, 0xffffdf30, 0xffffddac, 0xffffdc2a,
260xffffdaa8, 0xffffd928, 0xffffd7aa, 0xffffd62d, 0xffffd4b2, 0xffffd338, 0xffffd1c1, 0xffffd04b,
270xffffced6, 0xffffcd64, 0xffffcbf4, 0xffffca85, 0xffffc919, 0xffffc7af, 0xffffc647, 0xffffc4e1,
280xffffc37d, 0xffffc21c, 0xffffc0bd, 0xffffbf61, 0xffffbe07, 0xffffbcb0, 0xffffbb5b, 0xffffba09,
290xffffb8ba, 0xffffb76d, 0xffffb623, 0xffffb4dc, 0xffffb398, 0xffffb257, 0xffffb119, 0xffffafde,
300xffffaea6, 0xffffad71, 0xffffac3f, 0xffffab11, 0xffffa9e6, 0xffffa8be, 0xffffa799, 0xffffa678,
310xffffa55b, 0xffffa440, 0xffffa32a, 0xffffa217, 0xffffa107, 0xffff9ffc, 0xffff9ef3, 0xffff9def,
320xffff9cef, 0xffff9bf2, 0xffff9af9, 0xffff9a04, 0xffff9913, 0xffff9826, 0xffff973d, 0xffff9658,
330xffff9577, 0xffff949a, 0xffff93c1, 0xffff92ed, 0xffff921d, 0xffff9151, 0xffff9089, 0xffff8fc5,
340xffff8f06, 0xffff8e4b, 0xffff8d95, 0xffff8ce3, 0xffff8c35, 0xffff8b8c, 0xffff8ae7, 0xffff8a47,
350xffff89ac, 0xffff8915, 0xffff8882, 0xffff87f4, 0xffff876b, 0xffff86e7, 0xffff8667, 0xffff85eb,
360xffff8575, 0xffff8503, 0xffff8496, 0xffff842e, 0xffff83ca, 0xffff836c, 0xffff8312, 0xffff82bd,
370xffff826c, 0xffff8221, 0xffff81da, 0xffff8199, 0xffff815c, 0xffff8124, 0xffff80f1, 0xffff80c3,
380xffff8099, 0xffff8075, 0xffff8056, 0xffff803b, 0xffff8026, 0xffff8015, 0xffff8009, 0xffff8002,
39};
40static mpeg3_real_t *mpeg3_xsin1 =
41(mpeg3_real_t*)mpeg3_xsin1_fixedpoints;
42static long mpeg3_xcos2_fixedpoints[] = {
430xffff8001, 0xffff800d, 0xffff802d, 0xffff8061, 0xffff80a8, 0xffff8103, 0xffff8172, 0xffff81f4,
440xffff828a, 0xffff8333, 0xffff83ef, 0xffff84be, 0xffff85a1, 0xffff8696, 0xffff879e, 0xffff88b9,
450xffff89e5, 0xffff8b25, 0xffff8c76, 0xffff8dd9, 0xffff8f4d, 0xffff90d3, 0xffff926a, 0xffff9412,
460xffff95cb, 0xffff9794, 0xffff996d, 0xffff9b56, 0xffff9d4e, 0xffff9f56, 0xffffa16d, 0xffffa392,
470xffffa5c5, 0xffffa807, 0xffffaa55, 0xffffacb2, 0xffffaf1b, 0xffffb190, 0xffffb411, 0xffffb69f,
480xffffb937, 0xffffbbdb, 0xffffbe89, 0xffffc141, 0xffffc403, 0xffffc6ce, 0xffffc9a1, 0xffffcc7e,
490xffffcf62, 0xffffd24d, 0xffffd540, 0xffffd839, 0xffffdb39, 0xffffde3e, 0xffffe148, 0xffffe457,
500xffffe76a, 0xffffea81, 0xffffed9c, 0xfffff0b9, 0xfffff3d9, 0xfffff6fa, 0xfffffa1d, 0xfffffd41,
510xffffff9c, 0xfffffc78, 0xfffff954, 0xfffff632, 0xfffff311, 0xffffeff2, 0xffffecd5, 0xffffe9bb,
520xffffe6a5, 0xffffe393, 0xffffe085, 0xffffdd7c, 0xffffda78, 0xffffd77a, 0xffffd483, 0xffffd192,
530xffffcea8, 0xffffcbc6, 0xffffc8ec, 0xffffc61a, 0xffffc351, 0xffffc092, 0xffffbddc, 0xffffbb31,
540xffffb890, 0xffffb5fa, 0xffffb370, 0xffffb0f1, 0xffffae7f, 0xffffac19, 0xffffa9c0, 0xffffa775,
550xffffa537, 0xffffa307, 0xffffa0e6, 0xffff9ed3, 0xffff9ccf, 0xffff9ada, 0xffff98f5, 0xffff9720,
560xffff955b, 0xffff93a7, 0xffff9203, 0xffff9070, 0xffff8eee, 0xffff8d7e, 0xffff8c20, 0xffff8ad3,
570xffff8998, 0xffff8870, 0xffff875a, 0xffff8657, 0xffff8566, 0xffff8489, 0xffff83be, 0xffff8307,
580xffff8263, 0xffff81d2, 0xffff8155, 0xffff80eb, 0xffff8095, 0xffff8052, 0xffff8023, 0xffff8008,
59};
60static mpeg3_real_t *mpeg3_xcos2 =
61(mpeg3_real_t*)mpeg3_xcos2_fixedpoints;
62static long mpeg3_xsin2_fixedpoints[] = {
630xffffff9c, 0xfffffc78, 0xfffff954, 0xfffff632, 0xfffff311, 0xffffeff2, 0xffffecd5, 0xffffe9bb,
640xffffe6a5, 0xffffe393, 0xffffe085, 0xffffdd7c, 0xffffda78, 0xffffd77a, 0xffffd483, 0xffffd192,
650xffffcea8, 0xffffcbc6, 0xffffc8ec, 0xffffc61a, 0xffffc351, 0xffffc092, 0xffffbddc, 0xffffbb31,
660xffffb890, 0xffffb5fa, 0xffffb370, 0xffffb0f1, 0xffffae7f, 0xffffac19, 0xffffa9c0, 0xffffa775,
670xffffa537, 0xffffa307, 0xffffa0e6, 0xffff9ed3, 0xffff9ccf, 0xffff9ada, 0xffff98f5, 0xffff9720,
680xffff955b, 0xffff93a7, 0xffff9203, 0xffff9070, 0xffff8eee, 0xffff8d7e, 0xffff8c20, 0xffff8ad3,
690xffff8998, 0xffff8870, 0xffff875a, 0xffff8657, 0xffff8566, 0xffff8489, 0xffff83be, 0xffff8307,
700xffff8263, 0xffff81d2, 0xffff8155, 0xffff80eb, 0xffff8095, 0xffff8052, 0xffff8023, 0xffff8008,
710x00000004, 0x00000007, 0x0000000c, 0x00000010, 0x00000015, 0x0000001c, 0x00000023, 0x0000002a,
720x00000033, 0x0000003d, 0x00000048, 0x00000053, 0x00000061, 0x0000006f, 0x0000007f, 0x00000091,
730x000000a4, 0x000000b8, 0x000000cf, 0x000000e7, 0x00000101, 0x0000011d, 0x0000013b, 0x0000015b,
740x0000017e, 0x000001a3, 0x000001ca, 0x000001f4, 0x00000220, 0x0000024f, 0x00000281, 0x000002b7,
750x000002ef, 0x0000032a, 0x00000368, 0x000003aa, 0x000003ee, 0x00000437, 0x00000483, 0x000004d3,
760x00000526, 0x0000057e, 0x000005d9, 0x00000639, 0x0000069c, 0x00000704, 0x0000076f, 0x000007e0,
770x00000854, 0x000008cd, 0x0000094b, 0x000009cd, 0x00000a54, 0x00000adf, 0x00000b6f, 0x00000c04,
780x00000c9e, 0x00000d3d, 0x00000de0, 0x00000e89, 0x00000f36, 0x00000fe8, 0x0000109f, 0x0000115c,
79};
80static mpeg3_real_t *mpeg3_xsin2 =
81(mpeg3_real_t*)mpeg3_xsin2_fixedpoints;
82typedef struct { long r, i; } fixed_cmplx;
83fixed_cmplx ac3_w_d1[] = {
84 { 0x00008000, 0x00000000 },};
85fixed_cmplx ac3_w_d2[] = {
86 { 0x00008000, 0x00000000 }, { 0x00000000, 0xffff8000 },};
87fixed_cmplx ac3_w_d4[] = {
88 { 0x00008000, 0x00000000 }, { 0x00005a82, 0xffffa57e }, { 0x00000000, 0xffff8002 }, { 0xffffa580, 0xffffa580 },};
89fixed_cmplx ac3_w_d8[] = {
90 { 0x00008000, 0x00000000 }, { 0x00007641, 0xffffcf05 }, { 0x00005a81, 0xffffa580 }, { 0x000030fb, 0xffff89c4 },
91 { 0x00000002, 0xffff8007 }, { 0xffffcf09, 0xffff89c6 }, { 0xffffa587, 0xffffa583 }, { 0xffff89cb, 0xffffcf05 },};
92fixed_cmplx ac3_w_d16[] = {
93 { 0x00008000, 0x00000000 }, { 0x00007d8a, 0xffffe708 }, { 0x00007642, 0xffffcf06 }, { 0x00006a6e, 0xffffb8e7 },
94 { 0x00005a84, 0xffffa583 }, { 0x00004720, 0xffff9599 }, { 0x00003100, 0xffff89c6 }, { 0x000018ff, 0xffff827e },
95 { 0x00000008, 0xffff8008 }, { 0xffffe711, 0xffff827d }, { 0xffffcf11, 0xffff89c4 }, { 0xffffb8f2, 0xffff9595 },
96 { 0xffffa58e, 0xffffa57d }, { 0xffff95a5, 0xffffb8df }, { 0xffff89d2, 0xffffcefd }, { 0xffff8289, 0xffffe6fc },};
97fixed_cmplx ac3_w_d32[] = {
98 { 0x00008000, 0x00000000 }, { 0x00007f62, 0xfffff375 }, { 0x00007d8a, 0xffffe70a }, { 0x00007a7d, 0xffffdadc },
99 { 0x00007642, 0xffffcf0a }, { 0x000070e4, 0xffffc3b1 }, { 0x00006a70, 0xffffb8ed }, { 0x000062f6, 0xffffaed7 },
100 { 0x00005a88, 0xffffa58a }, { 0x0000513b, 0xffff9d1b }, { 0x00004726, 0xffff95a1 }, { 0x00003c62, 0xffff8f2d },
101 { 0x00003109, 0xffff89cf }, { 0x00002538, 0xffff8593 }, { 0x0000190b, 0xffff8286 }, { 0x00000ca1, 0xffff80ad },
102 { 0x00000017, 0xffff800f }, { 0xfffff38d, 0xffff80ab }, { 0xffffe723, 0xffff8281 }, { 0xffffdaf6, 0xffff858b },
103 { 0xffffcf25, 0xffff89c4 }, { 0xffffc3cc, 0xffff8f1f }, { 0xffffb908, 0xffff9591 }, { 0xffffaef3, 0xffff9d09 },
104 { 0xffffa5a6, 0xffffa575 }, { 0xffff9d37, 0xffffaebf }, { 0xffff95bb, 0xffffb8d2 }, { 0xffff8f46, 0xffffc393 },
105 { 0xffff89e7, 0xffffcee9 }, { 0xffff85aa, 0xffffdab8 }, { 0xffff829b, 0xffffe6e3 }, { 0xffff80c1, 0xfffff34b },};
106fixed_cmplx ac3_w_d64[] = {
107 { 0x00008000, 0x00000000 }, { 0x00007fd8, 0xfffff9b9 }, { 0x00007f62, 0xfffff376 }, { 0x00007e9d, 0xffffed3b },
108 { 0x00007d8a, 0xffffe70c }, { 0x00007c29, 0xffffe0ec }, { 0x00007a7c, 0xffffdae0 }, { 0x00007883, 0xffffd4eb },
109 { 0x00007641, 0xffffcf11 }, { 0x000073b6, 0xffffc955 }, { 0x000070e3, 0xffffc3bb }, { 0x00006dcb, 0xffffbe45 },
110 { 0x00006a6f, 0xffffb8f8 }, { 0x000066d2, 0xffffb3d7 }, { 0x000062f5, 0xffffaee5 }, { 0x00005edc, 0xffffaa25 },
111 { 0x00005a89, 0xffffa59a }, { 0x000055fe, 0xffffa147 }, { 0x0000513e, 0xffff9d2e }, { 0x00004c4c, 0xffff9952 },
112 { 0x0000472b, 0xffff95b6 }, { 0x000041de, 0xffff925b }, { 0x00003c69, 0xffff8f44 }, { 0x000036cf, 0xffff8c72 },
113 { 0x00003113, 0xffff89e7 }, { 0x00002b39, 0xffff87a4 }, { 0x00002544, 0xffff85ac }, { 0x00001f39, 0xffff8400 },
114 { 0x0000191b, 0xffff82a0 }, { 0x000012ed, 0xffff818d }, { 0x00000cb4, 0xffff80c8 }, { 0x00000673, 0xffff8051 },
115 { 0x0000002d, 0xffff8029 }, { 0xfffff9e8, 0xffff804f }, { 0xfffff3a7, 0xffff80c3 }, { 0xffffed6e, 0xffff8186 },
116 { 0xffffe741, 0xffff8297 }, { 0xffffe123, 0xffff83f5 }, { 0xffffdb18, 0xffff859f }, { 0xffffd524, 0xffff8795 },
117 { 0xffffcf4b, 0xffff89d5 }, { 0xffffc990, 0xffff8c5d }, { 0xffffc3f7, 0xffff8f2d }, { 0xffffbe82, 0xffff9242 },
118 { 0xffffb936, 0xffff959b }, { 0xffffb416, 0xffff9935 }, { 0xffffaf24, 0xffff9d0f }, { 0xffffaa64, 0xffffa125 },
119 { 0xffffa5d9, 0xffffa575 }, { 0xffffa186, 0xffffa9fd }, { 0xffff9d6d, 0xffffaeba }, { 0xffff9990, 0xffffb3a9 },
120 { 0xffff95f3, 0xffffb8c7 }, { 0xffff9297, 0xffffbe11 }, { 0xffff8f7f, 0xffffc383 }, { 0xffff8cac, 0xffffc91a },
121 { 0xffff8a20, 0xffffced3 }, { 0xffff87dc, 0xffffd4aa }, { 0xffff85e2, 0xffffda9c }, { 0xffff8434, 0xffffe0a5 },
122 { 0xffff82d2, 0xffffe6c1 }, { 0xffff81be, 0xffffecec }, { 0xffff80f7, 0xfffff323 }, { 0xffff807e, 0xfffff962 },};
123fixed_cmplx *ac3_w_fixedpoints[] = {
124ac3_w_d1, ac3_w_d2, ac3_w_d4, ac3_w_d8, ac3_w_d16, ac3_w_d32, ac3_w_d64, };
125#endif
126#ifdef USE_DATA_TABLES
127static long mpeg3_muls_data[] = {
1280x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1290x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1300x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1310x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1320x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1330x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1340x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1350x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1360xffff5556, 0xffff788b, 0xffff947d, 0xffffaaab, 0xffffbc46, 0xffffca3f, 0xffffd556, 0xffffde23,
1370xffffe520, 0xffffeaab, 0xffffef12, 0xfffff290, 0xfffff556, 0xfffff789, 0xfffff948, 0xfffffaab,
1380xfffffbc5, 0xfffffca4, 0xfffffd56, 0xfffffde3, 0xfffffe52, 0xfffffeab, 0xfffffef2, 0xffffff29,
1390xffffff56, 0xffffff79, 0xffffff95, 0xffffffab, 0xffffffbd, 0xffffffcb, 0xffffffd6, 0xffffffdf,
1400xffffffe6, 0xffffffeb, 0xfffffff0, 0xfffffff3, 0xfffffff6, 0xfffffff8, 0xfffffffa, 0xfffffffb,
1410xfffffffc, 0xfffffffd, 0xfffffffe, 0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000,
1420x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1430x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1440x0000aaaa, 0x00008775, 0x00006b83, 0x00005555, 0x000043ba, 0x000035c1, 0x00002aaa, 0x000021dd,
1450x00001ae0, 0x00001555, 0x000010ee, 0x00000d70, 0x00000aaa, 0x00000877, 0x000006b8, 0x00000555,
1460x0000043b, 0x0000035c, 0x000002aa, 0x0000021d, 0x000001ae, 0x00000155, 0x0000010e, 0x000000d7,
1470x000000aa, 0x00000087, 0x0000006b, 0x00000055, 0x00000043, 0x00000035, 0x0000002a, 0x00000021,
1480x0000001a, 0x00000015, 0x00000010, 0x0000000d, 0x0000000a, 0x00000008, 0x00000006, 0x00000005,
1490x00000004, 0x00000003, 0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000000,
1500x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1510x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1520x00004924, 0x00003a0d, 0x00002e13, 0x00002492, 0x00001d06, 0x00001709, 0x00001249, 0x00000e83,
1530x00000b84, 0x00000924, 0x00000741, 0x000005c2, 0x00000492, 0x000003a0, 0x000002e1, 0x00000249,
1540x000001d0, 0x00000170, 0x00000124, 0x000000e8, 0x000000b8, 0x00000092, 0x00000074, 0x0000005c,
1550x00000049, 0x0000003a, 0x0000002e, 0x00000024, 0x0000001d, 0x00000017, 0x00000012, 0x0000000e,
1560x0000000b, 0x00000009, 0x00000007, 0x00000005, 0x00000004, 0x00000003, 0x00000002, 0x00000002,
1570x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1580x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1590x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1600x00002222, 0x00001b17, 0x00001580, 0x00001111, 0x00000d8b, 0x00000ac0, 0x00000888, 0x000006c5,
1610x00000560, 0x00000444, 0x00000362, 0x000002b0, 0x00000222, 0x000001b1, 0x00000158, 0x00000111,
1620x000000d8, 0x000000ac, 0x00000088, 0x0000006c, 0x00000056, 0x00000044, 0x00000036, 0x0000002b,
1630x00000022, 0x0000001b, 0x00000015, 0x00000011, 0x0000000d, 0x0000000a, 0x00000008, 0x00000006,
1640x00000005, 0x00000004, 0x00000003, 0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001,
1650x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1660x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1670x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1680x00001084, 0x00000d1b, 0x00000a67, 0x00000842, 0x0000068d, 0x00000533, 0x00000421, 0x00000346,
1690x00000299, 0x00000210, 0x000001a3, 0x0000014c, 0x00000108, 0x000000d1, 0x000000a6, 0x00000084,
1700x00000068, 0x00000053, 0x00000042, 0x00000034, 0x00000029, 0x00000021, 0x0000001a, 0x00000014,
1710x00000010, 0x0000000d, 0x0000000a, 0x00000008, 0x00000006, 0x00000005, 0x00000004, 0x00000003,
1720x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
1730x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1740x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1750x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1760x00000820, 0x00000673, 0x0000051e, 0x00000410, 0x00000339, 0x0000028f, 0x00000208, 0x0000019c,
1770x00000147, 0x00000104, 0x000000ce, 0x000000a3, 0x00000082, 0x00000067, 0x00000051, 0x00000041,
1780x00000033, 0x00000028, 0x00000020, 0x00000019, 0x00000014, 0x00000010, 0x0000000c, 0x0000000a,
1790x00000008, 0x00000006, 0x00000005, 0x00000004, 0x00000003, 0x00000002, 0x00000002, 0x00000001,
1800x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1810x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1820x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1830x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1840x00000408, 0x00000333, 0x0000028a, 0x00000204, 0x00000199, 0x00000145, 0x00000102, 0x000000cc,
1850x000000a2, 0x00000081, 0x00000066, 0x00000051, 0x00000040, 0x00000033, 0x00000028, 0x00000020,
1860x00000019, 0x00000014, 0x00000010, 0x0000000c, 0x0000000a, 0x00000008, 0x00000006, 0x00000005,
1870x00000004, 0x00000003, 0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000000,
1880x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1890x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1900x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1910x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1920x00000202, 0x00000197, 0x00000143, 0x00000101, 0x000000cb, 0x000000a1, 0x00000080, 0x00000065,
1930x00000050, 0x00000040, 0x00000032, 0x00000028, 0x00000020, 0x00000019, 0x00000014, 0x00000010,
1940x0000000c, 0x0000000a, 0x00000008, 0x00000006, 0x00000005, 0x00000004, 0x00000003, 0x00000002,
1950x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1960x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1970x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1980x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1990x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2000x00000100, 0x000000cb, 0x000000a1, 0x00000080, 0x00000065, 0x00000050, 0x00000040, 0x00000032,
2010x00000028, 0x00000020, 0x00000019, 0x00000014, 0x00000010, 0x0000000c, 0x0000000a, 0x00000008,
2020x00000006, 0x00000005, 0x00000004, 0x00000003, 0x00000002, 0x00000002, 0x00000001, 0x00000001,
2030x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2040x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2050x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2060x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2070x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2080x00000080, 0x00000065, 0x00000050, 0x00000040, 0x00000032, 0x00000028, 0x00000020, 0x00000019,
2090x00000014, 0x00000010, 0x0000000c, 0x0000000a, 0x00000008, 0x00000006, 0x00000005, 0x00000004,
2100x00000003, 0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000,
2110x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2120x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2130x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2140x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2150x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2160x00000040, 0x00000032, 0x00000028, 0x00000020, 0x00000019, 0x00000014, 0x00000010, 0x0000000c,
2170x0000000a, 0x00000008, 0x00000006, 0x00000005, 0x00000004, 0x00000003, 0x00000002, 0x00000002,
2180x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2190x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2200x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2210x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2220x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2230x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2240x00000020, 0x00000019, 0x00000014, 0x00000010, 0x0000000c, 0x0000000a, 0x00000008, 0x00000006,
2250x00000005, 0x00000004, 0x00000003, 0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001,
2260x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2270x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2280x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2290x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2300x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2310x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2320x00000010, 0x0000000c, 0x0000000a, 0x00000008, 0x00000006, 0x00000005, 0x00000004, 0x00000003,
2330x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
2340x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2350x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2360x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2370x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2380x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2390x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2400x00000008, 0x00000006, 0x00000005, 0x00000004, 0x00000003, 0x00000002, 0x00000002, 0x00000001,
2410x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2420x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2430x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2440x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2450x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2460x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2470x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2480x00000004, 0x00000003, 0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000000,
2490x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2500x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2510x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2520x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2530x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2540x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2550x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2560x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2570x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2580x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2590x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2600x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2610x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2620x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2630x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2640xffff3334, 0xffff5d74, 0xffff7efc, 0xffff999a, 0xffffaeba, 0xffffbf7e, 0xffffcccd, 0xffffd75d,
2650xffffdfbf, 0xffffe667, 0xffffebaf, 0xffffefe0, 0xfffff334, 0xfffff5d8, 0xfffff7f0, 0xfffff99a,
2660xfffffaec, 0xfffffbf8, 0xfffffccd, 0xfffffd76, 0xfffffdfc, 0xfffffe67, 0xfffffebb, 0xfffffefe,
2670xffffff34, 0xffffff5e, 0xffffff7f, 0xffffff9a, 0xffffffaf, 0xffffffc0, 0xffffffcd, 0xffffffd8,
2680xffffffe0, 0xffffffe7, 0xffffffec, 0xfffffff0, 0xfffffff4, 0xfffffff6, 0xfffffff8, 0xfffffffa,
2690xfffffffb, 0xfffffffc, 0xfffffffd, 0xfffffffe, 0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff,
2700x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2710x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2720xffff999a, 0xffffaeba, 0xffffbf7e, 0xffffcccd, 0xffffd75d, 0xffffdfbf, 0xffffe667, 0xffffebaf,
2730xffffefe0, 0xfffff334, 0xfffff5d8, 0xfffff7f0, 0xfffff99a, 0xfffffaec, 0xfffffbf8, 0xfffffccd,
2740xfffffd76, 0xfffffdfc, 0xfffffe67, 0xfffffebb, 0xfffffefe, 0xffffff34, 0xffffff5e, 0xffffff7f,
2750xffffff9a, 0xffffffaf, 0xffffffc0, 0xffffffcd, 0xffffffd8, 0xffffffe0, 0xffffffe7, 0xffffffec,
2760xfffffff0, 0xfffffff4, 0xfffffff6, 0xfffffff8, 0xfffffffa, 0xfffffffb, 0xfffffffc, 0xfffffffd,
2770xfffffffe, 0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000,
2780x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2790x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2800x00006666, 0x00005146, 0x00004082, 0x00003333, 0x000028a3, 0x00002041, 0x00001999, 0x00001451,
2810x00001020, 0x00000ccc, 0x00000a28, 0x00000810, 0x00000666, 0x00000514, 0x00000408, 0x00000333,
2820x0000028a, 0x00000204, 0x00000199, 0x00000145, 0x00000102, 0x000000cc, 0x000000a2, 0x00000081,
2830x00000066, 0x00000051, 0x00000040, 0x00000033, 0x00000028, 0x00000020, 0x00000019, 0x00000014,
2840x00000010, 0x0000000c, 0x0000000a, 0x00000008, 0x00000006, 0x00000005, 0x00000004, 0x00000003,
2850x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
2860x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2870x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2880x0000cccc, 0x0000a28c, 0x00008104, 0x00006666, 0x00005146, 0x00004082, 0x00003333, 0x000028a3,
2890x00002041, 0x00001999, 0x00001451, 0x00001020, 0x00000ccc, 0x00000a28, 0x00000810, 0x00000666,
2900x00000514, 0x00000408, 0x00000333, 0x0000028a, 0x00000204, 0x00000199, 0x00000145, 0x00000102,
2910x000000cc, 0x000000a2, 0x00000081, 0x00000066, 0x00000051, 0x00000040, 0x00000033, 0x00000028,
2920x00000020, 0x00000019, 0x00000014, 0x00000010, 0x0000000c, 0x0000000a, 0x00000008, 0x00000006,
2930x00000005, 0x00000004, 0x00000003, 0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001,
2940x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2950x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2960xffff1c72, 0xffff4b64, 0xffff70a7, 0xffff8e39, 0xffffa5b2, 0xffffb854, 0xffffc71d, 0xffffd2d9,
2970xffffdc2a, 0xffffe38f, 0xffffe96d, 0xffffee15, 0xfffff1c8, 0xfffff4b7, 0xfffff70b, 0xfffff8e4,
2980xfffffa5c, 0xfffffb86, 0xfffffc72, 0xfffffd2e, 0xfffffdc3, 0xfffffe39, 0xfffffe97, 0xfffffee2,
2990xffffff1d, 0xffffff4c, 0xffffff71, 0xffffff8f, 0xffffffa6, 0xffffffb9, 0xffffffc8, 0xffffffd3,
3000xffffffdd, 0xffffffe4, 0xffffffea, 0xffffffef, 0xfffffff2, 0xfffffff5, 0xfffffff8, 0xfffffff9,
3010xfffffffb, 0xfffffffc, 0xfffffffd, 0xfffffffe, 0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff,
3020x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3030x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3040xffff8e39, 0xffffa5b2, 0xffffb854, 0xffffc71d, 0xffffd2d9, 0xffffdc2a, 0xffffe38f, 0xffffe96d,
3050xffffee15, 0xfffff1c8, 0xfffff4b7, 0xfffff70b, 0xfffff8e4, 0xfffffa5c, 0xfffffb86, 0xfffffc72,
3060xfffffd2e, 0xfffffdc3, 0xfffffe39, 0xfffffe97, 0xfffffee2, 0xffffff1d, 0xffffff4c, 0xffffff71,
3070xffffff8f, 0xffffffa6, 0xffffffb9, 0xffffffc8, 0xffffffd3, 0xffffffdd, 0xffffffe4, 0xffffffea,
3080xffffffef, 0xfffffff2, 0xfffffff5, 0xfffffff8, 0xfffffff9, 0xfffffffb, 0xfffffffc, 0xfffffffd,
3090xfffffffe, 0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000,
3100x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3110x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3120xffffc71d, 0xffffd2d9, 0xffffdc2a, 0xffffe38f, 0xffffe96d, 0xffffee15, 0xfffff1c8, 0xfffff4b7,
3130xfffff70b, 0xfffff8e4, 0xfffffa5c, 0xfffffb86, 0xfffffc72, 0xfffffd2e, 0xfffffdc3, 0xfffffe39,
3140xfffffe97, 0xfffffee2, 0xffffff1d, 0xffffff4c, 0xffffff71, 0xffffff8f, 0xffffffa6, 0xffffffb9,
3150xffffffc8, 0xffffffd3, 0xffffffdd, 0xffffffe4, 0xffffffea, 0xffffffef, 0xfffffff2, 0xfffffff5,
3160xfffffff8, 0xfffffff9, 0xfffffffb, 0xfffffffc, 0xfffffffd, 0xfffffffe, 0xfffffffe, 0xffffffff,
3170xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3180x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3190x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3200x000038e3, 0x00002d27, 0x000023d6, 0x00001c71, 0x00001693, 0x000011eb, 0x00000e38, 0x00000b49,
3210x000008f5, 0x0000071c, 0x000005a4, 0x0000047a, 0x0000038e, 0x000002d2, 0x0000023d, 0x000001c7,
3220x00000169, 0x0000011e, 0x000000e3, 0x000000b4, 0x0000008f, 0x00000071, 0x0000005a, 0x00000047,
3230x00000038, 0x0000002d, 0x00000023, 0x0000001c, 0x00000016, 0x00000011, 0x0000000e, 0x0000000b,
3240x00000008, 0x00000007, 0x00000005, 0x00000004, 0x00000003, 0x00000002, 0x00000002, 0x00000001,
3250x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3260x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3270x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3280x000071c7, 0x00005a4e, 0x000047ac, 0x000038e3, 0x00002d27, 0x000023d6, 0x00001c71, 0x00001693,
3290x000011eb, 0x00000e38, 0x00000b49, 0x000008f5, 0x0000071c, 0x000005a4, 0x0000047a, 0x0000038e,
3300x000002d2, 0x0000023d, 0x000001c7, 0x00000169, 0x0000011e, 0x000000e3, 0x000000b4, 0x0000008f,
3310x00000071, 0x0000005a, 0x00000047, 0x00000038, 0x0000002d, 0x00000023, 0x0000001c, 0x00000016,
3320x00000011, 0x0000000e, 0x0000000b, 0x00000008, 0x00000007, 0x00000005, 0x00000004, 0x00000003,
3330x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
3340x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3350x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3360x0000e38e, 0x0000b49c, 0x00008f59, 0x000071c7, 0x00005a4e, 0x000047ac, 0x000038e3, 0x00002d27,
3370x000023d6, 0x00001c71, 0x00001693, 0x000011eb, 0x00000e38, 0x00000b49, 0x000008f5, 0x0000071c,
3380x000005a4, 0x0000047a, 0x0000038e, 0x000002d2, 0x0000023d, 0x000001c7, 0x00000169, 0x0000011e,
3390x000000e3, 0x000000b4, 0x0000008f, 0x00000071, 0x0000005a, 0x00000047, 0x00000038, 0x0000002d,
3400x00000023, 0x0000001c, 0x00000016, 0x00000011, 0x0000000e, 0x0000000b, 0x00000008, 0x00000007,
3410x00000005, 0x00000004, 0x00000003, 0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001,
3420x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3430x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,};
344#endif
345#ifdef USE_DATA_TABLES
346static long mpeg3_gainpow2_data[] = {
3470x05a82799, 0x04c1bf82, 0x04000000, 0x035d13f3, 0x02d413cc, 0x0260dfc1, 0x02000000, 0x01ae89f9,
3480x016a09e6, 0x01306fe0, 0x01000000, 0x00d744fc, 0x00b504f3, 0x009837f0, 0x00800000, 0x006ba27e,
3490x005a8279, 0x004c1bf8, 0x00400000, 0x0035d13f, 0x002d413c, 0x00260dfc, 0x00200000, 0x001ae89f,
3500x0016a09e, 0x001306fe, 0x00100000, 0x000d744f, 0x000b504f, 0x0009837f, 0x00080000, 0x0006ba27,
3510x0005a827, 0x0004c1bf, 0x00040000, 0x00035d13, 0x0002d413, 0x000260df, 0x00020000, 0x0001ae89,
3520x00016a09, 0x0001306f, 0x00010000, 0x0000d744, 0x0000b504, 0x00009837, 0x00008000, 0x00006ba2,
3530x00005a82, 0x00004c1b, 0x00004000, 0x000035d1, 0x00002d41, 0x0000260d, 0x00002000, 0x00001ae8,
3540x000016a0, 0x00001306, 0x00001000, 0x00000d74, 0x00000b50, 0x00000983, 0x00000800, 0x000006ba,
3550x000005a8, 0x000004c1, 0x00000400, 0x0000035d, 0x000002d4, 0x00000260, 0x00000200, 0x000001ae,
3560x0000016a, 0x00000130, 0x00000100, 0x000000d7, 0x000000b5, 0x00000098, 0x00000080, 0x0000006b,
3570x0000005a, 0x0000004c, 0x00000040, 0x00000035, 0x0000002d, 0x00000026, 0x00000020, 0x0000001a,
3580x00000016, 0x00000013, 0x00000010, 0x0000000d, 0x0000000b, 0x00000009, 0x00000008, 0x00000006,
3590x00000005, 0x00000004, 0x00000004, 0x00000003, 0x00000002, 0x00000002, 0x00000002, 0x00000001,
3600x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3610x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3620x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3630x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3640x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3650x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3660x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3670x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3680x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3690x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3700x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3710x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3720x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3730x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3740x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3750x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3760x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3770x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3780x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3790x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3800x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3810x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3820x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3830x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3840x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3850x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3860x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3870x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3880x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3890x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3900x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3910x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3920x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3930x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3940x00000000, 0x00000000,};
395#endif
396#ifdef USE_DATA_TABLES
397static long mpeg3_ispow_data[] = {
3980x00000000, 0x00008000, 0x0001428a, 0x000229d2, 0x00032cbf, 0x00044662, 0x0005738c, 0x0006b1fc,
3990x0007ffff, 0x00095c41, 0x000ac5ad, 0x000c3b5d, 0x000dbc8f, 0x000f489e, 0x0010def9, 0x00127f20,
4000x001428a2, 0x0015db1b, 0x00179630, 0x0019598d, 0x001b24e8, 0x001cf7fc, 0x001ed28a, 0x0020b458,
4010x00229d2e, 0x00248cdb, 0x0026832f, 0x00287fff, 0x002a8322, 0x002c8c70, 0x002e9bc5, 0x0030b0ff,
4020x0032cbfd, 0x0034eca0, 0x003712ca, 0x00393e60, 0x003b6f47, 0x003da567, 0x003fe0a5, 0x004220ed,
4030x00446627, 0x0046b03e, 0x0048ff1e, 0x004b52b3, 0x004daaeb, 0x005007b4, 0x005268fc, 0x0054ceb2,
4040x005738c7, 0x0059a72a, 0x005c19cd, 0x005e90a1, 0x00610b98, 0x00638aa4, 0x00660db9, 0x006894c9,
4050x006b1fc8, 0x006daeaa, 0x00704163, 0x0072d7e8, 0x0075722e, 0x0078102b, 0x007ab1d3, 0x007d571e,
4060x007fffff, 0x0082ac70, 0x00855c65, 0x00880fd6, 0x008ac6b9, 0x008d8107, 0x00903eb7, 0x0092ffc0,
4070x0095c41a, 0x00988bbe, 0x009b56a4, 0x009e24c4, 0x00a0f617, 0x00a3ca96, 0x00a6a239, 0x00a97cfa,
4080x00ac5ad2, 0x00af3bbb, 0x00b21fad, 0x00b506a3, 0x00b7f096, 0x00badd81, 0x00bdcd5d, 0x00c0c025,
4090x00c3b5d2, 0x00c6ae60, 0x00c9a9c8, 0x00cca805, 0x00cfa912, 0x00d2acea, 0x00d5b387, 0x00d8bce5,
4100x00dbc8fe, 0x00ded7ce, 0x00e1e950, 0x00e4fd7e, 0x00e81456, 0x00eb2dd1, 0x00ee49ec, 0x00f168a2,
4110x00f489ef, 0x00f7adce, 0x00fad43c, 0x00fdfd34, 0x010128b2, 0x010456b2, 0x01078731, 0x010aba29,
4120x010def99, 0x0111277b, 0x011461cc, 0x01179e89, 0x011addae, 0x011e1f37, 0x01216320, 0x0124a967,
4130x0127f208, 0x012b3d00, 0x012e8a4b, 0x0131d9e6, 0x01352bce, 0x01387fff, 0x013bd678, 0x013f2f33,
4140x01428a2f, 0x0145e768, 0x014946dc, 0x014ca888, 0x01500c68, 0x01537279, 0x0156daba, 0x015a4527,
4150x015db1bd, 0x0161207a, 0x0164915b, 0x0168045d, 0x016b797e, 0x016ef0bb, 0x01726a12, 0x0175e580,
4160x01796302, 0x017ce297, 0x0180643b, 0x0183e7ec, 0x01876da9, 0x018af56e, 0x018e7f38, 0x01920b07,
4170x019598d8, 0x019928a8, 0x019cba74, 0x01a04e3c, 0x01a3e3fd, 0x01a77bb4, 0x01ab155f, 0x01aeb0fd,
4180x01b24e8b, 0x01b5ee07, 0x01b98f70, 0x01bd32c2, 0x01c0d7fc, 0x01c47f1d, 0x01c82821, 0x01cbd308,
4190x01cf7fcf, 0x01d32e74, 0x01d6def6, 0x01da9153, 0x01de4588, 0x01e1fb94, 0x01e5b375, 0x01e96d29,
4200x01ed28af, 0x01f0e604, 0x01f4a528, 0x01f86617, 0x01fc28d2, 0x01ffed55, 0x0203b39f, 0x02077baf,
4210x020b4582, 0x020f1118, 0x0212de6e, 0x0216ad83, 0x021a7e56, 0x021e50e4, 0x0222252d, 0x0225fb2e,
4220x0229d2e6, 0x022dac54, 0x02318776, 0x0235644b, 0x023942d1, 0x023d2306, 0x024104e9, 0x0244e879,
4230x0248cdb5, 0x024cb49a, 0x02509d28, 0x0254875c, 0x02587337, 0x025c60b5, 0x02604fd7, 0x0264409a,
4240x026832fd, 0x026c26ff, 0x02701c9f, 0x027413db, 0x02780cb1, 0x027c0722, 0x0280032a, 0x028400ca,
4250x0287ffff, 0x028c00ca, 0x02900327, 0x02940716, 0x02980c97, 0x029c13a7, 0x02a01c45, 0x02a42670,
4260x02a83228, 0x02ac3f6a, 0x02b04e36, 0x02b45e8b, 0x02b87067, 0x02bc83c9, 0x02c098b1, 0x02c4af1c,
4270x02c8c70a, 0x02cce07a, 0x02d0fb6a, 0x02d517da, 0x02d935c9, 0x02dd5534, 0x02e1761c, 0x02e59880,
4280x02e9bc5d, 0x02ede1b3, 0x02f20882, 0x02f630c8, 0x02fa5a83, 0x02fe85b4, 0x0302b258, 0x0306e070,
4290x030b0ff9, 0x030f40f3, 0x0313735e, 0x0317a737, 0x031bdc7e, 0x03201333, 0x03244b53, 0x032884de,
4300x032cbfd4, 0x0330fc33, 0x033539fa, 0x03397929, 0x033db9be, 0x0341fbb8, 0x03463f17, 0x034a83da,
4310x034eca00, 0x03531187, 0x03575a6f, 0x035ba4b8, 0x035ff060, 0x03643d66, 0x03688bc9, 0x036cdb8a,
4320x03712ca6, 0x03757f1d, 0x0379d2ee, 0x037e2818, 0x03827e9a, 0x0386d674, 0x038b2fa5, 0x038f8a2c,
4330x0393e608, 0x03984338, 0x039ca1bc, 0x03a10192, 0x03a562ba, 0x03a9c533, 0x03ae28fd, 0x03b28e16,
4340x03b6f47e, 0x03bb5c33, 0x03bfc536, 0x03c42f85, 0x03c89b20, 0x03cd0806, 0x03d17636, 0x03d5e5af,
4350x03da5671, 0x03dec87b, 0x03e33bcc, 0x03e7b063, 0x03ec2640, 0x03f09d62, 0x03f515c9, 0x03f98f73,
4360x03fe0a5f, 0x0402868e, 0x040703fe, 0x040b82af, 0x041002a0, 0x041483d1, 0x04190640, 0x041d89ec,
4370x04220ed7, 0x042694fd, 0x042b1c60, 0x042fa4fe, 0x04342ed6, 0x0438b9e9, 0x043d4635, 0x0441d3b9,
4380x04466275, 0x044af269, 0x044f8393, 0x045415f3, 0x0458a988, 0x045d3e53, 0x0461d451, 0x04666b83,
4390x046b03e7, 0x046f9d7e, 0x04743846, 0x0478d440, 0x047d716a, 0x04820fc3, 0x0486af4c, 0x048b5003,
4400x048ff1e8, 0x049494fa, 0x04993939, 0x049ddea5, 0x04a2853c, 0x04a72cfd, 0x04abd5ea, 0x04b07fff,
4410x04b52b3f, 0x04b9d7a6, 0x04be8536, 0x04c333ee, 0x04c7e3cc, 0x04cc94d1, 0x04d146fb, 0x04d5fa4b,
4420x04daaebf, 0x04df6458, 0x04e41b14, 0x04e8d2f3, 0x04ed8bf5, 0x04f24618, 0x04f7015d, 0x04fbbdc3,
4430x05007b49, 0x050539ef, 0x0509f9b4, 0x050eba98, 0x05137c9a, 0x05183fba, 0x051d03f6, 0x0521c950,
4440x05268fc6, 0x052b5757, 0x05302003, 0x0534e9ca, 0x0539b4ab, 0x053e80a5, 0x05434db9, 0x05481be5,
4450x054ceb29, 0x0551bb85, 0x05568cf8, 0x055b5f81, 0x05603321, 0x056507d6, 0x0569dda0, 0x056eb47f,
4460x05738c72, 0x05786578, 0x057d3f92, 0x05821abe, 0x0586f6fd, 0x058bd44e, 0x0590b2af, 0x05959222,
4470x059a72a5, 0x059f5438, 0x05a436da, 0x05a91a8c, 0x05adff4b, 0x05b2e519, 0x05b7cbf5, 0x05bcb3dd,
4480x05c19cd3, 0x05c686d4, 0x05cb71e2, 0x05d05dfb, 0x05d54b1f, 0x05da394d, 0x05df2885, 0x05e418c7,
4490x05e90a12, 0x05edfc66, 0x05f2efc2, 0x05f7e426, 0x05fcd992, 0x0601d004, 0x0606c77d, 0x060bbffd,
4500x0610b982, 0x0615b40c, 0x061aaf9b, 0x061fac2f, 0x0624a9c7, 0x0629a863, 0x062ea802, 0x0633a8a3,
4510x0638aa47, 0x063dacee, 0x0642b095, 0x0647b53f, 0x064cbae8, 0x0651c193, 0x0656c93d, 0x065bd1e7,
4520x0660db90, 0x0665e639, 0x066af1df, 0x066ffe84, 0x06750c26, 0x067a1ac6, 0x067f2a62, 0x06843afb,
4530x06894c90, 0x068e5f21, 0x069372ad, 0x06988735, 0x069d9cb6, 0x06a2b332, 0x06a7caa8, 0x06ace318,
4540x06b1fc80, 0x06b716e2, 0x06bc323b, 0x06c14e8d, 0x06c66bd6, 0x06cb8a17, 0x06d0a94e, 0x06d5c97c,
4550x06daeaa0, 0x06e00cba, 0x06e52fca, 0x06ea53ce, 0x06ef78c8, 0x06f49eb5, 0x06f9c597, 0x06feed6d,
4560x07041635, 0x07093ff1, 0x070e6aa0, 0x07139640, 0x0718c2d3, 0x071df057, 0x07231ecd, 0x07284e33,
4570x072d7e8a, 0x0732afd2, 0x0737e209, 0x073d1530, 0x07424946, 0x07477e4a, 0x074cb43e, 0x0751eb20,
4580x075722ef, 0x075c5bac, 0x07619556, 0x0766cfee, 0x076c0b71, 0x077147e1, 0x0776853d, 0x077bc385,
4590x078102b8, 0x078642d6, 0x078b83de, 0x0790c5d1, 0x079608ae, 0x079b4c74, 0x07a09124, 0x07a5d6bd,
4600x07ab1d3e, 0x07b064a8, 0x07b5acfa, 0x07baf634, 0x07c04056, 0x07c58b5e, 0x07cad74e, 0x07d02424,
4610x07d571e0, 0x07dac082, 0x07e0100a, 0x07e56077, 0x07eab1ca, 0x07f00401, 0x07f5571c, 0x07faab1c,
4620x07ffffff, 0x080555c7, 0x080aac71, 0x081003fe, 0x08155c6e, 0x081ab5c0, 0x08200ff5, 0x08256b0b,
4630x082ac703, 0x083023dc, 0x08358196, 0x083ae030, 0x08403fab, 0x0845a006, 0x084b0141, 0x0850635b,
4640x0855c654, 0x085b2a2d, 0x08608ee4, 0x0865f479, 0x086b5aed, 0x0870c23e, 0x08762a6d, 0x087b9379,
4650x0880fd62, 0x08866828, 0x088bd3ca, 0x08914048, 0x0896ada3, 0x089c1bd8, 0x08a18aea, 0x08a6fad6,
4660x08ac6b9d, 0x08b1dd3f, 0x08b74fbb, 0x08bcc311, 0x08c23741, 0x08c7ac4a, 0x08cd222c, 0x08d298e8,
4670x08d8107c, 0x08dd88e8, 0x08e3022d, 0x08e87c49, 0x08edf73d, 0x08f37309, 0x08f8efac, 0x08fe6d25,
4680x0903eb75, 0x09096a9c, 0x090eea99, 0x09146b6b, 0x0919ed13, 0x091f6f91, 0x0924f2e3, 0x092a770b,
4690x092ffc06, 0x093581d7, 0x093b087b, 0x09408ff3, 0x0946183f, 0x094ba15e, 0x09512b51, 0x0956b616,
4700x095c41ae, 0x0961ce18, 0x09675b54, 0x096ce962, 0x09727842, 0x097807f3, 0x097d9876, 0x098329c9,
4710x0988bbed, 0x098e4ee1, 0x0993e2a6, 0x0999773a, 0x099f0c9f, 0x09a4a2d3, 0x09aa39d6, 0x09afd1a8,
4720x09b56a49, 0x09bb03b8, 0x09c09df6, 0x09c63902, 0x09cbd4dc, 0x09d17183, 0x09d70ef8, 0x09dcad3a,
4730x09e24c49, 0x09e7ec25, 0x09ed8ccd, 0x09f32e41, 0x09f8d082, 0x09fe738e, 0x0a041766, 0x0a09bc09,
4740x0a0f6178, 0x0a1507b1, 0x0a1aaeb5, 0x0a205684, 0x0a25ff1c, 0x0a2ba87f, 0x0a3152ac, 0x0a36fda2,
4750x0a3ca962, 0x0a4255ea, 0x0a48033c, 0x0a4db157, 0x0a536039, 0x0a590fe5, 0x0a5ec058, 0x0a647193,
4760x0a6a2396, 0x0a6fd660, 0x0a7589f2, 0x0a7b3e4b, 0x0a80f36a, 0x0a86a950, 0x0a8c5ffc, 0x0a92176f,
4770x0a97cfa7, 0x0a9d88a5, 0x0aa34269, 0x0aa8fcf2, 0x0aaeb840, 0x0ab47453, 0x0aba312b, 0x0abfeec8,
4780x0ac5ad28, 0x0acb6c4d, 0x0ad12c36, 0x0ad6ece2, 0x0adcae52, 0x0ae27085, 0x0ae8337b, 0x0aedf734,
4790x0af3bbb0, 0x0af980ee, 0x0aff46ef, 0x0b050db2, 0x0b0ad536, 0x0b109d7c, 0x0b166684, 0x0b1c304d,
4800x0b21fad7, 0x0b27c622, 0x0b2d922e, 0x0b335efa, 0x0b392c87, 0x0b3efad3, 0x0b44c9e0, 0x0b4a99ac,
4810x0b506a38, 0x0b563b83, 0x0b5c0d8e, 0x0b61e057, 0x0b67b3df, 0x0b6d8826, 0x0b735d2b, 0x0b7932ee,
4820x0b7f096f, 0x0b84e0ae, 0x0b8ab8ab, 0x0b909165, 0x0b966add, 0x0b9c4511, 0x0ba22003, 0x0ba7fbb1,
4830x0badd81b, 0x0bb3b542, 0x0bb99326, 0x0bbf71c5, 0x0bc55120, 0x0bcb3136, 0x0bd11208, 0x0bd6f395,
4840x0bdcd5dd, 0x0be2b8e0, 0x0be89c9e, 0x0bee8116, 0x0bf46649, 0x0bfa4c36, 0x0c0032dc, 0x0c061a3d,
4850x0c0c0257, 0x0c11eb2a, 0x0c17d4b7, 0x0c1dbefd, 0x0c23a9fc, 0x0c2995b3, 0x0c2f8223, 0x0c356f4c,
4860x0c3b5d2c, 0x0c414bc5, 0x0c473b16, 0x0c4d2b1e, 0x0c531bde, 0x0c590d55, 0x0c5eff83, 0x0c64f268,
4870x0c6ae604, 0x0c70da57, 0x0c76cf60, 0x0c7cc51f, 0x0c82bb95, 0x0c88b2c1, 0x0c8eaaa2, 0x0c94a339,
4880x0c9a9c85, 0x0ca09687, 0x0ca6913e, 0x0cac8caa, 0x0cb288ca, 0x0cb885a0, 0x0cbe8329, 0x0cc48167,
4890x0cca8059, 0x0cd07fff, 0x0cd68059, 0x0cdc8167, 0x0ce28328, 0x0ce8859c, 0x0cee88c4, 0x0cf48c9e,
4900x0cfa912b, 0x0d00966b, 0x0d069c5d, 0x0d0ca302, 0x0d12aa59, 0x0d18b262, 0x0d1ebb1d, 0x0d24c489,
4910x0d2acea7, 0x0d30d976, 0x0d36e4f7, 0x0d3cf128, 0x0d42fe0b, 0x0d490b9e, 0x0d4f19e2, 0x0d5528d6,
4920x0d5b387b, 0x0d6148cf, 0x0d6759d4, 0x0d6d6b88, 0x0d737dec, 0x0d799100, 0x0d7fa4c3, 0x0d85b935,
4930x0d8bce56, 0x0d91e426, 0x0d97faa4, 0x0d9e11d1, 0x0da429ad, 0x0daa4237, 0x0db05b6f, 0x0db67555,
4940x0dbc8fe9, 0x0dc2ab2a, 0x0dc8c719, 0x0dcee3b5, 0x0dd500ff, 0x0ddb1ef5, 0x0de13d99, 0x0de75ce9,
4950x0ded7ce6, 0x0df39d8f, 0x0df9bee5, 0x0dffe0e7, 0x0e060394, 0x0e0c26ee, 0x0e124af4, 0x0e186fa5,
4960x0e1e9501, 0x0e24bb09, 0x0e2ae1bb, 0x0e310919, 0x0e373122, 0x0e3d59d5, 0x0e438333, 0x0e49ad3c,
4970x0e4fd7ee, 0x0e56034b, 0x0e5c2f52, 0x0e625c02, 0x0e68895d, 0x0e6eb761, 0x0e74e60e, 0x0e7b1564,
4980x0e814564, 0x0e87760d, 0x0e8da75e, 0x0e93d959, 0x0e9a0bfb, 0x0ea03f47, 0x0ea6733a, 0x0eaca7d6,
4990x0eb2dd1a, 0x0eb91305, 0x0ebf4999, 0x0ec580d4, 0x0ecbb8b6, 0x0ed1f140, 0x0ed82a71, 0x0ede6449,
5000x0ee49ec8, 0x0eead9ed, 0x0ef115ba, 0x0ef7522d, 0x0efd8f46, 0x0f03cd05, 0x0f0a0b6b, 0x0f104a76,
5010x0f168a28, 0x0f1cca7f, 0x0f230b7b, 0x0f294d1d, 0x0f2f8f65, 0x0f35d251, 0x0f3c15e3, 0x0f425a19,
5020x0f489ef4, 0x0f4ee474, 0x0f552a98, 0x0f5b7161, 0x0f61b8ce, 0x0f6800df, 0x0f6e4994, 0x0f7492ed,
5030x0f7adce9, 0x0f81278a, 0x0f8772cd, 0x0f8dbeb4, 0x0f940b3e, 0x0f9a586b, 0x0fa0a63c, 0x0fa6f4af,
5040x0fad43c4, 0x0fb3937c, 0x0fb9e3d7, 0x0fc034d4, 0x0fc68673, 0x0fccd8b4, 0x0fd32b97, 0x0fd97f1c,
5050x0fdfd343, 0x0fe6280b, 0x0fec7d74, 0x0ff2d37f, 0x0ff92a2b, 0x0fff8178, 0x1005d966, 0x100c31f5,
5060x10128b24, 0x1018e4f4, 0x101f3f64, 0x10259a75, 0x102bf626, 0x10325277, 0x1038af67, 0x103f0cf8,
5070x10456b28, 0x104bc9f8, 0x10522967, 0x10588976, 0x105eea24, 0x10654b70, 0x106bad5c, 0x10720fe7,
5080x10787310, 0x107ed6d8, 0x10853b3f, 0x108ba043, 0x109205e6, 0x10986c27, 0x109ed307, 0x10a53a83,
5090x10aba29e, 0x10b20b57, 0x10b874ac, 0x10bedea0, 0x10c54930, 0x10cbb45e, 0x10d22029, 0x10d88c90,
5100x10def995, 0x10e56736, 0x10ebd574, 0x10f2444e, 0x10f8b3c5, 0x10ff23d8, 0x11059487, 0x110c05d2,
5110x111277b9, 0x1118ea3b, 0x111f5d59, 0x1125d113, 0x112c4568, 0x1132ba59, 0x11392fe5, 0x113fa60c,
5120x11461ccd, 0x114c942a, 0x11530c22, 0x115984b4, 0x115ffde0, 0x116677a7, 0x116cf209, 0x11736d04,
5130x1179e89a, 0x118064c9, 0x1186e192, 0x118d5ef5, 0x1193dcf2, 0x119a5b88, 0x11a0dab8, 0x11a75a81,
5140x11addae3, 0x11b45bde, 0x11badd72, 0x11c15f9f, 0x11c7e265, 0x11ce65c4, 0x11d4e9bb, 0x11db6e4a,
5150x11e1f372, 0x11e87931, 0x11eeff89, 0x11f58679, 0x11fc0e01, 0x12029621, 0x12091ed8, 0x120fa827,
5160x1216320d, 0x121cbc8a, 0x1223479f, 0x1229d34b, 0x12305f8e, 0x1236ec68, 0x123d79d9, 0x124407e0,
5170x124a967e, 0x125125b2, 0x1257b57d, 0x125e45de, 0x1264d6d6, 0x126b6863, 0x1271fa86, 0x12788d40,
5180x127f208f, 0x1285b473, 0x128c48ed, 0x1292ddfd, 0x129973a2, 0x12a009dc, 0x12a6a0ab, 0x12ad3810,
5190x12b3d009, 0x12ba6897, 0x12c101ba, 0x12c79b71, 0x12ce35bd, 0x12d4d09e, 0x12db6c13, 0x12e2081b,
5200x12e8a4b9, 0x12ef41ea, 0x12f5dfaf, 0x12fc7e07, 0x13031cf4, 0x1309bc74, 0x13105c88, 0x1316fd2f,
5210x131d9e69, 0x13244036, 0x132ae297, 0x1331858b, 0x13382911, 0x133ecd2b, 0x134571d7, 0x134c1716,
5220x1352bce7, 0x1359634a, 0x13600a40, 0x1366b1c9, 0x136d59e3, 0x1374028f, 0x137aabce, 0x1381559e,
5230x1387ffff, 0x138eaaf3, 0x13955678, 0x139c028e, 0x13a2af36, 0x13a95c6f, 0x13b00a39, 0x13b6b895,
5240x13bd6781, 0x13c416fe, 0x13cac70c, 0x13d177aa, 0x13d828d9, 0x13deda99, 0x13e58ce9, 0x13ec3fc9,
5250x13f2f33a, 0x13f9a73a, 0x14005bcb, 0x140710eb, 0x140dc69c, 0x14147cdc, 0x141b33ab, 0x1421eb0a,
5260x1428a2f9, 0x142f5b77, 0x14361484, 0x143cce21, 0x1443884c, 0x144a4307, 0x1450fe50, 0x1457ba28,
5270x145e768f, 0x14653384, 0x146bf108, 0x1472af1b, 0x14796dbb, 0x14802cea, 0x1486eca8, 0x148dacf3,
5280x14946dcc, 0x149b2f33, 0x14a1f128, 0x14a8b3aa, 0x14af76ba, 0x14b63a58, 0x14bcfe83, 0x14c3c33b,
5290x14ca8881, 0x14d14e54, 0x14d814b4, 0x14dedba0, 0x14e5a31a, 0x14ec6b21, 0x14f333b4, 0x14f9fcd4,
5300x1500c680, 0x150790b9, 0x150e5b7e, 0x151526cf, 0x151bf2ad, 0x1522bf17, 0x15298c0c, 0x1530598e,
5310x1537279b, 0x153df634, 0x1544c559, 0x154b950a, 0x15526545, 0x1559360d, 0x1560075f, 0x1566d93d,
5320x156daba6, 0x15747e99, 0x157b5218, 0x15822622, 0x1588fab6, 0x158fcfd6, 0x1596a57f, 0x159d7bb4,
5330x15a45272, 0x15ab29bc, 0x15b2018f, 0x15b8d9ed, 0x15bfb2d4, 0x15c68c46, 0x15cd6641, 0x15d440c7,
5340x15db1bd6, 0x15e1f76f, 0x15e8d391, 0x15efb03d, 0x15f68d73, 0x15fd6b31, 0x16044979, 0x160b284a,
5350x161207a5, 0x1618e788, 0x161fc7f4, 0x1626a8e9, 0x162d8a67, 0x16346c6d, 0x163b4efc, 0x16423213,
5360x164915b3, 0x164ff9dc, 0x1656de8c, 0x165dc3c5, 0x1664a985, 0x166b8fce, 0x1672769f, 0x16795df7,
5370x168045d8, 0x16872e40, 0x168e172f, 0x169500a7, 0x169beaa5, 0x16a2d52b, 0x16a9c038, 0x16b0abcd,
5380x16b797e8, 0x16be848b, 0x16c571b4, 0x16cc5f65, 0x16d34d9c, 0x16da3c5a, 0x16e12b9e, 0x16e81b69,
5390x16ef0bbb, 0x16f5fc93, 0x16fcedf1, 0x1703dfd6, 0x170ad241, 0x1711c531, 0x1718b8a8, 0x171faca5,
5400x1726a127, 0x172d9630, 0x17348bbe, 0x173b81d1, 0x1742786b, 0x17496f89, 0x1750672d, 0x17575f56,
5410x175e5805, 0x17655139, 0x176c4af1, 0x1773452f, 0x177a3ff2, 0x17813b39, 0x17883705, 0x178f3356,
5420x1796302c, 0x179d2d86, 0x17a42b64, 0x17ab29c7, 0x17b228ae, 0x17b92819, 0x17c02809, 0x17c7287c,
5430x17ce2974, 0x17d52aef, 0x17dc2cef, 0x17e32f72, 0x17ea3278, 0x17f13603, 0x17f83a11, 0x17ff3ea2,
5440x180643b7, 0x180d494f, 0x18144f6a, 0x181b5609, 0x18225d2a, 0x182964cf, 0x18306cf6, 0x183775a1,
5450x183e7ece, 0x1845887e, 0x184c92b0, 0x18539d65, 0x185aa89d, 0x1861b457, 0x1868c093, 0x186fcd52,
5460x1876da93, 0x187de856, 0x1884f69b, 0x188c0562, 0x189314aa, 0x189a2475, 0x18a134c2, 0x18a84590,
5470x18af56e0, 0x18b668b1, 0x18bd7b04, 0x18c48dd8, 0x18cba12d, 0x18d2b504, 0x18d9c95c, 0x18e0de35,
5480x18e7f38f, 0x18ef096b, 0x18f61fc7, 0x18fd36a3, 0x19044e01, 0x190b65df, 0x19127e3e, 0x1919971d,
5490x1920b07d, 0x1927ca5d, 0x192ee4be, 0x1935ff9f, 0x193d1b00, 0x194436e1, 0x194b5342, 0x19527023,
5500x19598d84, 0x1960ab65, 0x1967c9c6, 0x196ee8a6, 0x19760806, 0x197d27e6, 0x19844845, 0x198b6923,
5510x19928a81, 0x1999ac5e, 0x19a0ceba, 0x19a7f196, 0x19af14f0, 0x19b638ca, 0x19bd5d22, 0x19c481f9,
5520x19cba74f, 0x19d2cd24, 0x19d9f378, 0x19e11a4a, 0x19e8419a, 0x19ef6969, 0x19f691b6, 0x19fdba82,
5530x1a04e3cc, 0x1a0c0d94, 0x1a1337da, 0x1a1a629f, 0x1a218de1, 0x1a28b9a1, 0x1a2fe5df, 0x1a37129b,
5540x1a3e3fd4, 0x1a456d8b, 0x1a4c9bc0, 0x1a53ca72, 0x1a5af9a2, 0x1a62294f, 0x1a695979, 0x1a708a21,
5550x1a77bb45, 0x1a7eece7, 0x1a861f06, 0x1a8d51a2, 0x1a9484bb, 0x1a9bb850, 0x1aa2ec62, 0x1aaa20f1,
5560x1ab155fd, 0x1ab88b85, 0x1abfc18a, 0x1ac6f80b, 0x1ace2f09, 0x1ad56683, 0x1adc9e79, 0x1ae3d6eb,
5570x1aeb0fda, 0x1af24944, 0x1af9832b, 0x1b00bd8d, 0x1b07f86c, 0x1b0f33c6, 0x1b166f9c, 0x1b1dabed,
5580x1b24e8ba, 0x1b2c2603, 0x1b3363c7, 0x1b3aa206, 0x1b41e0c1, 0x1b491ff7, 0x1b505fa9, 0x1b579fd5,
5590x1b5ee07d, 0x1b66219f, 0x1b6d633d, 0x1b74a555, 0x1b7be7e9, 0x1b832af7, 0x1b8a6e7f, 0x1b91b283,
5600x1b98f701, 0x1ba03bf9, 0x1ba7816c, 0x1baec75a, 0x1bb60dc1, 0x1bbd54a3, 0x1bc49bff, 0x1bcbe3d6,
5610x1bd32c26, 0x1bda74f1, 0x1be1be35, 0x1be907f3, 0x1bf0522b, 0x1bf79cdd, 0x1bfee809, 0x1c0633ae,
5620x1c0d7fcc, 0x1c14cc65, 0x1c1c1976, 0x1c236702, 0x1c2ab506, 0x1c320384, 0x1c39527b, 0x1c40a1eb,
5630x1c47f1d4, 0x1c4f4236, 0x1c569311, 0x1c5de466, 0x1c653632, 0x1c6c8878, 0x1c73db37, 0x1c7b2e6e,
5640x1c82821d, 0x1c89d646, 0x1c912ae6, 0x1c987fff, 0x1c9fd591, 0x1ca72b9b, 0x1cae821d, 0x1cb5d917,
5650x1cbd3089, 0x1cc48874, 0x1ccbe0d6, 0x1cd339b1, 0x1cda9303, 0x1ce1eccd, 0x1ce9470f, 0x1cf0a1c8,
5660x1cf7fcf9, 0x1cff58a2, 0x1d06b4c2, 0x1d0e115a, 0x1d156e69, 0x1d1ccbf0, 0x1d2429ed, 0x1d2b8862,
5670x1d32e74e, 0x1d3a46b2, 0x1d41a68c, 0x1d4906dd, 0x1d5067a6, 0x1d57c8e5, 0x1d5f2a9b, 0x1d668cc7,
5680x1d6def6b, 0x1d755285, 0x1d7cb615, 0x1d841a1c, 0x1d8b7e9a, 0x1d92e38e, 0x1d9a48f9, 0x1da1aed9,
5690x1da91530, 0x1db07bfd, 0x1db7e340, 0x1dbf4afa, 0x1dc6b329, 0x1dce1bce, 0x1dd584e9, 0x1ddcee7a,
5700x1de45881, 0x1debc2fe, 0x1df32df0, 0x1dfa9957, 0x1e020535, 0x1e097187, 0x1e10de50, 0x1e184b8d,
5710x1e1fb940, 0x1e272768, 0x1e2e9606, 0x1e360518, 0x1e3d74a0, 0x1e44e49d, 0x1e4c550e, 0x1e53c5f5,
5720x1e5b3750, 0x1e62a921, 0x1e6a1b66, 0x1e718e20, 0x1e79014e, 0x1e8074f1, 0x1e87e909, 0x1e8f5d95,
5730x1e96d295, 0x1e9e480a, 0x1ea5bdf3, 0x1ead3450, 0x1eb4ab22, 0x1ebc2268, 0x1ec39a22, 0x1ecb1250,
5740x1ed28af1, 0x1eda0407, 0x1ee17d91, 0x1ee8f78f, 0x1ef07200, 0x1ef7ece5, 0x1eff683d, 0x1f06e40a,
5750x1f0e604a, 0x1f15dcfd, 0x1f1d5a24, 0x1f24d7be, 0x1f2c55cb, 0x1f33d44c, 0x1f3b5340, 0x1f42d2a7,
5760x1f4a5281, 0x1f51d2ce, 0x1f59538f, 0x1f60d4c2, 0x1f685668, 0x1f6fd881, 0x1f775b0d, 0x1f7ede0c,
5770x1f86617d, 0x1f8de561, 0x1f9569b7, 0x1f9cee80, 0x1fa473bb, 0x1fabf969, 0x1fb37f8a, 0x1fbb061c,
5780x1fc28d21, 0x1fca1498, 0x1fd19c81, 0x1fd924dc, 0x1fe0ada9, 0x1fe836e9, 0x1fefc09a, 0x1ff74abd,
5790x1ffed552, 0x20066059, 0x200debd1, 0x201577bc, 0x201d0417, 0x202490e5, 0x202c1e24, 0x2033abd4,
5800x203b39f6, 0x2042c889, 0x204a578d, 0x2051e703, 0x205976ea, 0x20610742, 0x2068980b, 0x20702946,
5810x2077baf1, 0x207f4d0d, 0x2086df9a, 0x208e7298, 0x20960607, 0x209d99e7, 0x20a52e37, 0x20acc2f8,
5820x20b45829, 0x20bbedcb, 0x20c383de, 0x20cb1a61, 0x20d2b154, 0x20da48b8, 0x20e1e08c, 0x20e978d0,
5830x20f11185, 0x20f8aaa9, 0x2100443e, 0x2107de43, 0x210f78b7, 0x2117139c, 0x211eaef0, 0x21264ab5,
5840x212de6e9, 0x2135838d, 0x213d20a0, 0x2144be24, 0x214c5c16, 0x2153fa79, 0x215b994b, 0x2163388c,
5850x216ad83d, 0x2172785d, 0x217a18ec, 0x2181b9ea, 0x21895b58, 0x2190fd35, 0x21989f81, 0x21a0423c,
5860x21a7e566, 0x21af88ff, 0x21b72d06, 0x21bed17d, 0x21c67663, 0x21ce1bb7, 0x21d5c17a, 0x21dd67ab,
5870x21e50e4b, 0x21ecb55a, 0x21f45cd7, 0x21fc04c3, 0x2203ad1d, 0x220b55e5, 0x2212ff1c, 0x221aa8c1,
5880x222252d4, 0x2229fd56, 0x2231a845, 0x223953a3, 0x2240ff6e, 0x2248aba8, 0x2250584f, 0x22580565,
5890x225fb2e8, 0x226760d9, 0x226f0f37, 0x2276be04, 0x227e6d3e, 0x22861ce5, 0x228dccfa, 0x22957d7d,
5900x229d2e6d, 0x22a4dfcb, 0x22ac9195, 0x22b443cd, 0x22bbf673, 0x22c3a985, 0x22cb5d05, 0x22d310f2,
5910x22dac54c, 0x22e27a13, 0x22ea2f47, 0x22f1e4e8, 0x22f99af5, 0x23015170, 0x23090857, 0x2310bfab,
5920x2318776c, 0x23202f99, 0x2327e833, 0x232fa13a, 0x23375aad, 0x233f148c, 0x2346ced8, 0x234e8991,
5930x235644b5, 0x235e0046, 0x2365bc43, 0x236d78ac, 0x23753582, 0x237cf2c3, 0x2384b071, 0x238c6e8a,
5940x23942d10, 0x239bec01, 0x23a3ab5e, 0x23ab6b28, 0x23b32b5c, 0x23baebfd, 0x23c2ad09, 0x23ca6e81,
5950x23d23064, 0x23d9f2b3, 0x23e1b56e, 0x23e97894, 0x23f13c25, 0x23f90022, 0x2400c48a, 0x2408895d,
5960x24104e9b, 0x24181445, 0x241fda5a, 0x2427a0da, 0x242f67c5, 0x24372f1a, 0x243ef6db, 0x2446bf07,
5970x244e879e, 0x2456509f, 0x245e1a0b, 0x2465e3e2, 0x246dae24, 0x247578d0, 0x247d43e7, 0x24850f68,
5980x248cdb54, 0x2494a7ab, 0x249c746b, 0x24a44197, 0x24ac0f2c, 0x24b3dd2c, 0x24bbab96, 0x24c37a6a,
5990x24cb49a8, 0x24d31951, 0x24dae963, 0x24e2b9e0, 0x24ea8ac6, 0x24f25c17, 0x24fa2dd1, 0x2501fff5,
6000x2509d283, 0x2511a57b, 0x251978dc, 0x25214ca7, 0x252920dc, 0x2530f57b, 0x2538ca82, 0x25409ff4,
6010x254875cf, 0x25504c13, 0x255822c0, 0x255ff9d7, 0x2567d157, 0x256fa941, 0x25778193, 0x257f5a4f,
6020x25873374, 0x258f0d02, 0x2596e6f9, 0x259ec159, 0x25a69c22, 0x25ae7753, 0x25b652ee, 0x25be2ef1,
6030x25c60b5e, 0x25cde833, 0x25d5c570, 0x25dda316, 0x25e58125, 0x25ed5f9d, 0x25f53e7c, 0x25fd1dc5,
6040x2604fd76, 0x260cdd8f, 0x2614be10, 0x261c9efa, 0x2624804c, 0x262c6206, 0x26344429, 0x263c26b3,
6050x264409a6, 0x264bed01, 0x2653d0c3, 0x265bb4ee, 0x26639980, 0x266b7e7b, 0x267363dd, 0x267b49a7,
6060x26832fd9, 0x268b1673, 0x2692fd74, 0x269ae4dd, 0x26a2ccad, 0x26aab4e5, 0x26b29d85, 0x26ba868c,
6070x26c26ffa, 0x26ca59d0, 0x26d2440d, 0x26da2eb1, 0x26e219bd, 0x26ea0530, 0x26f1f10a, 0x26f9dd4b,
6080x2701c9f4, 0x2709b703, 0x2711a479, 0x27199257, 0x2721809b, 0x27296f46, 0x27315e58, 0x27394dd1,
6090x27413db0, 0x27492df7, 0x27511ea4, 0x27590fb7, 0x27610132, 0x2768f312, 0x2770e55a, 0x2778d808,
6100x2780cb1c, 0x2788be96, 0x2790b277, 0x2798a6bf, 0x27a09b6c, 0x27a89080, 0x27b085fa, 0x27b87bdb,
6110x27c07221, 0x27c868cd, 0x27d05fe0, 0x27d85758, 0x27e04f37, 0x27e8477b, 0x27f04026, 0x27f83936,
6120x280032ac, 0x28082c87, 0x281026c9, 0x28182170, 0x28201c7d, 0x282817ef, 0x283013c7, 0x28381004,
6130x28400ca7, 0x284809b0, 0x2850071d, 0x285804f1, 0x28600329, 0x286801c7, 0x287000ca, 0x28780032,
6140x287fffff, 0x28880032, 0x289000ca, 0x289801c6, 0x28a00328, 0x28a804ef, 0x28b0071b, 0x28b809ab,
6150x28c00ca1, 0x28c80ffb, 0x28d013ba, 0x28d817de, 0x28e01c66, 0x28e82153, 0x28f026a5, 0x28f82c5b,
6160x29003276, 0x290838f6, 0x29103fda, 0x29184722, 0x29204ecf, 0x292856e0, 0x29305f55, 0x2938682f,
6170x2940716d, 0x29487b0f, 0x29508516, 0x29588f80, 0x29609a4f, 0x2968a582, 0x2970b118, 0x2978bd13,
6180x2980c972, 0x2988d634, 0x2990e35a, 0x2998f0e5, 0x29a0fed3, 0x29a90d24, 0x29b11bda, 0x29b92af3,
6190x29c13a70, 0x29c94a50, 0x29d15a94, 0x29d96b3c, 0x29e17c47, 0x29e98db5, 0x29f19f87, 0x29f9b1bc,
6200x2a01c455, 0x2a09d751, 0x2a11eab0, 0x2a19fe72, 0x2a221298, 0x2a2a2721, 0x2a323c0d, 0x2a3a515c,
6210x2a42670e, 0x2a4a7d23, 0x2a52939b, 0x2a5aaa75, 0x2a62c1b3, 0x2a6ad954, 0x2a72f157, 0x2a7b09be,
6220x2a832287, 0x2a8b3bb2, 0x2a935541, 0x2a9b6f32, 0x2aa38986, 0x2aaba43c, 0x2ab3bf55, 0x2abbdad0,
6230x2ac3f6ad, 0x2acc12ee, 0x2ad42f90, 0x2adc4c95, 0x2ae469fc, 0x2aec87c6, 0x2af4a5f1, 0x2afcc47f,
6240x2b04e36f, 0x2b0d02c1, 0x2b152276, 0x2b1d428c, 0x2b256304, 0x2b2d83df, 0x2b35a51b, 0x2b3dc6b9,
6250x2b45e8b9, 0x2b4e0b1b, 0x2b562ddf, 0x2b5e5104, 0x2b66748c, 0x2b6e9875, 0x2b76bcbf, 0x2b7ee16b,
6260x2b870679, 0x2b8f2be9, 0x2b9751b9, 0x2b9f77ec, 0x2ba79e80, 0x2bafc575, 0x2bb7eccb, 0x2bc01483,
6270x2bc83c9d, 0x2bd06517, 0x2bd88df3, 0x2be0b730, 0x2be8e0ce, 0x2bf10acd, 0x2bf9352e, 0x2c015fef,
6280x2c098b11, 0x2c11b695, 0x2c19e279, 0x2c220ebf, 0x2c2a3b65, 0x2c32686c, 0x2c3a95d4, 0x2c42c39c,
6290x2c4af1c6, 0x2c532050, 0x2c5b4f3a, 0x2c637e86, 0x2c6bae32, 0x2c73de3e, 0x2c7c0eab, 0x2c843f79,
6300x2c8c70a7, 0x2c94a236, 0x2c9cd424, 0x2ca50674, 0x2cad3923, 0x2cb56c33, 0x2cbd9fa3, 0x2cc5d374,
6310x2cce07a4, 0x2cd63c35, 0x2cde7126, 0x2ce6a677, 0x2ceedc28, 0x2cf71238, 0x2cff48a9, 0x2d077f7a,
6320x2d0fb6ab, 0x2d17ee3c, 0x2d20262c, 0x2d285e7d, 0x2d30972d, 0x2d38d03d, 0x2d4109ac, 0x2d49437c,
6330x2d517daa, 0x2d59b839, 0x2d61f327, 0x2d6a2e75, 0x2d726a22, 0x2d7aa62e, 0x2d82e29b, 0x2d8b1f66,
6340x2d935c91, 0x2d9b9a1b, 0x2da3d804, 0x2dac164d, 0x2db454f5, 0x2dbc93fc, 0x2dc4d363, 0x2dcd1328,
6350x2dd5534d, 0x2ddd93d0, 0x2de5d4b3, 0x2dee15f5, 0x2df65795, 0x2dfe9995, 0x2e06dbf4, 0x2e0f1eb1,
6360x2e1761cd, 0x2e1fa548, 0x2e27e922, 0x2e302d5a, 0x2e3871f2, 0x2e40b6e8, 0x2e48fc3c, 0x2e5141ef,
6370x2e598801, 0x2e61ce71, 0x2e6a1540, 0x2e725c6d, 0x2e7aa3f9, 0x2e82ebe3, 0x2e8b342b, 0x2e937cd2,
6380x2e9bc5d7, 0x2ea40f3b, 0x2eac58fc, 0x2eb4a31c, 0x2ebced9a, 0x2ec53876, 0x2ecd83b0, 0x2ed5cf49,
6390x2ede1b3f, 0x2ee66794, 0x2eeeb446, 0x2ef70156, 0x2eff4ec5, 0x2f079c91, 0x2f0feabb, 0x2f183942,
6400x2f208828, 0x2f28d76b, 0x2f31270c, 0x2f39770b, 0x2f41c768, 0x2f4a1822, 0x2f526939, 0x2f5abaaf,
6410x2f630c81, 0x2f6b5eb2, 0x2f73b13f, 0x2f7c042a, 0x2f845773, 0x2f8cab19, 0x2f94ff1c, 0x2f9d537d,
6420x2fa5a83a, 0x2fadfd56, 0x2fb652ce, 0x2fbea8a3, 0x2fc6fed6, 0x2fcf5566, 0x2fd7ac52, 0x2fe0039c,
6430x2fe85b43, 0x2ff0b347, 0x2ff90ba8, 0x30016466, 0x3009bd80, 0x301216f8, 0x301a70cc, 0x3022cafd,
6440x302b258b, 0x30338076, 0x303bdbbd, 0x30443761, 0x304c9362, 0x3054efbf, 0x305d4c79, 0x3065a98f,
6450x306e0702, 0x307664d2, 0x307ec2fe, 0x30872186, 0x308f806b, 0x3097dfac, 0x30a03f49, 0x30a89f43,
6460x30b0ff99, 0x30b9604b, 0x30c1c159, 0x30ca22c4, 0x30d2848a, 0x30dae6ad, 0x30e3492c, 0x30ebac07,
6470x30f40f3e, 0x30fc72d1, 0x3104d6c0, 0x310d3b0b, 0x31159fb1, 0x311e04b4, 0x31266a12, 0x312ecfcd,
6480x313735e3, 0x313f9c55, 0x31480322, 0x31506a4b, 0x3158d1d0, 0x316139b0, 0x3169a1ed, 0x31720a84,
6490x317a7377, 0x3182dcc6, 0x318b4670, 0x3193b076, 0x319c1ad6, 0x31a48593, 0x31acf0aa, 0x31b55c1d,
6500x31bdc7ec, 0x31c63415, 0x31cea09a, 0x31d70d7a, 0x31df7ab5, 0x31e7e84b, 0x31f0563d, 0x31f8c489,
6510x32013331, 0x3209a233, 0x32121191, 0x321a8149, 0x3222f15d, 0x322b61cb, 0x3233d294, 0x323c43b8,
6520x3244b537, 0x324d2711, 0x32559945, 0x325e0bd4, 0x32667ebe, 0x326ef202, 0x327765a1, 0x327fd99b,
6530x32884def, 0x3290c29e, 0x329937a7, 0x32a1ad0b, 0x32aa22c9, 0x32b298e2, 0x32bb0f55, 0x32c38622,
6540x32cbfd4a, 0x32d474cc, 0x32dceca8, 0x32e564df, 0x32eddd70, 0x32f6565b, 0x32fecfa0, 0x3307493f,
6550x330fc338, 0x33183d8c, 0x3320b839, 0x33293341, 0x3331aea2, 0x333a2a5e, 0x3342a673, 0x334b22e2,
6560x33539fab, 0x335c1cce, 0x33649a4b, 0x336d1821, 0x33759652, 0x337e14dc, 0x338693bf, 0x338f12fd,
6570x33979294, 0x33a01284, 0x33a892cf, 0x33b11372, 0x33b9946f, 0x33c215c6, 0x33ca9776, 0x33d31980,
6580x33db9be3, 0x33e41ea0, 0x33eca1b5, 0x33f52524, 0x33fda8ed, 0x34062d0e, 0x340eb189, 0x3417365d,
6590x341fbb8b, 0x34284111, 0x3430c6f1, 0x34394d29, 0x3441d3bb, 0x344a5aa6, 0x3452e1e9, 0x345b6986,
6600x3463f17c, 0x346c79ca, 0x34750272, 0x347d8b72, 0x348614cb, 0x348e9e7d, 0x34972888, 0x349fb2eb,
6610x34a83da8, 0x34b0c8bd, 0x34b9542a, 0x34c1dff0, 0x34ca6c0f, 0x34d2f887, 0x34db8557, 0x34e4127f,
6620x34eca000, 0x34f52dda, 0x34fdbc0c, 0x35064a96, 0x350ed979, 0x351768b4, 0x351ff847, 0x35288833,
6630x35311877, 0x3539a913, 0x35423a08, 0x354acb54, 0x35535cf9, 0x355beef6, 0x3564814b, 0x356d13f8,
6640x3575a6fe, 0x357e3a5b, 0x3586ce10, 0x358f621d, 0x3597f682, 0x35a08b40, 0x35a92055, 0x35b1b5c1,
6650x35ba4b86, 0x35c2e1a3, 0x35cb7817, 0x35d40ee3, 0x35dca607, 0x35e53d82, 0x35edd555, 0x35f66d80,
6660x35ff0602, 0x36079edc, 0x3610380e, 0x3618d197, 0x36216b77, 0x362a05af, 0x3632a03f, 0x363b3b26,
6670x3643d664, 0x364c71fa, 0x36550de7, 0x365daa2b, 0x366646c7, 0x366ee3ba, 0x36778104, 0x36801ea5,
6680x3688bc9e, 0x36915aee, 0x3699f994, 0x36a29892, 0x36ab37e7, 0x36b3d793, 0x36bc7796, 0x36c517f1,
6690x36cdb8a2, 0x36d659aa, 0x36defb08, 0x36e79cbe, 0x36f03ecb, 0x36f8e12e, 0x370183e9, 0x370a26fa,
6700x3712ca62, 0x371b6e20, 0x37241235, 0x372cb6a1, 0x37355b64, 0x373e007d, 0x3746a5ed, 0x374f4bb3,
6710x3757f1d0, 0x37609844, 0x37693f0e, 0x3771e62e, 0x377a8da5, 0x37833572, 0x378bdd96, 0x37948610,
6720x379d2ee0, 0x37a5d807, 0x37ae8183, 0x37b72b57, 0x37bfd580, 0x37c87fff, 0x37d12ad5, 0x37d9d601,
6730x37e28183, 0x37eb2d5b, 0x37f3d989, 0x37fc860e, 0x380532e8, 0x380de018, 0x38168d9e, 0x381f3b7b,
6740x3827e9ad, 0x38309835, 0x38394712, 0x3841f646, 0x384aa5d0, 0x385355af, 0x385c05e4, 0x3864b66f,
6750x386d674f, 0x38761885, 0x387eca11, 0x38877bf2, 0x38902e29, 0x3898e0b6, 0x38a19398, 0x38aa46d0,
6760x38b2fa5d, 0x38bbae40, 0x38c46278, 0x38cd1705, 0x38d5cbe8, 0x38de8120, 0x38e736ae, 0x38efec91,
6770x38f8a2c9, 0x39015957, 0x390a103a, 0x3912c772, 0x391b7eff, 0x392436e1, 0x392cef19, 0x3935a7a5,
6780x393e6087, 0x394719be, 0x394fd34a, 0x39588d2b, 0x39614760, 0x396a01eb, 0x3972bccb, 0x397b7800,
6790x39843389, 0x398cef68, 0x3995ab9b, 0x399e6823, 0x39a72500, 0x39afe232, 0x39b89fb8, 0x39c15d93,
6800x39ca1bc3, 0x39d2da47, 0x39db9921, 0x39e4584e, 0x39ed17d1, 0x39f5d7a8, 0x39fe97d3, 0x3a075853,
6810x3a101927, 0x3a18da50, 0x3a219bce, 0x3a2a5d9f, 0x3a331fc5, 0x3a3be240, 0x3a44a50f, 0x3a4d6832,
6820x3a562ba9, 0x3a5eef75, 0x3a67b395, 0x3a707809, 0x3a793cd2, 0x3a8201ee, 0x3a8ac75f, 0x3a938d24,
6830x3a9c533d, 0x3aa519aa, 0x3aade06b, 0x3ab6a780, 0x3abf6ee9, 0x3ac836a6, 0x3ad0feb7, 0x3ad9c71c,
6840x3ae28fd5, 0x3aeb58e1, 0x3af42242, 0x3afcebf6, 0x3b05b5fe, 0x3b0e805a, 0x3b174b0a, 0x3b20160d,
6850x3b28e164, 0x3b31ad0f, 0x3b3a790e, 0x3b434560, 0x3b4c1205, 0x3b54deff, 0x3b5dac4b, 0x3b6679ec,
6860x3b6f47e0, 0x3b781627, 0x3b80e4c2, 0x3b89b3b0, 0x3b9282f2, 0x3b9b5287, 0x3ba4226f, 0x3bacf2ab,
6870x3bb5c33a, 0x3bbe941c, 0x3bc76552, 0x3bd036db, 0x3bd908b7, 0x3be1dae6, 0x3beaad69, 0x3bf3803e,
6880x3bfc5367, 0x3c0526e3, 0x3c0dfab2, 0x3c16ced4, 0x3c1fa349, 0x3c287811, 0x3c314d2c, 0x3c3a229a,
6890x3c42f85b, 0x3c4bce6f, 0x3c54a4d5, 0x3c5d7b8f, 0x3c66529b, 0x3c6f29fa, 0x3c7801ac, 0x3c80d9b1,
6900x3c89b209, 0x3c928ab3, 0x3c9b63b0, 0x3ca43cff, 0x3cad16a2, 0x3cb5f097, 0x3cbecade, 0x3cc7a578,
6910x3cd08065, 0x3cd95ba4, 0x3ce23736, 0x3ceb131a, 0x3cf3ef50, 0x3cfccbd9, 0x3d05a8b5, 0x3d0e85e3,
6920x3d176363, 0x3d204136, 0x3d291f5b, 0x3d31fdd2, 0x3d3adc9b, 0x3d43bbb7, 0x3d4c9b25, 0x3d557ae5,
6930x3d5e5af7, 0x3d673b5c, 0x3d701c13, 0x3d78fd1b, 0x3d81de76, 0x3d8ac023, 0x3d93a222, 0x3d9c8473,
6940x3da56716, 0x3dae4a0b, 0x3db72d52, 0x3dc010eb, 0x3dc8f4d6, 0x3dd1d912, 0x3ddabda1, 0x3de3a281,
6950x3dec87b3, 0x3df56d37, 0x3dfe530d, 0x3e073934, 0x3e101fad, 0x3e190678, 0x3e21ed95, 0x3e2ad503,
6960x3e33bcc3, 0x3e3ca4d4, 0x3e458d37, 0x3e4e75ec, 0x3e575ef2, 0x3e60484a, 0x3e6931f3, 0x3e721bed,
6970x3e7b0639, 0x3e83f0d7, 0x3e8cdbc6, 0x3e95c706, 0x3e9eb298, 0x3ea79e7a, 0x3eb08aaf, 0x3eb97734,
6980x3ec2640b, 0x3ecb5133, 0x3ed43eac, 0x3edd2c77, 0x3ee61a93, 0x3eef08ff, 0x3ef7f7bd, 0x3f00e6cc,
6990x3f09d62c, 0x3f12c5de, 0x3f1bb5e0, 0x3f24a633, 0x3f2d96d7, 0x3f3687cd, 0x3f3f7913, 0x3f486aaa,
7000x3f515c92, 0x3f5a4ecb, 0x3f634155, 0x3f6c342f, 0x3f75275b, 0x3f7e1ad7, 0x3f870ea4, 0x3f9002c2,
7010x3f98f730, 0x3fa1ebef, 0x3faae0ff, 0x3fb3d660, 0x3fbccc11, 0x3fc5c213, 0x3fceb865, 0x3fd7af08,
7020x3fe0a5fc, 0x3fe99d40, 0x3ff294d4, 0x3ffb8cb9, 0x400484ef, 0x400d7d75, 0x4016764b, 0x401f6f72,
7030x402868e9, 0x403162b1, 0x403a5cc8, 0x40435730, 0x404c51e9, 0x40554cf2, 0x405e484b, 0x406743f4,
7040x40703fed, 0x40793c37, 0x408238d0, 0x408b35ba, 0x409432f4, 0x409d307e, 0x40a62e58, 0x40af2c82,
7050x40b82afd, 0x40c129c7, 0x40ca28e1, 0x40d3284b, 0x40dc2805, 0x40e5280f, 0x40ee2869, 0x40f72913,
7060x41002a0c, 0x41092b56, 0x41122cef, 0x411b2ed8, 0x41243111, 0x412d3399, 0x41363672, 0x413f399a,
7070x41483d11, 0x415140d9, 0x415a44f0, 0x41634956, 0x416c4e0c, 0x41755312, 0x417e5867, 0x41875e0c,
7080x41906401, 0x41996a44, 0x41a270d8, 0x41ab77ba, 0x41b47eed, 0x41bd866e, 0x41c68e3f, 0x41cf965f,
7090x41d89ecf, 0x41e1a78e, 0x41eab09c, 0x41f3b9fa, 0x41fcc3a6, 0x4205cda2, 0x420ed7ee, 0x4217e288,
7100x4220ed72, 0x4229f8aa, 0x42330432, 0x423c1009, 0x42451c2f, 0x424e28a4, 0x42573569, 0x4260427c,
7110x42694fde, 0x42725d8f, 0x427b6b8f, 0x428479de, 0x428d887c, 0x42969769, 0x429fa6a5, 0x42a8b62f,
7120x42b1c609, 0x42bad631, 0x42c3e6a8, 0x42ccf76e, 0x42d60882, 0x42df19e5, 0x42e82b97, 0x42f13d98,
7130x42fa4fe7, 0x43036285, 0x430c7572, 0x431588ad, 0x431e9c37, 0x4327b00f, 0x4330c436, 0x4339d8ab,
7140x4342ed6f, 0x434c0282, 0x435517e3, 0x435e2d92, 0x4367438f, 0x437059dc, 0x43797076, 0x4382875f,
7150x438b9e96, 0x4394b61b, 0x439dcdef, 0x43a6e611, 0x43affe81, 0x43b91740, 0x43c2304d, 0x43cb49a8,
7160x43d46351, 0x43dd7d48, 0x43e6978d, 0x43efb221, 0x43f8cd02, 0x4401e832, 0x440b03af, 0x44141f7b,
7170x441d3b95, 0x442657fc, 0x442f74b2, 0x443891b6, 0x4441af07, 0x444acca7, 0x4453ea94, 0x445d08cf,
7180x44662758, 0x446f462f, 0x44786553, 0x448184c6, 0x448aa486, 0x4493c494, 0x449ce4f0, 0x44a60599,
7190x44af2690, 0x44b847d5, 0x44c16967, 0x44ca8b47, 0x44d3ad74, 0x44dccfef, 0x44e5f2b8, 0x44ef15ce,
7200x44f83932, 0x45015ce3, 0x450a80e2, 0x4513a52e, 0x451cc9c8, 0x4525eeaf, 0x452f13e3, 0x45383965,
7210x45415f34, 0x454a8551, 0x4553abbb, 0x455cd272, 0x4565f976, 0x456f20c8, 0x45784867, 0x45817053,
7220x458a988c, 0x4593c113, 0x459ce9e7, 0x45a61307, 0x45af3c75, 0x45b86630, 0x45c19039, 0x45caba8e,
7230x45d3e530, 0x45dd101f, 0x45e63b5c, 0x45ef66e5, 0x45f892bb, 0x4601bede, 0x460aeb4e, 0x4614180b,
7240x461d4515, 0x4626726c, 0x462fa00f, 0x4638ce00, 0x4641fc3d, 0x464b2ac7, 0x4654599e, 0x465d88c1,
7250x4666b832, 0x466fe7ef, 0x467917f8, 0x4682484e, 0x468b78f1, 0x4694a9e1, 0x469ddb1d, 0x46a70ca6,
7260x46b03e7b, 0x46b9709d, 0x46c2a30c, 0x46cbd5c7, 0x46d508ce, 0x46de3c22, 0x46e76fc2, 0x46f0a3af,
7270x46f9d7e9, 0x47030c6e, 0x470c4140, 0x4715765f, 0x471eabc9, 0x4727e180, 0x47311784, 0x473a4dd3,
7280x4743846f, 0x474cbb57, 0x4755f28c, 0x475f2a0c, 0x476861d9, 0x477199f2, 0x477ad257, 0x47840b08,
7290x478d4405, 0x47967d4f, 0x479fb6e4, 0x47a8f0c5, 0x47b22af3, 0x47bb656c, 0x47c4a032, 0x47cddb43,
7300x47d716a1, 0x47e0524a, 0x47e98e40, 0x47f2ca81, 0x47fc070e, 0x480543e7, 0x480e810c, 0x4817be7c,
7310x4820fc39, 0x482a3a41, 0x48337895, 0x483cb735, 0x4845f620, 0x484f3557, 0x485874da, 0x4861b4a8,
7320x486af4c3, 0x48743528, 0x487d75da, 0x4886b6d7, 0x488ff81f, 0x489939b3, 0x48a27b93, 0x48abbdbe,
7330x48b50035, 0x48be42f7, 0x48c78605, 0x48d0c95e, 0x48da0d02, 0x48e350f2, 0x48ec952e, 0x48f5d9b4,
7340x48ff1e86, 0x490863a4, 0x4911a90c, 0x491aeec0, 0x492434bf, 0x492d7b0a, 0x4936c1a0, 0x49400881,
7350x49494fad, 0x49529724, 0x495bdee7, 0x496526f4, 0x496e6f4d, 0x4977b7f1, 0x498100e0, 0x498a4a1a,
7360x4993939f, 0x499cdd6f, 0x49a6278a, 0x49af71f0, 0x49b8bca2, 0x49c2079e, 0x49cb52e5, 0x49d49e77,
7370x49ddea53, 0x49e7367b, 0x49f082ee, 0x49f9cfab, 0x4a031cb4, 0x4a0c6a07, 0x4a15b7a5, 0x4a1f058d,
7380x4a2853c1, 0x4a31a23f, 0x4a3af108, 0x4a44401b, 0x4a4d8f7a, 0x4a56df23, 0x4a602f16, 0x4a697f55,
7390x4a72cfdd, 0x4a7c20b1, 0x4a8571cf, 0x4a8ec337, 0x4a9814eb, 0x4aa166e8, 0x4aaab930, 0x4ab40bc3,
7400x4abd5ea0, 0x4ac6b1c8, 0x4ad0053a, 0x4ad958f6, 0x4ae2acfd, 0x4aec014e, 0x4af555e9, 0x4afeaacf,
7410x4b07ffff, 0x4b11557a, 0x4b1aab3f, 0x4b24014e, 0x4b2d57a7, 0x4b36ae4b, 0x4b400538, 0x4b495c70,
7420x4b52b3f2, 0x4b5c0bbf, 0x4b6563d5, 0x4b6ebc36, 0x4b7814e0, 0x4b816dd5, 0x4b8ac714, 0x4b94209d,
7430x4b9d7a6f, 0x4ba6d48c, 0x4bb02ef3, 0x4bb989a4, 0x4bc2e49f, 0x4bcc3fe4, 0x4bd59b72, 0x4bdef74b,
7440x4be8536e, 0x4bf1afda, 0x4bfb0c90, 0x4c046990, 0x4c0dc6da, 0x4c17246e, 0x4c20824b, 0x4c29e073,
7450x4c333ee4, 0x4c3c9d9e, 0x4c45fca3, 0x4c4f5bf1, 0x4c58bb89, 0x4c621b6a, 0x4c6b7b95, 0x4c74dc0a,
7460x4c7e3cc9, 0x4c879dd0, 0x4c90ff22, 0x4c9a60bd, 0x4ca3c2a2, 0x4cad24d0, 0x4cb68747, 0x4cbfea09,
7470x4cc94d13, 0x4cd2b067, 0x4cdc1405, 0x4ce577ec, 0x4ceedc1c, 0x4cf84096, 0x4d01a559, 0x4d0b0a65,
7480x4d146fbb, 0x4d1dd55a, 0x4d273b42, 0x4d30a174, 0x4d3a07ee, 0x4d436eb2, 0x4d4cd5c0, 0x4d563d16,
7490x4d5fa4b6, 0x4d690c9f, 0x4d7274d1, 0x4d7bdd4c, 0x4d854610, 0x4d8eaf1e, 0x4d981874, 0x4da18214,
7500x4daaebfc, 0x4db4562e, 0x4dbdc0a8, 0x4dc72b6c, 0x4dd09679, 0x4dda01ce, 0x4de36d6d, 0x4decd954,
7510x4df64584, 0x4dffb1fe, 0x4e091ec0, 0x4e128bcb, 0x4e1bf91f, 0x4e2566bb, 0x4e2ed4a1, 0x4e3842cf,
7520x4e41b146, 0x4e4b2006, 0x4e548f0e, 0x4e5dfe5f, 0x4e676df9, 0x4e70dddc, 0x4e7a4e07, 0x4e83be7b,
7530x4e8d2f38, 0x4e96a03d, 0x4ea0118b, 0x4ea98321, 0x4eb2f500, 0x4ebc6728, 0x4ec5d998, 0x4ecf4c50,
7540x4ed8bf51, 0x4ee2329b, 0x4eeba62d, 0x4ef51a07, 0x4efe8e2a, 0x4f080296, 0x4f117749, 0x4f1aec45,
7550x4f24618a, 0x4f2dd717, 0x4f374cec, 0x4f40c309, 0x4f4a396f, 0x4f53b01d, 0x4f5d2713, 0x4f669e52,
7560x4f7015d9, 0x4f798da8, 0x4f8305bf, 0x4f8c7e1e, 0x4f95f6c6, 0x4f9f6fb5, 0x4fa8e8ed, 0x4fb2626d,
7570x4fbbdc35, 0x4fc55645, 0x4fced09d, 0x4fd84b3e, 0x4fe1c626, 0x4feb4156, 0x4ff4bcce, 0x4ffe388f,
7580x5007b497, 0x501130e7, 0x501aad7f, 0x50242a5f, 0x502da787, 0x503724f7, 0x5040a2ae, 0x504a20ae,
7590x50539ef5, 0x505d1d84, 0x50669c5b, 0x50701b7a, 0x50799ae0, 0x50831a8e, 0x508c9a84, 0x50961ac2,
7600x509f9b47, 0x50a91c14, 0x50b29d29, 0x50bc1e85, 0x50c5a029, 0x50cf2215, 0x50d8a448, 0x50e226c2,
7610x50eba985, 0x50f52c8f, 0x50feafe0, 0x51083379, 0x5111b759, 0x511b3b81, 0x5124bff1, 0x512e44a7,
7620x5137c9a6, 0x51414eeb, 0x514ad478, 0x51545a4d, 0x515de069, 0x516766cc, 0x5170ed76, 0x517a7468,
7630x5183fba1, 0x518d8322, 0x51970ae9, 0x51a092f8, 0x51aa1b4e, 0x51b3a3ec, 0x51bd2cd0, 0x51c6b5fc,
7640x51d03f6f, 0x51d9c929, 0x51e3532b, 0x51ecdd73, 0x51f66802, 0x51fff2d9, 0x52097df7, 0x5213095b,
7650x521c9507, 0x522620fa, 0x522fad34, 0x523939b5, 0x5242c67c, 0x524c538b, 0x5255e0e1, 0x525f6e7e,
7660x5268fc61, 0x52728a8c, 0x527c18fd, 0x5285a7b5, 0x528f36b4, 0x5298c5fa, 0x52a25587, 0x52abe55a,
7670x52b57575, 0x52bf05d6, 0x52c8967d, 0x52d2276c, 0x52dbb8a1, 0x52e54a1d, 0x52eedbe0, 0x52f86de9,
7680x53020039, 0x530b92d0, 0x531525ad, 0x531eb8d1, 0x53284c3c, 0x5331dfed, 0x533b73e4, 0x53450823,
7690x534e9ca7, 0x53583173, 0x5361c684, 0x536b5bdc, 0x5374f17b, 0x537e8760, 0x53881d8c, 0x5391b3fe,
7700x539b4ab6, 0x53a4e1b5, 0x53ae78fa, 0x53b81086, 0x53c1a858, 0x53cb4070, 0x53d4d8ce, 0x53de7173,
7710x53e80a5e, 0x53f1a390, 0x53fb3d07, 0x5404d6c5, 0x540e70c9, 0x54180b13, 0x5421a5a4, 0x542b407a,
7720x5434db97, 0x543e76fa, 0x544812a3, 0x5451ae92, 0x545b4ac8, 0x5464e743, 0x546e8404, 0x5478210c,
7730x5481be59, 0x548b5bed, 0x5494f9c6, 0x549e97e5, 0x54a8364b, 0x54b1d4f6, 0x54bb73e8, 0x54c5131f,
7740x54ceb29c, 0x54d8525f, 0x54e1f268, 0x54eb92b6, 0x54f5334b, 0x54fed425, 0x55087546, 0x551216ac,
7750x551bb858, 0x55255a49, 0x552efc80, 0x55389efe, 0x554241c0, 0x554be4c9, 0x55558817, 0x555f2bab,
7760x5568cf84, 0x557273a3, 0x557c1808, 0x5585bcb3, 0x558f61a3, 0x559906d8, 0x55a2ac53, 0x55ac5214,
7770x55b5f81a, 0x55bf9e66, 0x55c944f7, 0x55d2ebce, 0x55dc92ea, 0x55e63a4c, 0x55efe1f3, 0x55f989e0,
7780x56033212, 0x560cda89, 0x56168346, 0x56202c48, 0x5629d58f, 0x56337f1c, 0x563d28ee, 0x5646d306,
7790x56507d62, 0x565a2804, 0x5663d2ec, 0x566d7e18, 0x5677298a, 0x5680d541, 0x568a813d, 0x56942d7e,
7800x569dda05, 0x56a786d1, 0x56b133e1, 0x56bae137, 0x56c48ed2, 0x56ce3cb3, 0x56d7ead8, 0x56e19942,
7810x56eb47f1, 0x56f4f6e6, 0x56fea61f, 0x5708559e, 0x57120561, 0x571bb569, 0x572565b7, 0x572f1649,
7820x5738c720, 0x5742783c, 0x574c299e, 0x5755db43, 0x575f8d2e, 0x57693f5e, 0x5772f1d2, 0x577ca48c,
7830x5786578a, 0x57900acd, 0x5799be54, 0x57a37221, 0x57ad2632, 0x57b6da88, 0x57c08f23, 0x57ca4402,
7840x57d3f926, 0x57ddae8f, 0x57e7643c, 0x57f11a2f, 0x57fad065, 0x580486e1, 0x580e3da1, 0x5817f4a5,
7850x5821abee, 0x582b637c, 0x58351b4e, 0x583ed365, 0x58488bc0, 0x58524460, 0x585bfd44, 0x5865b66d,
7860x586f6fda, 0x5879298b, 0x5882e381, 0x588c9dbc, 0x5896583b, 0x58a012fe, 0x58a9ce05, 0x58b38951,
7870x58bd44e2, 0x58c700b6, 0x58d0bccf, 0x58da792c, 0x58e435ce, 0x58edf2b4, 0x58f7afde, 0x59016d4c,
7880x590b2afe, 0x5914e8f5, 0x591ea730, 0x592865af, 0x59322472, 0x593be379, 0x5945a2c5, 0x594f6255,
7890x59592228, 0x5962e240, 0x596ca29c, 0x5976633c, 0x59802420, 0x5989e548, 0x5993a6b4, 0x599d6864,
7900x59a72a58, 0x59b0ec90, 0x59baaf0c, 0x59c471cc, 0x59ce34d0, 0x59d7f818, 0x59e1bba3, 0x59eb7f73,
7910x59f54386, 0x59ff07dd, 0x5a08cc79, 0x5a129158, 0x5a1c567a, 0x5a261be1, 0x5a2fe18b, 0x5a39a779,
7920x5a436dab, 0x5a4d3421, 0x5a56fada, 0x5a60c1d8, 0x5a6a8918, 0x5a74509d, 0x5a7e1865, 0x5a87e071,
7930x5a91a8c0, 0x5a9b7153, 0x5aa53a2a, 0x5aaf0344, 0x5ab8cca2, 0x5ac29644, 0x5acc6029, 0x5ad62a51,
7940x5adff4bd, 0x5ae9bf6d, 0x5af38a60, 0x5afd5597, 0x5b072111, 0x5b10ecce, 0x5b1ab8cf, 0x5b248514,
7950x5b2e519c, 0x5b381e67, 0x5b41eb76, 0x5b4bb8c8, 0x5b55865d, 0x5b5f5436, 0x5b692252, 0x5b72f0b1,
7960x5b7cbf54, 0x5b868e3a, 0x5b905d63, 0x5b9a2cd0, 0x5ba3fc7f, 0x5badcc72, 0x5bb79ca9, 0x5bc16d22,
7970x5bcb3ddf, 0x5bd50ede, 0x5bdee021, 0x5be8b1a7, 0x5bf28371, 0x5bfc557d, 0x5c0627cc, 0x5c0ffa5f,
7980x5c19cd35, 0x5c23a04d, 0x5c2d73a9, 0x5c374748, 0x5c411b2a, 0x5c4aef4e, 0x5c54c3b6, 0x5c5e9861,
7990x5c686d4f, 0x5c724280, 0x5c7c17f3, 0x5c85edaa, 0x5c8fc3a3, 0x5c9999e0, 0x5ca3705f, 0x5cad4721,
8000x5cb71e26, 0x5cc0f56e, 0x5ccaccf9, 0x5cd4a4c6, 0x5cde7cd7, 0x5ce8552a, 0x5cf22dbf, 0x5cfc0698,
8010x5d05dfb3, 0x5d0fb912, 0x5d1992b2, 0x5d236c96, 0x5d2d46bc, 0x5d372125, 0x5d40fbd1, 0x5d4ad6bf,
8020x5d54b1f0, 0x5d5e8d63, 0x5d686919, 0x5d724512, 0x5d7c214d, 0x5d85fdcb, 0x5d8fda8b, 0x5d99b78e,
8030x5da394d4, 0x5dad725c, 0x5db75026, 0x5dc12e33, 0x5dcb0c82, 0x5dd4eb14, 0x5ddec9e9, 0x5de8a8ff,
8040x5df28858, 0x5dfc67f4, 0x5e0647d2, 0x5e1027f2, 0x5e1a0855, 0x5e23e8fa, 0x5e2dc9e1, 0x5e37ab0b,
8050x5e418c77, 0x5e4b6e25, 0x5e555016, 0x5e5f3249, 0x5e6914be, 0x5e72f775, 0x5e7cda6f, 0x5e86bdab,
8060x5e90a129, 0x5e9a84e9, 0x5ea468eb, 0x5eae4d30, 0x5eb831b6, 0x5ec2167f, 0x5ecbfb8a, 0x5ed5e0d7,
8070x5edfc666, 0x5ee9ac37, 0x5ef3924a, 0x5efd78a0, 0x5f075f37, 0x5f114610, 0x5f1b2d2c, 0x5f251489,
8080x5f2efc28, 0x5f38e40a, 0x5f42cc2d, 0x5f4cb492, 0x5f569d39, 0x5f608622, 0x5f6a6f4d, 0x5f7458ba,
8090x5f7e4269, 0x5f882c5a, 0x5f92168c, 0x5f9c0100, 0x5fa5ebb6, 0x5fafd6ae, 0x5fb9c1e8, 0x5fc3ad64,
8100x5fcd9921, 0x5fd78520, 0x5fe17161, 0x5feb5de3, 0x5ff54aa7, 0x5fff37ad, 0x600924f5, 0x6013127e,
8110x601d0049, 0x6026ee56, 0x6030dca4, 0x603acb34, 0x6044ba05, 0x604ea918, 0x6058986d, 0x60628803,
8120x606c77db, 0x607667f4, 0x6080584f, 0x608a48ec, 0x609439ca, 0x609e2ae9, 0x60a81c4a, 0x60b20dec,
8130x60bbffd0, 0x60c5f1f5, 0x60cfe45c, 0x60d9d704, 0x60e3c9ed, 0x60edbd18, 0x60f7b084, 0x6101a432,
8140x610b9821, 0x61158c51, 0x611f80c3, 0x61297576, 0x61336a6a, 0x613d5f9f, 0x61475516, 0x61514ace,
8150x615b40c7, 0x61653702, 0x616f2d7e, 0x6179243a, 0x61831b38, 0x618d1278, 0x619709f8, 0x61a101ba,
8160x61aaf9bd, 0x61b4f200, 0x61beea85, 0x61c8e34b, 0x61d2dc53, 0x61dcd59b, 0x61e6cf24, 0x61f0c8ee,
8170x61fac2fa, 0x6204bd46, 0x620eb7d4, 0x6218b2a2, 0x6222adb1, 0x622ca902, 0x6236a493, 0x6240a065,
8180x624a9c78, 0x625498cd, 0x625e9562, 0x62689238, 0x62728f4e, 0x627c8ca6, 0x62868a3e, 0x62908818,
8190x629a8632, 0x62a4848d, 0x62ae8329, 0x62b88205, 0x62c28123, 0x62cc8081, 0x62d68020, 0x62e07fff,
8200x62ea8020, 0x62f48081, 0x62fe8123, 0x63088205, 0x63128328, 0x631c848c, 0x63268631, 0x63308816,
8210x633a8a3b, 0x63448ca2, 0x634e8f49, 0x63589230, 0x63629558, 0x636c98c1, 0x63769c6a, 0x6380a054,
8220x638aa47e, 0x6394a8e9, 0x639ead94, 0x63a8b280, 0x63b2b7ac, 0x63bcbd19, 0x63c6c2c6, 0x63d0c8b3,
8230x63dacee1, 0x63e4d550, 0x63eedbff, 0x63f8e2ee, 0x6402ea1d, 0x640cf18d, 0x6416f93e, 0x6421012e,
8240x642b095f, 0x643511d0, 0x643f1a82, 0x64492374, 0x64532ca6, 0x645d3618, 0x64673fcb, 0x647149bd,
8250x647b53f0, 0x64855e64, 0x648f6917, 0x6499740b, 0x64a37f3e, 0x64ad8ab2, 0x64b79666, 0x64c1a25b,
8260x64cbae8f, 0x64d5bb03, 0x64dfc7b8, 0x64e9d4ad, 0x64f3e1e1, 0x64fdef56, 0x6507fd0b, 0x65120b00,
8270x651c1934, 0x652627a9, 0x6530365e, 0x653a4553, 0x65445488, 0x654e63fd, 0x655873b1, 0x656283a6,
8280x656c93db, 0x6576a44f, 0x6580b503, 0x658ac5f8, 0x6594d72c, 0x659ee8a0, 0x65a8fa54, 0x65b30c47,
8290x65bd1e7b, 0x65c730ee, 0x65d143a1, 0x65db5694, 0x65e569c7, 0x65ef7d39, 0x65f990eb, 0x6603a4dd,
8300x660db90f, 0x6617cd80, 0x6621e231, 0x662bf722, 0x66360c52, 0x664021c2, 0x664a3772, 0x66544d62,
8310x665e6390, 0x666879ff, 0x667290ad, 0x667ca79b, 0x6686bec8, 0x6690d635, 0x669aede2, 0x66a505ce,
8320x66af1df9, 0x66b93664, 0x66c34f0f, 0x66cd67f9, 0x66d78123, 0x66e19a8c, 0x66ebb434, 0x66f5ce1c,
8330x66ffe843, 0x670a02aa, 0x67141d50, 0x671e3836, 0x6728535b, 0x67326ebf, 0x673c8a63, 0x6746a646,
8340x6750c268, 0x675adeca, 0x6764fb6b, 0x676f184b, 0x6779356a, 0x678352c9, 0x678d7067, 0x67978e45,
8350x67a1ac61, 0x67abcabd, 0x67b5e958, 0x67c00832, 0x67ca274c, 0x67d446a4, 0x67de663c, 0x67e88613,
8360x67f2a629, 0x67fcc67e, 0x6806e712, 0x681107e6, 0x681b28f8, 0x68254a4a, 0x682f6bda, 0x68398daa,
8370x6843afb9, 0x684dd206, 0x6857f493, 0x6862175f, 0x686c3a6a, 0x68765db3, 0x6880813c, 0x688aa504,
8380x6894c90a, 0x689eed50, 0x68a911d5, 0x68b33698, 0x68bd5b9a, 0x68c780dc, 0x68d1a65c, 0x68dbcc1b,
8390x68e5f218, 0x68f01855, 0x68fa3ed0, 0x6904658b, 0x690e8c84, 0x6918b3bc, 0x6922db32, 0x692d02e8,
8400x69372adc, 0x6941530f, 0x694b7b81, 0x6955a431, 0x695fcd20, 0x6969f64e, 0x69741fbb, 0x697e4966,
8410x69887350, 0x69929d78, 0x699cc7df, 0x69a6f285, 0x69b11d69, 0x69bb488c, 0x69c573ee, 0x69cf9f8e,
8420x69d9cb6d, 0x69e3f78a, 0x69ee23e6, 0x69f85080, 0x6a027d59, 0x6a0caa71, 0x6a16d7c7, 0x6a21055b,
8430x6a2b332e, 0x6a35613f, 0x6a3f8f8f, 0x6a49be1d, 0x6a53ecea, 0x6a5e1bf5, 0x6a684b3f, 0x6a727ac7,
8440x6a7caa8d, 0x6a86da91, 0x6a910ad4, 0x6a9b3b56, 0x6aa56c15, 0x6aaf9d13, 0x6ab9ce50, 0x6ac3ffca,
8450x6ace3183, 0x6ad8637b, 0x6ae295b0, 0x6aecc824, 0x6af6fad6, 0x6b012dc6, 0x6b0b60f4, 0x6b159461,
8460x6b1fc80c, 0x6b29fbf5, 0x6b34301c, 0x6b3e6481, 0x6b489925, 0x6b52ce06, 0x6b5d0326, 0x6b673884,
8470x6b716e20, 0x6b7ba3fa, 0x6b85da12, 0x6b901068, 0x6b9a46fd, 0x6ba47dcf, 0x6baeb4df, 0x6bb8ec2e,
8480x6bc323ba, 0x6bcd5b85, 0x6bd7938d, 0x6be1cbd3, 0x6bec0458, 0x6bf63d1a, 0x6c00761a, 0x6c0aaf58,
8490x6c14e8d4, 0x6c1f228e, 0x6c295c86, 0x6c3396bc, 0x6c3dd130, 0x6c480be1, 0x6c5246d1, 0x6c5c81fe,
8500x6c66bd69, 0x6c70f912, 0x6c7b34f8, 0x6c85711d, 0x6c8fad7f, 0x6c99ea1f, 0x6ca426fd, 0x6cae6418,
8510x6cb8a172, 0x6cc2df09, 0x6ccd1cdd, 0x6cd75af0, 0x6ce19940, 0x6cebd7ce, 0x6cf61699, 0x6d0055a2,
8520x6d0a94e9, 0x6d14d46d, 0x6d1f142f, 0x6d29542f, 0x6d33946c, 0x6d3dd4e7, 0x6d4815a0, 0x6d525695,
8530x6d5c97c9, 0x6d66d93a, 0x6d711ae9, 0x6d7b5cd5, 0x6d859eff, 0x6d8fe166, 0x6d9a240a, 0x6da466ec,
8540x6daeaa0c, 0x6db8ed69, 0x6dc33104, 0x6dcd74db, 0x6dd7b8f1, 0x6de1fd44, 0x6dec41d4, 0x6df686a1,
8550x6e00cbac, 0x6e0b10f5, 0x6e15567a, 0x6e1f9c3d, 0x6e29e23d, 0x6e34287b, 0x6e3e6ef6, 0x6e48b5ae,
8560x6e52fca4, 0x6e5d43d7, 0x6e678b47, 0x6e71d2f4, 0x6e7c1adf, 0x6e866307, 0x6e90ab6c, 0x6e9af40e,
8570x6ea53ced, 0x6eaf860a, 0x6eb9cf64, 0x6ec418fb, 0x6ece62cf, 0x6ed8ace0, 0x6ee2f72e, 0x6eed41ba,
8580x6ef78c83, 0x6f01d788, 0x6f0c22cb, 0x6f166e4b, 0x6f20ba08, 0x6f2b0602, 0x6f355239, 0x6f3f9ead,
8590x6f49eb5e, 0x6f54384d, 0x6f5e8578, 0x6f68d2e0, 0x6f732085, 0x6f7d6e67, 0x6f87bc86, 0x6f920ae2,
8600x6f9c597b, 0x6fa6a851, 0x6fb0f763, 0x6fbb46b3, 0x6fc59640, 0x6fcfe609, 0x6fda360f, 0x6fe48652,
8610x6feed6d2, 0x6ff9278f, 0x70037889, 0x700dc9bf, 0x70181b32, 0x70226ce3, 0x702cbecf, 0x703710f9,
8620x7041635f, 0x704bb602, 0x705608e2, 0x70605bff, 0x706aaf58, 0x707502ee, 0x707f56c1, 0x7089aad0,
8630x7093ff1c, 0x709e53a5, 0x70a8a86a, 0x70b2fd6c, 0x70bd52ab, 0x70c7a826, 0x70d1fdde, 0x70dc53d2,
8640x70e6aa03, 0x70f10071, 0x70fb571b, 0x7105ae02, 0x71100525, 0x711a5c85, 0x7124b421, 0x712f0bfa,
8650x7139640f, 0x7143bc61, 0x714e14ef, 0x71586dba, 0x7162c6c1, 0x716d2004, 0x71777984, 0x7181d341,
8660x718c2d3a, 0x7196876f, 0x71a0e1e1, 0x71ab3c8f, 0x71b59779, 0x71bff2a0, 0x71ca4e03, 0x71d4a9a3,
8670x71df057e, 0x71e96197, 0x71f3bdeb, 0x71fe1a7c, 0x72087749, 0x7212d452, 0x721d3197, 0x72278f19,
8680x7231ecd7, 0x723c4ad1, 0x7246a908, 0x7251077b, 0x725b6629, 0x7265c514, 0x7270243c, 0x727a839f,
8690x7284e33f, 0x728f431a, 0x7299a332, 0x72a40386, 0x72ae6416, 0x72b8c4e2, 0x72c325eb, 0x72cd872f,
8700x72d7e8af, 0x72e24a6c, 0x72ecac64, 0x72f70e99, 0x73017109, 0x730bd3b6, 0x7316369f, 0x732099c3,
8710x732afd24, 0x733560c0, 0x733fc499, 0x734a28ad, 0x73548cfe, 0x735ef18a, 0x73695652, 0x7373bb57,
8720x737e2097, 0x73888613, 0x7392ebca, 0x739d51be, 0x73a7b7ee, 0x73b21e59, 0x73bc8500, 0x73c6ebe4,
8730x73d15302, 0x73dbba5d, 0x73e621f4, 0x73f089c6, 0x73faf1d4, 0x74055a1e, 0x740fc2a3, 0x741a2b65,
8740x74249462, 0x742efd9b, 0x7439670f, 0x7443d0bf, 0x744e3aab, 0x7458a4d3, 0x74630f36, 0x746d79d5,
8750x7477e4af, 0x74824fc6, 0x748cbb17, 0x749726a5, 0x74a1926e, 0x74abfe73, 0x74b66ab3, 0x74c0d72f,
8760x74cb43e6, 0x74d5b0d9, 0x74e01e07, 0x74ea8b71, 0x74f4f917, 0x74ff66f8, 0x7509d514, 0x7514436c,
8770x751eb200, 0x752920cf, 0x75338fd9, 0x753dff1f, 0x75486ea1, 0x7552de5d, 0x755d4e56, 0x7567be89,
8780x75722ef8, 0x757c9fa3, 0x75871089, 0x759181aa, 0x759bf306, 0x75a6649e, 0x75b0d671, 0x75bb4880,
8790x75c5baca, 0x75d02d4f, 0x75daa00f, 0x75e5130b, 0x75ef8642, 0x75f9f9b4, 0x76046d62, 0x760ee14b,
8800x7619556f, 0x7623c9ce, 0x762e3e68, 0x7638b33e, 0x7643284f, 0x764d9d9b, 0x76581322, 0x766288e4,
8810x766cfee2, 0x7677751b, 0x7681eb8e, 0x768c623d, 0x7696d927, 0x76a1504d, 0x76abc7ad, 0x76b63f48,
8820x76c0b71f, 0x76cb2f30, 0x76d5a77d, 0x76e02004, 0x76ea98c7, 0x76f511c4, 0x76ff8afd, 0x770a0471,
8830x77147e1f, 0x771ef809, 0x7729722d, 0x7733ec8d, 0x773e6727, 0x7748e1fd, 0x77535d0d, 0x775dd858,
8840x776853df, 0x7772cfa0, 0x777d4b9c, 0x7787c7d2, 0x77924444, 0x779cc0f1, 0x77a73dd8, 0x77b1bafa,
8850x77bc3858, 0x77c6b5ef, 0x77d133c2, 0x77dbb1d0, 0x77e63018, 0x77f0ae9b, 0x77fb2d59, 0x7805ac52,
8860x78102b85, 0x781aaaf3, 0x78252a9c, 0x782faa80, 0x783a2a9e, 0x7844aaf7, 0x784f2b8a, 0x7859ac59,
8870x78642d62, 0x786eaea5, 0x78793024, 0x7883b1dd, 0x788e33d0, 0x7898b5fe, 0x78a33867, 0x78adbb0b,
8880x78b83de9, 0x78c2c101, 0x78cd4454, 0x78d7c7e2, 0x78e24baa, 0x78eccfad, 0x78f753ea, 0x7901d862,
8890x790c5d15, 0x7916e202, 0x79216729, 0x792bec8b, 0x79367227, 0x7940f7fe, 0x794b7e0f, 0x7956045b,
8900x79608ae1, 0x796b11a1, 0x7975989c, 0x79801fd1, 0x798aa741, 0x79952eeb, 0x799fb6d0, 0x79aa3eee,
8910x79b4c748, 0x79bf4fdb, 0x79c9d8a9, 0x79d461b1, 0x79deeaf4, 0x79e97470, 0x79f3fe27, 0x79fe8819,
8920x7a091244, 0x7a139caa, 0x7a1e274a, 0x7a28b225, 0x7a333d39, 0x7a3dc888, 0x7a485411, 0x7a52dfd4,
8930x7a5d6bd2, 0x7a67f809, 0x7a72847b, 0x7a7d1127, 0x7a879e0d, 0x7a922b2e, 0x7a9cb888, 0x7aa7461d,
8940x7ab1d3eb, 0x7abc61f4, 0x7ac6f037, 0x7ad17eb4, 0x7adc0d6b, 0x7ae69c5c, 0x7af12b87, 0x7afbbaec,
8950x7b064a8b, 0x7b10da64, 0x7b1b6a78, 0x7b25fac5, 0x7b308b4c, 0x7b3b1c0e, 0x7b45ad09, 0x7b503e3e,
8960x7b5acfad, 0x7b656156, 0x7b6ff339, 0x7b7a8556, 0x7b8517ad, 0x7b8faa3e, 0x7b9a3d09, 0x7ba4d00d,
8970x7baf634c, 0x7bb9f6c4, 0x7bc48a76, 0x7bcf1e62, 0x7bd9b288, 0x7be446e8, 0x7beedb82, 0x7bf97055,
8980x7c040562, 0x7c0e9aa9, 0x7c19302a, 0x7c23c5e5, 0x7c2e5bd9, 0x7c38f207, 0x7c43886f, 0x7c4e1f10,
8990x7c58b5ec, 0x7c634d01, 0x7c6de450, 0x7c787bd8, 0x7c83139a, 0x7c8dab96, 0x7c9843cb, 0x7ca2dc3a,
9000x7cad74e3, 0x7cb80dc6, 0x7cc2a6e2, 0x7ccd4037, 0x7cd7d9c7, 0x7ce27390, 0x7ced0d92, 0x7cf7a7ce,
9010x7d024244, 0x7d0cdcf3, 0x7d1777dc, 0x7d2212fe, 0x7d2cae5a, 0x7d3749ef, 0x7d41e5be, 0x7d4c81c7,
9020x7d571e08, 0x7d61ba84, 0x7d6c5739, 0x7d76f427, 0x7d81914f, 0x7d8c2eb0, 0x7d96cc4b, 0x7da16a1f,
9030x7dac082d, 0x7db6a673, 0x7dc144f4, 0x7dcbe3ae, 0x7dd682a1, 0x7de121cd, 0x7debc133, 0x7df660d2,
9040x7e0100ab, 0x7e0ba0bd, 0x7e164108, 0x7e20e18d, 0x7e2b824b, 0x7e362342, 0x7e40c472, 0x7e4b65dc,
9050x7e56077f, 0x7e60a95b, 0x7e6b4b71, 0x7e75edc0, 0x7e809048, 0x7e8b3309, 0x7e95d603, 0x7ea07937,
9060x7eab1ca4, 0x7eb5c04a, 0x7ec06429, 0x7ecb0842, 0x7ed5ac93, 0x7ee0511e, 0x7eeaf5e2, 0x7ef59adf,
9070x7f004015, 0x7f0ae584, 0x7f158b2c, 0x7f20310e, 0x7f2ad728, 0x7f357d7c, 0x7f402409, 0x7f4acace,
9080x7f5571cd, 0x7f601905, 0x7f6ac076, 0x7f75681f, 0x7f801002, 0x7f8ab81e, 0x7f956073, 0x7fa00901,
9090x7faab1c7, 0x7fb55ac7, 0x7fc00400, 0x7fcaad71, 0x7fd5571c, 0x7fe00100, 0x7feaab1c, 0x7ff55571,
9100x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9110x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9120x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9130x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9140x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9150x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9160x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9170x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9180x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9190x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9200x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9210x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9220x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9230x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9240x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9250x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9260x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9270x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9280x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9290x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9300x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9310x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9320x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9330x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9340x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9350x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9360x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9370x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9380x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9390x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9400x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9410x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9420x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9430x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9440x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9450x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9460x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9470x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9480x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9490x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9500x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9510x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9520x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9530x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9540x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9550x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9560x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9570x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9580x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9590x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9600x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9610x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9620x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9630x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9640x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9650x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9660x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9670x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9680x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9690x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9700x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9710x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9720x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9730x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9740x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9750x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9760x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9770x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9780x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9790x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9800x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9810x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9820x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9830x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9840x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9850x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9860x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9870x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9880x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9890x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9900x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9910x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9920x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9930x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9940x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9950x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9960x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9970x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9980x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
9990x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10000x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10010x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10020x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10030x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10040x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10050x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10060x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10070x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10080x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10090x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10100x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10110x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10120x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10130x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10140x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10150x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10160x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10170x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10180x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10190x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10200x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10210x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10220x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10230x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10240x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10250x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10260x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10270x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10280x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10290x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10300x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10310x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10320x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10330x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10340x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10350x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10360x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10370x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10380x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10390x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10400x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10410x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10420x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10430x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10440x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10450x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10460x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10470x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10480x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10490x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10500x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10510x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10520x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10530x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10540x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10550x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10560x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10570x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10580x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10590x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10600x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10610x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10620x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10630x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10640x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10650x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10660x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10670x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10680x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10690x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10700x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10710x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10720x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10730x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10740x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10750x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10760x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10770x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10780x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10790x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10800x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10810x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10820x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10830x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10840x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10850x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10860x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10870x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10880x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10890x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10900x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10910x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10920x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10930x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10940x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10950x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10960x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10970x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10980x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
10990x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11000x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11010x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11020x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11030x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11040x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11050x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11060x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11070x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11080x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11090x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11100x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11110x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11120x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11130x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11140x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11150x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11160x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11170x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11180x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11190x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11200x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11210x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11220x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11230x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11240x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11250x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11260x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11270x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11280x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11290x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11300x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11310x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11320x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11330x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11340x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11350x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11360x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11370x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11380x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11390x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11400x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11410x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11420x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11430x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11440x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11450x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11460x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11470x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11480x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11490x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11500x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11510x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11520x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11530x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11540x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11550x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11560x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11570x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11580x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11590x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11600x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11610x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11620x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11630x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11640x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11650x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11660x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11670x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11680x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11690x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11700x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11710x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11720x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11730x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11740x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11750x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11760x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11770x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11780x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11790x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11800x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11810x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11820x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11830x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11840x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11850x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11860x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11870x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11880x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11890x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11900x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11910x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11920x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11930x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11940x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11950x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11960x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11970x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11980x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
11990x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12000x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12010x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12020x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12030x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12040x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12050x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12060x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12070x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12080x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12090x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12100x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12110x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12120x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12130x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12140x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12150x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12160x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12170x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12180x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12190x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12200x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12210x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12220x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12230x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12240x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12250x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12260x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12270x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12280x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12290x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12300x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12310x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12320x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12330x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12340x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12350x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12360x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12370x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12380x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12390x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12400x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12410x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12420x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12430x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12440x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12450x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12460x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12470x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12480x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12490x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12500x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12510x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12520x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12530x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12540x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12550x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12560x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12570x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12580x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12590x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12600x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12610x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12620x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12630x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12640x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12650x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12660x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12670x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12680x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12690x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12700x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12710x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12720x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12730x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12740x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12750x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12760x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12770x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12780x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12790x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12800x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12810x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12820x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12830x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12840x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12850x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12860x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12870x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12880x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12890x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12900x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12910x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12920x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12930x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12940x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12950x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12960x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12970x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12980x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
12990x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13000x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13010x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13020x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13030x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13040x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13050x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13060x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13070x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13080x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13090x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13100x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13110x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13120x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13130x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13140x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13150x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13160x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13170x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13180x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13190x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13200x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13210x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13220x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13230x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13240x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13250x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13260x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13270x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13280x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13290x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13300x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13310x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13320x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13330x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13340x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13350x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13360x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13370x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13380x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13390x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13400x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13410x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13420x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13430x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13440x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13450x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13460x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13470x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13480x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13490x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13500x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13510x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13520x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13530x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13540x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13550x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13560x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13570x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13580x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13590x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13600x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13610x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13620x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13630x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13640x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13650x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13660x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13670x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13680x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13690x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13700x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13710x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13720x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13730x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13740x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13750x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13760x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13770x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13780x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13790x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13800x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13810x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13820x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13830x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13840x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13850x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13860x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13870x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13880x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13890x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13900x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13910x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13920x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13930x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13940x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13950x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13960x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13970x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13980x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
13990x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
14000x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
14010x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
14020x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
14030x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
14040x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
14050x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
14060x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
14070x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
14080x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
14090x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
14100x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
14110x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
14120x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
14130x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
14140x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
14150x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
14160x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
14170x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
14180x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
14190x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
14200x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
14210x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
14220x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
14230x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,};
1424#endif
1425#ifdef USE_DATA_TABLES
1426static long mpeg3_aa_cs_data[] = {
14270x00006dc2, 0x000070dc, 0x0000798d, 0x00007ddd, 0x00007f6d, 0x00007fe4, 0x00007ffc, 0x00007fff,};
1428#endif
1429#ifdef USE_DATA_TABLES
1430static long mpeg3_aa_ca_data[] = {
14310xffffbe26, 0xffffc39f, 0xffffd7e4, 0xffffe8b8, 0xfffff3e5, 0xfffffac2, 0xfffffe2f, 0xffffff87,};
1432#endif
1433#ifdef USE_DATA_TABLES
1434static long mpeg3_win_data[] = {
14350x00000421, 0x00000db8, 0x000019c7, 0x000029ad, 0x00003fff, 0x00006246, 0x00009ee0, 0x00012a7d,
14360x0003df40, 0xfffbc63e, 0xfffe7b01, 0xffff069e, 0xffff4338, 0xffff657e, 0xffff7bd0, 0xffff8bb6,
14370xffff97c5, 0xffffa15c, 0xffffa947, 0xffffb006, 0xffffb5eb, 0xffffbb30, 0xffffc000, 0xffffc47a,
14380xffffc8b7, 0xffffccca, 0xffffd0c5, 0xffffd4b9, 0xffffd8b4, 0xffffdcc8, 0xffffe104, 0xffffe57e,
14390xffffea4e, 0xffffef94, 0xfffff579, 0xfffffc37, 0x00000421, 0x00000db8, 0x000019c7, 0x000029ad,
14400x00003fff, 0x00006246, 0x00009ee0, 0x00012a7d, 0x0003df40, 0xfffbc63e, 0xfffe7b01, 0xffff069e,
14410xffff4338, 0xffff657e, 0xffff7bd0, 0xffff8bb6, 0xffff97c5, 0xffffa15c, 0xffffa932, 0xffffaf55,
14420xffffb41e, 0xffffb7d9, 0xffffbabb, 0xffffbce5, 0xffffbf02, 0xffffc45d, 0xffffcd2e, 0xffffd901,
14430xffffe74d, 0xfffff772, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
14440x00000db8, 0x00003fff, 0x00012a7d, 0xfffe7b01, 0xffff657e, 0xffff97c5, 0xffffb006, 0xffffc000,
14450xffffccca, 0xffffd8b4, 0xffffe57e, 0xfffff579, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
14460x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
14470x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
14480x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
14490x00000000, 0x00000000, 0x00002698, 0x0000bba3, 0x00037d32, 0xfffb73f7, 0xfffe3b01, 0xfffedad6,
14500xffff2b2b, 0xffff58c3, 0xffff7566, 0xffff88e3, 0xffff96df, 0xffffa145, 0xffffa947, 0xffffb006,
14510xffffb5eb, 0xffffbb30, 0xffffc000, 0xffffc47a, 0xffffc8b7, 0xffffccca, 0xffffd0c5, 0xffffd4b9,
14520xffffd8b4, 0xffffdcc8, 0xffffe104, 0xffffe57e, 0xffffea4e, 0xffffef94, 0xfffff579, 0xfffffc37,};
1453#endif
1454#ifdef USE_DATA_TABLES
1455static long mpeg3_COS9_data[] = {
14560x00008000, 0x00007e0e, 0x00007847, 0x00006ed9, 0x0000620d, 0x00005246, 0x00004000, 0x00002bc7,
14570x0000163a,};
1458#endif
1459#ifdef USE_DATA_TABLES
1460static long mpeg3_tfcos36_data[] = {
14610x0000403e, 0x00004241, 0x0000469d, 0x00004e21, 0x00005a82, 0x00006f94, 0x0000976f, 0x0000f746,
14620x0002de51,};
1463#endif
1464#ifdef USE_DATA_TABLES
1465static long mpeg3_tfcos12_data[] = {
14660x00004241, 0x00005a82, 0x0000f746,};
1467#endif
1468#ifdef USE_DATA_TABLES
1469static long mpeg3_cos9_data[] = {
14700x00007847, 0xffffe9c6, 0xffff9df3,};
1471#endif
1472#ifdef USE_DATA_TABLES
1473static long mpeg3_cos18_data[] = {
14740x00007e0e, 0xffffd439, 0xffffadba,};
1475#endif
1476#ifdef USE_DATA_TABLES
1477static long mpeg3_COS1_data[] = {
14780x00004deb, 0xffff89bf, 0xffffef4b, 0x00007ee7, 0xffffcf05, 0xffff9a74, 0x000030fb, 0xffff89bf,
14790x00007641, 0xffffcf05, 0xffffcf05, 0x00007641, 0x000010b5, 0xffffcf05, 0x00004deb, 0xffff9a74,
14800x00007641, 0xffff8119, 0xffffef4b, 0x000030fb, 0xffffb215, 0x0000658c, 0xffff89bf, 0x00007ee7,
14810xffffcf05, 0x00007641, 0xffff89bf, 0x000030fb, 0x000030fb, 0xffff89bf, 0xffffb215, 0x00007641,
14820x000010b5, 0xffff8119, 0x000030fb, 0x0000658c, 0xffff9a74, 0x000030fb, 0x00007ee7, 0x000010b5,
14830xffff89bf, 0xffffb215, 0xffff89bf, 0xffffcf05, 0x000030fb, 0x00007641, 0x00007641, 0x000030fb,
14840xffff8119, 0xffff89bf, 0xffff9a74, 0xffffb215, 0xffffcf05, 0xffffef4b, 0xffff8119, 0xffff89bf,
14850xffff9a74, 0xffffb215, 0xffffcf05, 0xffffef4b, 0xffff89bf, 0xffffcf05, 0x000030fb, 0x00007641,
14860x00007641, 0x000030fb, 0xffff9a74, 0x000030fb, 0x00007ee7, 0x000010b5, 0xffff89bf, 0xffffb215,};
1487#endif
1488#ifdef USE_DATA_TABLES
1489static long mpeg3_win1_data[] = {
14900x00000421, 0xfffff248, 0x000019c7, 0xffffd653, 0x00003fff, 0xffff9dba, 0x00009ee0, 0xfffed583,
14910x0003df40, 0x000439c2, 0xfffe7b01, 0x0000f962, 0xffff4338, 0x00009a82, 0xffff7bd0, 0x0000744a,
14920xffff97c5, 0x00005ea4, 0xffffa947, 0x00004ffa, 0xffffb5eb, 0x000044d0, 0xffffc000, 0x00003b86,
14930xffffc8b7, 0x00003336, 0xffffd0c5, 0x00002b47, 0xffffd8b4, 0x00002338, 0xffffe104, 0x00001a82,
14940xffffea4e, 0x0000106c, 0xfffff579, 0x000003c9, 0x00000421, 0xfffff248, 0x000019c7, 0xffffd653,
14950x00003fff, 0xffff9dba, 0x00009ee0, 0xfffed583, 0x0003df40, 0x000439c2, 0xfffe7b01, 0x0000f962,
14960xffff4338, 0x00009a82, 0xffff7bd0, 0x0000744a, 0xffff97c5, 0x00005ea4, 0xffffa932, 0x000050ab,
14970xffffb41e, 0x00004827, 0xffffbabb, 0x0000431b, 0xffffbf02, 0x00003ba3, 0xffffcd2e, 0x000026ff,
14980xffffe74d, 0x0000088e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
14990x00000db8, 0xffffc001, 0x00012a7d, 0x000184ff, 0xffff657e, 0x0000683b, 0xffffb006, 0x00004000,
15000xffffccca, 0x0000274c, 0xffffe57e, 0x00000a87, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
15010x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
15020x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
15030x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
15040x00000000, 0x00000000, 0x00002698, 0xffff445d, 0x00037d32, 0x00048c09, 0xfffe3b01, 0x0001252a,
15050xffff2b2b, 0x0000a73d, 0xffff7566, 0x0000771d, 0xffff96df, 0x00005ebb, 0xffffa947, 0x00004ffa,
15060xffffb5eb, 0x000044d0, 0xffffc000, 0x00003b86, 0xffffc8b7, 0x00003336, 0xffffd0c5, 0x00002b47,
15070xffffd8b4, 0x00002338, 0xffffe104, 0x00001a82, 0xffffea4e, 0x0000106c, 0xfffff579, 0x000003c9,};
1508#endif
1509#ifdef USE_DATA_TABLES
1510static long mpeg3_tan1_1_data[] = {
15110x00000000, 0x00001b0c, 0x00002ed9, 0x00003fff, 0x00005126, 0x000064f3, 0x00007fff, 0x0000aed9,
15120x00012ed9, 0x7fffffff, 0xffff5127, 0xffffd127, 0x00000000, 0x00001b0c, 0x00002ed9, 0x00003fff,};
1513#endif
1514#ifdef USE_DATA_TABLES
1515static long mpeg3_tan2_1_data[] = {
15160x00008000, 0x000064f3, 0x00005126, 0x00004000, 0x00002ed9, 0x00001b0c, 0x00000000, 0xffffd127,
15170xffff5127, 0x80000000, 0x00012ed9, 0x0000aed9, 0x00008000, 0x000064f3, 0x00005126, 0x00004000,};
1518#endif
1519#ifdef USE_DATA_TABLES
1520static long mpeg3_tan1_2_data[] = {
15210x00000000, 0x00002640, 0x00004241, 0x00005a82, 0x000072c2, 0x00008ec3, 0x0000b504, 0x0000f746,
15220x0001ac4b, 0x7fffffff, 0xffff08ba, 0xffffbdbf, 0x00000000, 0x00002640, 0x00004241, 0x00005a82,};
1523#endif
1524#ifdef USE_DATA_TABLES
1525static long mpeg3_tan2_2_data[] = {
15260x0000b504, 0x00008ec3, 0x000072c2, 0x00005a82, 0x00004241, 0x00002640, 0x00000000, 0xffffbdbf,
15270xffff08ba, 0x80000000, 0x0001ac4b, 0x0000f746, 0x0000b504, 0x00008ec3, 0x000072c2, 0x00005a82,};
1528#endif
1529#ifdef USE_DATA_TABLES
1530static long mpeg3_pow1_1_data[] = {
15310x00008000, 0x00006ba2, 0x00008000, 0x00005a82, 0x00008000, 0x00004c1b, 0x00008000, 0x00004000,
15320x00008000, 0x000035d1, 0x00008000, 0x00002d41, 0x00008000, 0x0000260d, 0x00008000, 0x00002000,
15330x00008000, 0x00005a82, 0x00008000, 0x00003fff, 0x00008000, 0x00002d41, 0x00008000, 0x00001fff,
15340x00008000, 0x000016a0, 0x00008000, 0x00000fff, 0x00008000, 0x00000b50, 0x00008000, 0x000007ff,};
1535#endif
1536#ifdef USE_DATA_TABLES
1537static long mpeg3_pow2_1_data[] = {
15380x00008000, 0x00008000, 0x00006ba2, 0x00008000, 0x00005a82, 0x00008000, 0x00004c1b, 0x00008000,
15390x00004000, 0x00008000, 0x000035d1, 0x00008000, 0x00002d41, 0x00008000, 0x0000260d, 0x00008000,
15400x00008000, 0x00008000, 0x00005a82, 0x00008000, 0x00003fff, 0x00008000, 0x00002d41, 0x00008000,
15410x00001fff, 0x00008000, 0x000016a0, 0x00008000, 0x00000fff, 0x00008000, 0x00000b50, 0x00008000,};
1542#endif
1543#ifdef USE_DATA_TABLES
1544static long mpeg3_pow1_2_data[] = {
15450x0000b504, 0x00009837, 0x0000b504, 0x00008000, 0x0000b504, 0x00006ba2, 0x0000b504, 0x00005a82,
15460x0000b504, 0x00004c1b, 0x0000b504, 0x00004000, 0x0000b504, 0x000035d1, 0x0000b504, 0x00002d41,
15470x0000b504, 0x00008000, 0x0000b504, 0x00005a82, 0x0000b504, 0x00003fff, 0x0000b504, 0x00002d41,
15480x0000b504, 0x00001fff, 0x0000b504, 0x000016a0, 0x0000b504, 0x00000fff, 0x0000b504, 0x00000b50,};
1549#endif
1550#ifdef USE_DATA_TABLES
1551static long mpeg3_pow2_2_data[] = {
15520x0000b504, 0x0000b504, 0x00009837, 0x0000b504, 0x00008000, 0x0000b504, 0x00006ba2, 0x0000b504,
15530x00005a82, 0x0000b504, 0x00004c1b, 0x0000b504, 0x00004000, 0x0000b504, 0x000035d1, 0x0000b504,
15540x0000b504, 0x0000b504, 0x00008000, 0x0000b504, 0x00005a82, 0x0000b504, 0x00003fff, 0x0000b504,
15550x00002d41, 0x0000b504, 0x00001fff, 0x0000b504, 0x000016a0, 0x0000b504, 0x00000fff, 0x0000b504,};
1556#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 @@
1#include "mpeg3audio.h"
2#include "tables.h"
3#include "../libmpeg3.h"
4#include "../mpeg3protos.h"
5
6#include <stdio.h>
7
8/* Return 1 if the head check doesn't find a header. */
9int mpeg3audio_head_check(unsigned long head)
10{
11 if((head & 0xffe00000) != 0xffe00000) return 1;
12 if(!((head >> 17) & 3)) return 1;
13 if(((head >> 12) & 0xf) == 0xf) return 1;
14 if(!((head >> 12) & 0xf)) return 1;
15 if(((head >> 10) & 0x3) == 0x3 ) return 1;
16 if(((head >> 19) & 1) == 1 && ((head >> 17) & 3) == 3 && ((head >> 16) & 1) == 1)
17 return 1;
18 if((head & 0xffff0000) == 0xfffe0000) return 1;
19
20 return 0;
21}
22
23int mpeg3audio_decode_header(mpeg3audio_t *audio)
24{
25 if(audio->newhead & (1 << 20))
26 {
27 audio->lsf = (audio->newhead & (1 << 19)) ? 0x0 : 0x1;
28 audio->mpeg35 = 0;
29 }
30 else
31 {
32 audio->lsf = 1;
33 audio->mpeg35 = 1;
34 }
35
36 audio->layer = 4 - ((audio->newhead >> 17) & 3);
37 if(audio->mpeg35)
38 audio->sampling_frequency_code = 6 + ((audio->newhead >> 10) & 0x3);
39 else
40 audio->sampling_frequency_code = ((audio->newhead >> 10) & 0x3) + (audio->lsf * 3);
41
42 audio->error_protection = ((audio->newhead >> 16) & 0x1) ^ 0x1;
43
44 audio->bitrate_index = ((audio->newhead >> 12) & 0xf);
45 audio->padding = ((audio->newhead >> 9) & 0x1);
46 audio->extension = ((audio->newhead >> 8) & 0x1);
47 audio->mode = ((audio->newhead >> 6) & 0x3);
48 audio->mode_ext = ((audio->newhead >> 4) & 0x3);
49 audio->copyright = ((audio->newhead >> 3) & 0x1);
50 audio->original = ((audio->newhead >> 2) & 0x1);
51 audio->emphasis = audio->newhead & 0x3;
52 audio->channels = (audio->mode == MPG_MD_MONO) ? 1 : 2;
53 if(audio->channels > 1)
54 audio->single = -1;
55 else
56 audio->single = 3;
57
58 audio->prev_framesize = audio->framesize;
59
60 if(!audio->bitrate_index) return 1;
61 audio->bitrate = 1000 * mpeg3_tabsel_123[audio->lsf][audio->layer - 1][audio->bitrate_index];
62
63 switch(audio->layer)
64 {
65 case 1:
66 audio->framesize = (long)mpeg3_tabsel_123[audio->lsf][0][audio->bitrate_index] * 12000;
67 audio->framesize /= mpeg3_freqs[audio->sampling_frequency_code];
68 audio->framesize = ((audio->framesize + audio->padding) << 2) - 4;
69 break;
70 case 2:
71 audio->framesize = (long)mpeg3_tabsel_123[audio->lsf][1][audio->bitrate_index] * 144000;
72 audio->framesize /= mpeg3_freqs[audio->sampling_frequency_code];
73 audio->framesize += audio->padding - 4;
74 break;
75 case 3:
76 if(audio->lsf)
77 audio->ssize = (audio->channels == 1) ? 9 : 17;
78 else
79 audio->ssize = (audio->channels == 1) ? 17 : 32;
80 if(audio->error_protection)
81 audio->ssize += 2;
82 audio->framesize = (long)mpeg3_tabsel_123[audio->lsf][2][audio->bitrate_index] * 144000;
83 audio->framesize /= mpeg3_freqs[audio->sampling_frequency_code] << (audio->lsf);
84 audio->framesize = audio->framesize + audio->padding - 4;
85 break;
86 default:
87 return 1;
88 }
89
90 if(audio->framesize > MAXFRAMESIZE) return 1;
91
92 return 0;
93}
94
95int mpeg3audio_read_frame_body(mpeg3audio_t *audio)
96{
97 int i;
98 for(i = 0; i < audio->framesize; i++)
99 {
100 audio->bsbuf[i] = mpeg3bits_getbits(audio->astream, 8);
101 }
102 return 0;
103}
104
105/* Seek to the start of the previous header */
106int mpeg3audio_prev_header(mpeg3audio_t *audio)
107{
108 int result = 0, i, len = (int)audio->avg_framesize;
109
110 for(i = 0; i < len && !result; i++)
111 {
112 mpeg3bits_getbits_reverse(audio->astream, 8);
113 }
114/* Get reading in the forward direction again. */
115 result |= mpeg3bits_refill(audio->astream);
116 return result;
117}
118
119/* Read the next header */
120int mpeg3audio_read_header(mpeg3audio_t *audio)
121{
122 unsigned int code;
123 int i;
124 int attempt = 0;
125 int result = 0;
126
127 switch(audio->format)
128 {
129 case AUDIO_AC3:
130 result = mpeg3audio_read_ac3_header(audio);
131 break;
132
133 case AUDIO_MPEG:
134/* Layer 1 not supported */
135 if(audio->layer == 1)
136 {
137 fprintf(stderr, "mpeg3audio_new: layer 1 not supported\n");
138 result = 1;
139 }
140 audio->newhead = mpeg3bits_showbits(audio->astream, 32);
141 if(!mpeg3bits_eof(audio->astream) &&
142 (mpeg3audio_head_check(audio->newhead) || mpeg3audio_decode_header(audio)))
143 {
144 do
145 {
146 attempt++;
147 mpeg3bits_getbyte_noptr(audio->astream);
148 audio->newhead = mpeg3bits_showbits(audio->astream, 32);
149 }while(!mpeg3bits_eof(audio->astream) &&
150 attempt < 65536 &&
151 (mpeg3audio_head_check(audio->newhead) || mpeg3audio_decode_header(audio)));
152 }
153
154/* Skip the 4 bytes containing the header */
155 mpeg3bits_getbits(audio->astream, 32);
156 break;
157
158 case AUDIO_PCM:
159 mpeg3audio_read_pcm_header(audio);
160 break;
161 }
162 return mpeg3bits_eof(audio->astream);
163}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef HUFFMAN_H
21#define HUFFMAN_H
22
23/*
24 * huffman tables ... recalcualted to work with my optimzed
25 * decoder scheme (MH)
26 *
27 * probably we could save a few bytes of memory, because the
28 * smaller tables are often the part of a bigger table
29 */
30
31struct newhuff
32{
33 unsigned int linbits;
34 short *table;
35};
36
37static short mpeg3_tab0[] =
38{
39 0
40};
41
42static short mpeg3_tab1[] =
43{
44 -5, -3, -1, 17, 1, 16, 0
45};
46
47static short mpeg3_tab2[] =
48{
49 -15, -11, -9, -5, -3, -1, 34, 2, 18, -1, 33, 32, 17, -1, 1,
50 16, 0
51};
52
53static short mpeg3_tab3[] =
54{
55 -13, -11, -9, -5, -3, -1, 34, 2, 18, -1, 33, 32, 16, 17, -1,
56 1, 0
57};
58
59static short mpeg3_tab5[] =
60{
61 -29, -25, -23, -15, -7, -5, -3, -1, 51, 35, 50, 49, -3, -1, 19,
62 3, -1, 48, 34, -3, -1, 18, 33, -1, 2, 32, 17, -1, 1, 16,
63 0
64};
65
66static short mpeg3_tab6[] =
67{
68 -25, -19, -13, -9, -5, -3, -1, 51, 3, 35, -1, 50, 48, -1, 19,
69 49, -3, -1, 34, 2, 18, -3, -1, 33, 32, 1, -1, 17, -1, 16,
70 0
71};
72
73static short mpeg3_tab7[] =
74{
75 -69, -65, -57, -39, -29, -17, -11, -7, -3, -1, 85, 69, -1, 84, 83,
76 -1, 53, 68, -3, -1, 37, 82, 21, -5, -1, 81, -1, 5, 52, -1,
77 80, -1, 67, 51, -5, -3, -1, 36, 66, 20, -1, 65, 64, -11, -7,
78 -3, -1, 4, 35, -1, 50, 3, -1, 19, 49, -3, -1, 48, 34, 18,
79 -5, -1, 33, -1, 2, 32, 17, -1, 1, 16, 0
80};
81
82static short mpeg3_tab8[] =
83{
84 -65, -63, -59, -45, -31, -19, -13, -7, -5, -3, -1, 85, 84, 69, 83,
85 -3, -1, 53, 68, 37, -3, -1, 82, 5, 21, -5, -1, 81, -1, 52,
86 67, -3, -1, 80, 51, 36, -5, -3, -1, 66, 20, 65, -3, -1, 4,
87 64, -1, 35, 50, -9, -7, -3, -1, 19, 49, -1, 3, 48, 34, -1,
88 2, 32, -1, 18, 33, 17, -3, -1, 1, 16, 0
89};
90
91static short mpeg3_tab9[] =
92{
93 -63, -53, -41, -29, -19, -11, -5, -3, -1, 85, 69, 53, -1, 83, -1,
94 84, 5, -3, -1, 68, 37, -1, 82, 21, -3, -1, 81, 52, -1, 67,
95 -1, 80, 4, -7, -3, -1, 36, 66, -1, 51, 64, -1, 20, 65, -5,
96 -3, -1, 35, 50, 19, -1, 49, -1, 3, 48, -5, -3, -1, 34, 2,
97 18, -1, 33, 32, -3, -1, 17, 1, -1, 16, 0
98};
99
100static short mpeg3_tab10[] =
101{
102-125,-121,-111, -83, -55, -35, -21, -13, -7, -3, -1, 119, 103, -1, 118,
103 87, -3, -1, 117, 102, 71, -3, -1, 116, 86, -1, 101, 55, -9, -3,
104 -1, 115, 70, -3, -1, 85, 84, 99, -1, 39, 114, -11, -5, -3, -1,
105 100, 7, 112, -1, 98, -1, 69, 53, -5, -1, 6, -1, 83, 68, 23,
106 -17, -5, -1, 113, -1, 54, 38, -5, -3, -1, 37, 82, 21, -1, 81,
107 -1, 52, 67, -3, -1, 22, 97, -1, 96, -1, 5, 80, -19, -11, -7,
108 -3, -1, 36, 66, -1, 51, 4, -1, 20, 65, -3, -1, 64, 35, -1,
109 50, 3, -3, -1, 19, 49, -1, 48, 34, -7, -3, -1, 18, 33, -1,
110 2, 32, 17, -1, 1, 16, 0
111};
112
113static short mpeg3_tab11[] =
114{
115-121,-113, -89, -59, -43, -27, -17, -7, -3, -1, 119, 103, -1, 118, 117,
116 -3, -1, 102, 71, -1, 116, -1, 87, 85, -5, -3, -1, 86, 101, 55,
117 -1, 115, 70, -9, -7, -3, -1, 69, 84, -1, 53, 83, 39, -1, 114,
118 -1, 100, 7, -5, -1, 113, -1, 23, 112, -3, -1, 54, 99, -1, 96,
119 -1, 68, 37, -13, -7, -5, -3, -1, 82, 5, 21, 98, -3, -1, 38,
120 6, 22, -5, -1, 97, -1, 81, 52, -5, -1, 80, -1, 67, 51, -1,
121 36, 66, -15, -11, -7, -3, -1, 20, 65, -1, 4, 64, -1, 35, 50,
122 -1, 19, 49, -5, -3, -1, 3, 48, 34, 33, -5, -1, 18, -1, 2,
123 32, 17, -3, -1, 1, 16, 0
124};
125
126static short mpeg3_tab12[] =
127{
128-115, -99, -73, -45, -27, -17, -9, -5, -3, -1, 119, 103, 118, -1, 87,
129 117, -3, -1, 102, 71, -1, 116, 101, -3, -1, 86, 55, -3, -1, 115,
130 85, 39, -7, -3, -1, 114, 70, -1, 100, 23, -5, -1, 113, -1, 7,
131 112, -1, 54, 99, -13, -9, -3, -1, 69, 84, -1, 68, -1, 6, 5,
132 -1, 38, 98, -5, -1, 97, -1, 22, 96, -3, -1, 53, 83, -1, 37,
133 82, -17, -7, -3, -1, 21, 81, -1, 52, 67, -5, -3, -1, 80, 4,
134 36, -1, 66, 20, -3, -1, 51, 65, -1, 35, 50, -11, -7, -5, -3,
135 -1, 64, 3, 48, 19, -1, 49, 34, -1, 18, 33, -7, -5, -3, -1,
136 2, 32, 0, 17, -1, 1, 16
137};
138
139static short mpeg3_tab13[] =
140{
141-509,-503,-475,-405,-333,-265,-205,-153,-115, -83, -53, -35, -21, -13, -9,
142 -7, -5, -3, -1, 254, 252, 253, 237, 255, -1, 239, 223, -3, -1, 238,
143 207, -1, 222, 191, -9, -3, -1, 251, 206, -1, 220, -1, 175, 233, -1,
144 236, 221, -9, -5, -3, -1, 250, 205, 190, -1, 235, 159, -3, -1, 249,
145 234, -1, 189, 219, -17, -9, -3, -1, 143, 248, -1, 204, -1, 174, 158,
146 -5, -1, 142, -1, 127, 126, 247, -5, -1, 218, -1, 173, 188, -3, -1,
147 203, 246, 111, -15, -7, -3, -1, 232, 95, -1, 157, 217, -3, -1, 245,
148 231, -1, 172, 187, -9, -3, -1, 79, 244, -3, -1, 202, 230, 243, -1,
149 63, -1, 141, 216, -21, -9, -3, -1, 47, 242, -3, -1, 110, 156, 15,
150 -5, -3, -1, 201, 94, 171, -3, -1, 125, 215, 78, -11, -5, -3, -1,
151 200, 214, 62, -1, 185, -1, 155, 170, -1, 31, 241, -23, -13, -5, -1,
152 240, -1, 186, 229, -3, -1, 228, 140, -1, 109, 227, -5, -1, 226, -1,
153 46, 14, -1, 30, 225, -15, -7, -3, -1, 224, 93, -1, 213, 124, -3,
154 -1, 199, 77, -1, 139, 184, -7, -3, -1, 212, 154, -1, 169, 108, -1,
155 198, 61, -37, -21, -9, -5, -3, -1, 211, 123, 45, -1, 210, 29, -5,
156 -1, 183, -1, 92, 197, -3, -1, 153, 122, 195, -7, -5, -3, -1, 167,
157 151, 75, 209, -3, -1, 13, 208, -1, 138, 168, -11, -7, -3, -1, 76,
158 196, -1, 107, 182, -1, 60, 44, -3, -1, 194, 91, -3, -1, 181, 137,
159 28, -43, -23, -11, -5, -1, 193, -1, 152, 12, -1, 192, -1, 180, 106,
160 -5, -3, -1, 166, 121, 59, -1, 179, -1, 136, 90, -11, -5, -1, 43,
161 -1, 165, 105, -1, 164, -1, 120, 135, -5, -1, 148, -1, 119, 118, 178,
162 -11, -3, -1, 27, 177, -3, -1, 11, 176, -1, 150, 74, -7, -3, -1,
163 58, 163, -1, 89, 149, -1, 42, 162, -47, -23, -9, -3, -1, 26, 161,
164 -3, -1, 10, 104, 160, -5, -3, -1, 134, 73, 147, -3, -1, 57, 88,
165 -1, 133, 103, -9, -3, -1, 41, 146, -3, -1, 87, 117, 56, -5, -1,
166 131, -1, 102, 71, -3, -1, 116, 86, -1, 101, 115, -11, -3, -1, 25,
167 145, -3, -1, 9, 144, -1, 72, 132, -7, -5, -1, 114, -1, 70, 100,
168 40, -1, 130, 24, -41, -27, -11, -5, -3, -1, 55, 39, 23, -1, 113,
169 -1, 85, 7, -7, -3, -1, 112, 54, -1, 99, 69, -3, -1, 84, 38,
170 -1, 98, 53, -5, -1, 129, -1, 8, 128, -3, -1, 22, 97, -1, 6,
171 96, -13, -9, -5, -3, -1, 83, 68, 37, -1, 82, 5, -1, 21, 81,
172 -7, -3, -1, 52, 67, -1, 80, 36, -3, -1, 66, 51, 20, -19, -11,
173 -5, -1, 65, -1, 4, 64, -3, -1, 35, 50, 19, -3, -1, 49, 3,
174 -1, 48, 34, -3, -1, 18, 33, -1, 2, 32, -3, -1, 17, 1, 16,
175 0
176};
177
178static short mpeg3_tab15[] =
179{
180-495,-445,-355,-263,-183,-115, -77, -43, -27, -13, -7, -3, -1, 255, 239,
181 -1, 254, 223, -1, 238, -1, 253, 207, -7, -3, -1, 252, 222, -1, 237,
182 191, -1, 251, -1, 206, 236, -7, -3, -1, 221, 175, -1, 250, 190, -3,
183 -1, 235, 205, -1, 220, 159, -15, -7, -3, -1, 249, 234, -1, 189, 219,
184 -3, -1, 143, 248, -1, 204, 158, -7, -3, -1, 233, 127, -1, 247, 173,
185 -3, -1, 218, 188, -1, 111, -1, 174, 15, -19, -11, -3, -1, 203, 246,
186 -3, -1, 142, 232, -1, 95, 157, -3, -1, 245, 126, -1, 231, 172, -9,
187 -3, -1, 202, 187, -3, -1, 217, 141, 79, -3, -1, 244, 63, -1, 243,
188 216, -33, -17, -9, -3, -1, 230, 47, -1, 242, -1, 110, 240, -3, -1,
189 31, 241, -1, 156, 201, -7, -3, -1, 94, 171, -1, 186, 229, -3, -1,
190 125, 215, -1, 78, 228, -15, -7, -3, -1, 140, 200, -1, 62, 109, -3,
191 -1, 214, 227, -1, 155, 185, -7, -3, -1, 46, 170, -1, 226, 30, -5,
192 -1, 225, -1, 14, 224, -1, 93, 213, -45, -25, -13, -7, -3, -1, 124,
193 199, -1, 77, 139, -1, 212, -1, 184, 154, -7, -3, -1, 169, 108, -1,
194 198, 61, -1, 211, 210, -9, -5, -3, -1, 45, 13, 29, -1, 123, 183,
195 -5, -1, 209, -1, 92, 208, -1, 197, 138, -17, -7, -3, -1, 168, 76,
196 -1, 196, 107, -5, -1, 182, -1, 153, 12, -1, 60, 195, -9, -3, -1,
197 122, 167, -1, 166, -1, 192, 11, -1, 194, -1, 44, 91, -55, -29, -15,
198 -7, -3, -1, 181, 28, -1, 137, 152, -3, -1, 193, 75, -1, 180, 106,
199 -5, -3, -1, 59, 121, 179, -3, -1, 151, 136, -1, 43, 90, -11, -5,
200 -1, 178, -1, 165, 27, -1, 177, -1, 176, 105, -7, -3, -1, 150, 74,
201 -1, 164, 120, -3, -1, 135, 58, 163, -17, -7, -3, -1, 89, 149, -1,
202 42, 162, -3, -1, 26, 161, -3, -1, 10, 160, 104, -7, -3, -1, 134,
203 73, -1, 148, 57, -5, -1, 147, -1, 119, 9, -1, 88, 133, -53, -29,
204 -13, -7, -3, -1, 41, 103, -1, 118, 146, -1, 145, -1, 25, 144, -7,
205 -3, -1, 72, 132, -1, 87, 117, -3, -1, 56, 131, -1, 102, 71, -7,
206 -3, -1, 40, 130, -1, 24, 129, -7, -3, -1, 116, 8, -1, 128, 86,
207 -3, -1, 101, 55, -1, 115, 70, -17, -7, -3, -1, 39, 114, -1, 100,
208 23, -3, -1, 85, 113, -3, -1, 7, 112, 54, -7, -3, -1, 99, 69,
209 -1, 84, 38, -3, -1, 98, 22, -3, -1, 6, 96, 53, -33, -19, -9,
210 -5, -1, 97, -1, 83, 68, -1, 37, 82, -3, -1, 21, 81, -3, -1,
211 5, 80, 52, -7, -3, -1, 67, 36, -1, 66, 51, -1, 65, -1, 20,
212 4, -9, -3, -1, 35, 50, -3, -1, 64, 3, 19, -3, -1, 49, 48,
213 34, -9, -7, -3, -1, 18, 33, -1, 2, 32, 17, -3, -1, 1, 16,
214 0
215};
216
217static short mpeg3_tab16[] =
218{
219-509,-503,-461,-323,-103, -37, -27, -15, -7, -3, -1, 239, 254, -1, 223,
220 253, -3, -1, 207, 252, -1, 191, 251, -5, -1, 175, -1, 250, 159, -3,
221 -1, 249, 248, 143, -7, -3, -1, 127, 247, -1, 111, 246, 255, -9, -5,
222 -3, -1, 95, 245, 79, -1, 244, 243, -53, -1, 240, -1, 63, -29, -19,
223 -13, -7, -5, -1, 206, -1, 236, 221, 222, -1, 233, -1, 234, 217, -1,
224 238, -1, 237, 235, -3, -1, 190, 205, -3, -1, 220, 219, 174, -11, -5,
225 -1, 204, -1, 173, 218, -3, -1, 126, 172, 202, -5, -3, -1, 201, 125,
226 94, 189, 242, -93, -5, -3, -1, 47, 15, 31, -1, 241, -49, -25, -13,
227 -5, -1, 158, -1, 188, 203, -3, -1, 142, 232, -1, 157, 231, -7, -3,
228 -1, 187, 141, -1, 216, 110, -1, 230, 156, -13, -7, -3, -1, 171, 186,
229 -1, 229, 215, -1, 78, -1, 228, 140, -3, -1, 200, 62, -1, 109, -1,
230 214, 155, -19, -11, -5, -3, -1, 185, 170, 225, -1, 212, -1, 184, 169,
231 -5, -1, 123, -1, 183, 208, 227, -7, -3, -1, 14, 224, -1, 93, 213,
232 -3, -1, 124, 199, -1, 77, 139, -75, -45, -27, -13, -7, -3, -1, 154,
233 108, -1, 198, 61, -3, -1, 92, 197, 13, -7, -3, -1, 138, 168, -1,
234 153, 76, -3, -1, 182, 122, 60, -11, -5, -3, -1, 91, 137, 28, -1,
235 192, -1, 152, 121, -1, 226, -1, 46, 30, -15, -7, -3, -1, 211, 45,
236 -1, 210, 209, -5, -1, 59, -1, 151, 136, 29, -7, -3, -1, 196, 107,
237 -1, 195, 167, -1, 44, -1, 194, 181, -23, -13, -7, -3, -1, 193, 12,
238 -1, 75, 180, -3, -1, 106, 166, 179, -5, -3, -1, 90, 165, 43, -1,
239 178, 27, -13, -5, -1, 177, -1, 11, 176, -3, -1, 105, 150, -1, 74,
240 164, -5, -3, -1, 120, 135, 163, -3, -1, 58, 89, 42, -97, -57, -33,
241 -19, -11, -5, -3, -1, 149, 104, 161, -3, -1, 134, 119, 148, -5, -3,
242 -1, 73, 87, 103, 162, -5, -1, 26, -1, 10, 160, -3, -1, 57, 147,
243 -1, 88, 133, -9, -3, -1, 41, 146, -3, -1, 118, 9, 25, -5, -1,
244 145, -1, 144, 72, -3, -1, 132, 117, -1, 56, 131, -21, -11, -5, -3,
245 -1, 102, 40, 130, -3, -1, 71, 116, 24, -3, -1, 129, 128, -3, -1,
246 8, 86, 55, -9, -5, -1, 115, -1, 101, 70, -1, 39, 114, -5, -3,
247 -1, 100, 85, 7, 23, -23, -13, -5, -1, 113, -1, 112, 54, -3, -1,
248 99, 69, -1, 84, 38, -3, -1, 98, 22, -1, 97, -1, 6, 96, -9,
249 -5, -1, 83, -1, 53, 68, -1, 37, 82, -1, 81, -1, 21, 5, -33,
250 -23, -13, -7, -3, -1, 52, 67, -1, 80, 36, -3, -1, 66, 51, 20,
251 -5, -1, 65, -1, 4, 64, -1, 35, 50, -3, -1, 19, 49, -3, -1,
252 3, 48, 34, -3, -1, 18, 33, -1, 2, 32, -3, -1, 17, 1, 16,
253 0
254};
255
256static short mpeg3_tab24[] =
257{
258-451,-117, -43, -25, -15, -7, -3, -1, 239, 254, -1, 223, 253, -3, -1,
259 207, 252, -1, 191, 251, -5, -1, 250, -1, 175, 159, -1, 249, 248, -9,
260 -5, -3, -1, 143, 127, 247, -1, 111, 246, -3, -1, 95, 245, -1, 79,
261 244, -71, -7, -3, -1, 63, 243, -1, 47, 242, -5, -1, 241, -1, 31,
262 240, -25, -9, -1, 15, -3, -1, 238, 222, -1, 237, 206, -7, -3, -1,
263 236, 221, -1, 190, 235, -3, -1, 205, 220, -1, 174, 234, -15, -7, -3,
264 -1, 189, 219, -1, 204, 158, -3, -1, 233, 173, -1, 218, 188, -7, -3,
265 -1, 203, 142, -1, 232, 157, -3, -1, 217, 126, -1, 231, 172, 255,-235,
266-143, -77, -45, -25, -15, -7, -3, -1, 202, 187, -1, 141, 216, -5, -3,
267 -1, 14, 224, 13, 230, -5, -3, -1, 110, 156, 201, -1, 94, 186, -9,
268 -5, -1, 229, -1, 171, 125, -1, 215, 228, -3, -1, 140, 200, -3, -1,
269 78, 46, 62, -15, -7, -3, -1, 109, 214, -1, 227, 155, -3, -1, 185,
270 170, -1, 226, 30, -7, -3, -1, 225, 93, -1, 213, 124, -3, -1, 199,
271 77, -1, 139, 184, -31, -15, -7, -3, -1, 212, 154, -1, 169, 108, -3,
272 -1, 198, 61, -1, 211, 45, -7, -3, -1, 210, 29, -1, 123, 183, -3,
273 -1, 209, 92, -1, 197, 138, -17, -7, -3, -1, 168, 153, -1, 76, 196,
274 -3, -1, 107, 182, -3, -1, 208, 12, 60, -7, -3, -1, 195, 122, -1,
275 167, 44, -3, -1, 194, 91, -1, 181, 28, -57, -35, -19, -7, -3, -1,
276 137, 152, -1, 193, 75, -5, -3, -1, 192, 11, 59, -3, -1, 176, 10,
277 26, -5, -1, 180, -1, 106, 166, -3, -1, 121, 151, -3, -1, 160, 9,
278 144, -9, -3, -1, 179, 136, -3, -1, 43, 90, 178, -7, -3, -1, 165,
279 27, -1, 177, 105, -1, 150, 164, -17, -9, -5, -3, -1, 74, 120, 135,
280 -1, 58, 163, -3, -1, 89, 149, -1, 42, 162, -7, -3, -1, 161, 104,
281 -1, 134, 119, -3, -1, 73, 148, -1, 57, 147, -63, -31, -15, -7, -3,
282 -1, 88, 133, -1, 41, 103, -3, -1, 118, 146, -1, 25, 145, -7, -3,
283 -1, 72, 132, -1, 87, 117, -3, -1, 56, 131, -1, 102, 40, -17, -7,
284 -3, -1, 130, 24, -1, 71, 116, -5, -1, 129, -1, 8, 128, -1, 86,
285 101, -7, -5, -1, 23, -1, 7, 112, 115, -3, -1, 55, 39, 114, -15,
286 -7, -3, -1, 70, 100, -1, 85, 113, -3, -1, 54, 99, -1, 69, 84,
287 -7, -3, -1, 38, 98, -1, 22, 97, -5, -3, -1, 6, 96, 53, -1,
288 83, 68, -51, -37, -23, -15, -9, -3, -1, 37, 82, -1, 21, -1, 5,
289 80, -1, 81, -1, 52, 67, -3, -1, 36, 66, -1, 51, 20, -9, -5,
290 -1, 65, -1, 4, 64, -1, 35, 50, -1, 19, 49, -7, -5, -3, -1,
291 3, 48, 34, 18, -1, 33, -1, 2, 32, -3, -1, 17, 1, -1, 16,
292 0
293};
294
295static short mpeg3_tab_c0[] =
296{
297 -29, -21, -13, -7, -3, -1, 11, 15, -1, 13, 14, -3, -1, 7, 5,
298 9, -3, -1, 6, 3, -1, 10, 12, -3, -1, 2, 1, -1, 4, 8,
299 0
300};
301
302static short mpeg3_tab_c1[] =
303{
304 -15, -7, -3, -1, 15, 14, -1, 13, 12, -3, -1, 11, 10, -1, 9,
305 8, -7, -3, -1, 7, 6, -1, 5, 4, -3, -1, 3, 2, -1, 1,
306 0
307};
308
309
310
311static struct newhuff mpeg3_ht[] =
312{
313 { /* 0 */ 0 , mpeg3_tab0 } ,
314 { /* 2 */ 0 , mpeg3_tab1 } ,
315 { /* 3 */ 0 , mpeg3_tab2 } ,
316 { /* 3 */ 0 , mpeg3_tab3 } ,
317 { /* 0 */ 0 , mpeg3_tab0 } ,
318 { /* 4 */ 0 , mpeg3_tab5 } ,
319 { /* 4 */ 0 , mpeg3_tab6 } ,
320 { /* 6 */ 0 , mpeg3_tab7 } ,
321 { /* 6 */ 0 , mpeg3_tab8 } ,
322 { /* 6 */ 0 , mpeg3_tab9 } ,
323 { /* 8 */ 0 , mpeg3_tab10 } ,
324 { /* 8 */ 0 , mpeg3_tab11 } ,
325 { /* 8 */ 0 , mpeg3_tab12 } ,
326 { /* 16 */ 0 , mpeg3_tab13 } ,
327 { /* 0 */ 0 , mpeg3_tab0 } ,
328 { /* 16 */ 0 , mpeg3_tab15 } ,
329
330 { /* 16 */ 1 , mpeg3_tab16 } ,
331 { /* 16 */ 2 , mpeg3_tab16 } ,
332 { /* 16 */ 3 , mpeg3_tab16 } ,
333 { /* 16 */ 4 , mpeg3_tab16 } ,
334 { /* 16 */ 6 , mpeg3_tab16 } ,
335 { /* 16 */ 8 , mpeg3_tab16 } ,
336 { /* 16 */ 10, mpeg3_tab16 } ,
337 { /* 16 */ 13, mpeg3_tab16 } ,
338 { /* 16 */ 4 , mpeg3_tab24 } ,
339 { /* 16 */ 5 , mpeg3_tab24 } ,
340 { /* 16 */ 6 , mpeg3_tab24 } ,
341 { /* 16 */ 7 , mpeg3_tab24 } ,
342 { /* 16 */ 8 , mpeg3_tab24 } ,
343 { /* 16 */ 9 , mpeg3_tab24 } ,
344 { /* 16 */ 11, mpeg3_tab24 } ,
345 { /* 16 */ 13, mpeg3_tab24 }
346};
347
348static struct newhuff mpeg3_htc[] =
349{
350 { /* 1 , 1 , */ 0 , mpeg3_tab_c0 } ,
351 { /* 1 , 1 , */ 0 , mpeg3_tab_c1 }
352};
353
354
355#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 @@
1#include "mpeg3audio.h"
2
3int mpeg3audio_dolayer1(mpeg3audio_t *audio)
4{
5 ;
6}
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 @@
1/*
2 * most other tables are calculated on program start (which is (of course)
3 * not ISO-conform) ..
4 * Layer-3 huffman table is in huffman.h
5 */
6
7#include "mpeg3audio.h"
8#include "../libmpeg3.h"
9#include "../mpeg3protos.h"
10#include "tables.h"
11
12struct al_table alloc_0[] = {
13 {4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511},
14 {11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767},
15 {4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511},
16 {11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767},
17 {4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511},
18 {11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767},
19 {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
20 {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
21 {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
22 {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
23 {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
24 {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
25 {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
26 {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
27 {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
28 {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
29 {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
30 {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
31 {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
32 {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
33 {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
34 {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
35 {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
36 {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
37 {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
38 {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
39 {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
40 {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
41 {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
42 {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
43 {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
44 {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
45 {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
46 {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
47 {2,0},{5,3},{7,5},{16,-32767},
48 {2,0},{5,3},{7,5},{16,-32767},
49 {2,0},{5,3},{7,5},{16,-32767},
50 {2,0},{5,3},{7,5},{16,-32767} };
51
52struct al_table alloc_1[] = {
53 {4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511},
54 {11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767},
55 {4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511},
56 {11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767},
57 {4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511},
58 {11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767},
59 {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
60 {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
61 {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
62 {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
63 {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
64 {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
65 {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
66 {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
67 {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
68 {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
69 {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
70 {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
71 {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
72 {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
73 {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
74 {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
75 {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
76 {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
77 {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
78 {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
79 {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
80 {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
81 {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
82 {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
83 {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
84 {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
85 {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
86 {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
87 {2,0},{5,3},{7,5},{16,-32767},
88 {2,0},{5,3},{7,5},{16,-32767},
89 {2,0},{5,3},{7,5},{16,-32767},
90 {2,0},{5,3},{7,5},{16,-32767},
91 {2,0},{5,3},{7,5},{16,-32767},
92 {2,0},{5,3},{7,5},{16,-32767},
93 {2,0},{5,3},{7,5},{16,-32767} };
94
95struct al_table alloc_2[] = {
96 {4,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},
97 {10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},
98 {4,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},
99 {10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},
100 {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
101 {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
102 {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
103 {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
104 {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
105 {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63} };
106
107struct al_table alloc_3[] = {
108 {4,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},
109 {10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},
110 {4,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},
111 {10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},
112 {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
113 {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
114 {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
115 {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
116 {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
117 {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
118 {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
119 {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
120 {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
121 {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63} };
122
123struct al_table alloc_4[] = {
124 {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
125 {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},
126 {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
127 {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},
128 {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
129 {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},
130 {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
131 {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},
132 {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
133 {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
134 {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
135 {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
136 {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
137 {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
138 {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
139 {2,0},{5,3},{7,5},{10,9},
140 {2,0},{5,3},{7,5},{10,9},
141 {2,0},{5,3},{7,5},{10,9},
142 {2,0},{5,3},{7,5},{10,9},
143 {2,0},{5,3},{7,5},{10,9},
144 {2,0},{5,3},{7,5},{10,9},
145 {2,0},{5,3},{7,5},{10,9},
146 {2,0},{5,3},{7,5},{10,9},
147 {2,0},{5,3},{7,5},{10,9},
148 {2,0},{5,3},{7,5},{10,9},
149 {2,0},{5,3},{7,5},{10,9},
150 {2,0},{5,3},{7,5},{10,9},
151 {2,0},{5,3},{7,5},{10,9},
152 {2,0},{5,3},{7,5},{10,9},
153 {2,0},{5,3},{7,5},{10,9},
154 {2,0},{5,3},{7,5},{10,9},
155 {2,0},{5,3},{7,5},{10,9},
156 {2,0},{5,3},{7,5},{10,9},
157 {2,0},{5,3},{7,5},{10,9} };
158
159
160int mpeg3audio_II_select_table(mpeg3audio_t *audio)
161{
162 static int translate[3][2][16] =
163 {{{ 0,2,2,2,2,2,2,0,0,0,1,1,1,1,1,0},
164 { 0,2,2,0,0,0,1,1,1,1,1,1,1,1,1,0}},
165 {{ 0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0},
166 { 0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0}},
167 {{ 0,3,3,3,3,3,3,0,0,0,1,1,1,1,1,0},
168 { 0,3,3,0,0,0,1,1,1,1,1,1,1,1,1,0}}};
169 int table, sblim;
170 static struct al_table *tables[5] =
171 {alloc_0, alloc_1, alloc_2, alloc_3, alloc_4};
172 static int sblims[5] = {27, 30, 8, 12, 30};
173
174 if(audio->lsf)
175 table = 4;
176 else
177 table = translate[audio->sampling_frequency_code][2 - audio->channels][audio->bitrate_index];
178 sblim = sblims[table];
179
180 audio->alloc = tables[table];
181 audio->II_sblimit = sblim;
182 return 0;
183}
184
185int mpeg3audio_II_step_one(mpeg3audio_t *audio, unsigned int *bit_alloc, int *scale)
186{
187 int stereo = audio->channels - 1;
188 int sblimit = audio->II_sblimit;
189 int jsbound = audio->jsbound;
190 int sblimit2 = audio->II_sblimit << stereo;
191 struct al_table *alloc1 = audio->alloc;
192 int i, result = 0;
193 unsigned int *scfsi_buf = audio->layer2_scfsi_buf;
194 unsigned int *scfsi, *bita;
195 int sc, step;
196
197 bita = bit_alloc;
198 if(stereo)
199 {
200/* Stereo */
201 for(i = jsbound;i ; i--, alloc1 += (1 << step))
202 {
203 *bita++ = (char)mpeg3bits_getbits(audio->astream, step = alloc1->bits);
204 *bita++ = (char)mpeg3bits_getbits(audio->astream, step);
205 }
206 for(i = sblimit-jsbound; i; i--, alloc1 += (1 << step))
207 {
208 bita[0] = (char)mpeg3bits_getbits(audio->astream, step = alloc1->bits);
209 bita[1] = bita[0];
210 bita += 2;
211 }
212 bita = bit_alloc;
213 scfsi = scfsi_buf;
214 for(i = sblimit2; i; i--)
215 if(*bita++) *scfsi++ = (char)mpeg3bits_getbits(audio->astream, 2);
216 }
217 else
218 {
219/* mono */
220 for(i = sblimit; i; i--, alloc1 += (1 << step))
221 *bita++ = (char)mpeg3bits_getbits(audio->astream, step = alloc1->bits);
222 bita = bit_alloc;
223 scfsi = scfsi_buf;
224 for(i = sblimit; i; i--) if (*bita++) *scfsi++ = (char)mpeg3bits_getbits(audio->astream, 2);
225 }
226
227 bita = bit_alloc;
228 scfsi = scfsi_buf;
229 for(i = sblimit2; i; i--)
230 {
231 if(*bita++)
232 switch(*scfsi++)
233 {
234 case 0:
235 *scale++ = mpeg3bits_getbits(audio->astream, 6);
236 *scale++ = mpeg3bits_getbits(audio->astream, 6);
237 *scale++ = mpeg3bits_getbits(audio->astream, 6);
238 break;
239 case 1 :
240 *scale++ = sc = mpeg3bits_getbits(audio->astream, 6);
241 *scale++ = sc;
242 *scale++ = mpeg3bits_getbits(audio->astream, 6);
243 break;
244 case 2:
245 *scale++ = sc = mpeg3bits_getbits(audio->astream, 6);
246 *scale++ = sc;
247 *scale++ = sc;
248 break;
249 default: /* case 3 */
250 *scale++ = mpeg3bits_getbits(audio->astream, 6);
251 *scale++ = sc = mpeg3bits_getbits(audio->astream, 6);
252 *scale++ = sc;
253 break;
254 }
255 }
256 return result | mpeg3bits_error(audio->astream);
257}
258
259int mpeg3audio_II_step_two(mpeg3audio_t *audio, unsigned int *bit_alloc, mpeg3_real_t fraction[2][4][SBLIMIT], int *scale, int x1)
260{
261 int i, j, k, ba, result = 0;
262 int channels = audio->channels;
263 int sblimit = audio->II_sblimit;
264 int jsbound = audio->jsbound;
265 struct al_table *alloc2, *alloc1 = audio->alloc;
266 unsigned int *bita = bit_alloc;
267 int d1, step, test;
268
269 for(i = 0; i < jsbound; i++, alloc1 += (1 << step))
270 {
271 step = alloc1->bits;
272 for(j = 0; j < channels; j++)
273 {
274 if(ba = *bita++)
275 {
276 k = (alloc2 = alloc1 + ba)->bits;
277 if((d1 = alloc2->d) < 0)
278 {
279 mpeg3_real_t cm = mpeg3_muls[k][scale[x1]];
280
281 fraction[j][0][i] = ((mpeg3_real_t)((int)mpeg3bits_getbits(audio->astream, k) + d1)) * cm;
282 fraction[j][1][i] = ((mpeg3_real_t)((int)mpeg3bits_getbits(audio->astream, k) + d1)) * cm;
283 fraction[j][2][i] = ((mpeg3_real_t)((int)mpeg3bits_getbits(audio->astream, k) + d1)) * cm;
284 }
285 else
286 {
287 static int *table[] =
288 {0, 0, 0, mpeg3_grp_3tab, 0, mpeg3_grp_5tab, 0, 0, 0, mpeg3_grp_9tab};
289 unsigned int idx, *tab, m = scale[x1];
290
291 idx = (unsigned int)mpeg3bits_getbits(audio->astream, k);
292 tab = (unsigned int*)(table[d1] + idx + idx + idx);
293 fraction[j][0][i] = mpeg3_muls[*tab++][m];
294 fraction[j][1][i] = mpeg3_muls[*tab++][m];
295 fraction[j][2][i] = mpeg3_muls[*tab][m];
296 }
297 scale += 3;
298 }
299 else
300 fraction[j][0][i] = fraction[j][1][i] = fraction[j][2][i] = 0.0;
301 }
302 }
303
304 for(i = jsbound; i < sblimit; i++, alloc1 += (1 << step))
305 {
306 step = alloc1->bits;
307/* channel 1 and channel 2 bitalloc are the same */
308 bita++;
309 if((ba = *bita++))
310 {
311 k=(alloc2 = alloc1+ba)->bits;
312 if((d1 = alloc2->d) < 0)
313 {
314 mpeg3_real_t cm;
315
316 cm = mpeg3_muls[k][scale[x1 + 3]];
317 fraction[1][0][i] = (fraction[0][0][i] = (mpeg3_real_t)((int)mpeg3bits_getbits(audio->astream, k) + d1)) * cm;
318 fraction[1][1][i] = (fraction[0][1][i] = (mpeg3_real_t)((int)mpeg3bits_getbits(audio->astream, k) + d1)) * cm;
319 fraction[1][2][i] = (fraction[0][2][i] = (mpeg3_real_t)((int)mpeg3bits_getbits(audio->astream, k) + d1)) * cm;
320 cm = mpeg3_muls[k][scale[x1]];
321 fraction[0][0][i] *= cm;
322 fraction[0][1][i] *= cm;
323 fraction[0][2][i] *= cm;
324 }
325 else
326 {
327 static int *table[] = {0, 0, 0, mpeg3_grp_3tab, 0, mpeg3_grp_5tab, 0, 0, 0, mpeg3_grp_9tab};
328 unsigned int idx, *tab, m1, m2;
329
330 m1 = scale[x1];
331 m2 = scale[x1+3];
332 idx = (unsigned int)mpeg3bits_getbits(audio->astream, k);
333 tab = (unsigned int*)(table[d1] + idx + idx + idx);
334 fraction[0][0][i] = mpeg3_muls[*tab][m1];
335 fraction[1][0][i] = mpeg3_muls[*tab++][m2];
336 fraction[0][1][i] = mpeg3_muls[*tab][m1];
337 fraction[1][1][i] = mpeg3_muls[*tab++][m2];
338 fraction[0][2][i] = mpeg3_muls[*tab][m1];
339 fraction[1][2][i] = mpeg3_muls[*tab][m2];
340 }
341 scale += 6;
342 }
343 else
344 {
345 fraction[0][0][i] = fraction[0][1][i] = fraction[0][2][i] =
346 fraction[1][0][i] = fraction[1][1][i] = fraction[1][2][i] = 0.0;
347 }
348/*
349 should we use individual scalefac for channel 2 or
350 is the current way the right one , where we just copy channel 1 to
351 channel 2 ??
352 The current 'strange' thing is, that we throw away the scalefac
353 values for the second channel ...!!
354-> changed .. now we use the scalefac values of channel one !!
355*/
356 }
357
358 if(sblimit > SBLIMIT) sblimit = SBLIMIT;
359
360 for(i = sblimit; i < SBLIMIT; i++)
361 for(j = 0; j < channels; j++)
362 fraction[j][0][i] = fraction[j][1][i] = fraction[j][2][i] = 0.0;
363
364 return result | mpeg3bits_error(audio->astream);
365}
366
367int mpeg3audio_dolayer2(mpeg3audio_t *audio)
368{
369 int i, j, result = 0;
370 int channels = audio->channels;
371 mpeg3_real_t fraction[2][4][SBLIMIT]; /* pick_table clears unused subbands */
372 unsigned int bit_alloc[64];
373 int scale[192];
374 int single = audio->single;
375
376 if(audio->error_protection)
377 mpeg3bits_getbits(audio->astream, 16);
378
379 mpeg3audio_II_select_table(audio);
380
381 audio->jsbound = (audio->mode == MPG_MD_JOINT_STEREO) ?
382 (audio->mode_ext << 2) + 4 : audio->II_sblimit;
383
384 if(channels == 1 || single == 3)
385 single = 0;
386
387 result |= mpeg3audio_II_step_one(audio, bit_alloc, scale);
388
389 for(i = 0; i < SCALE_BLOCK && !result; i++)
390 {
391 result |= mpeg3audio_II_step_two(audio, bit_alloc, fraction, scale, i >> 2);
392
393 for(j = 0; j < 3; j++)
394 {
395 if(single >= 0)
396 {
397/* Monaural */
398 mpeg3audio_synth_mono(audio, fraction[single][j], audio->pcm_sample, &(audio->pcm_point));
399 }
400 else
401 {
402/* Stereo */
403 int p1 = audio->pcm_point;
404 mpeg3audio_synth_stereo(audio, fraction[0][j], 0, audio->pcm_sample, &p1);
405 mpeg3audio_synth_stereo(audio, fraction[1][j], 1, audio->pcm_sample, &(audio->pcm_point));
406 }
407
408 if(audio->pcm_point / audio->channels >= audio->pcm_allocated - MPEG3AUDIO_PADDING * audio->channels)
409 {
410/* Need more room */
411 mpeg3audio_replace_buffer(audio, audio->pcm_allocated + MPEG3AUDIO_PADDING * audio->channels);
412 }
413 }
414 }
415
416
417 return result;
418}
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 @@
1#include "huffman.h"
2#include "mpeg3audio.h"
3#include "../libmpeg3.h"
4#include "../mpeg3protos.h"
5#include "tables.h"
6
7#include <stdio.h>
8#include <string.h>
9
10struct gr_info_s {
11 int scfsi;
12 unsigned part2_3_length;
13 unsigned big_values;
14 unsigned scalefac_compress;
15 unsigned block_type;
16 unsigned mixed_block_flag;
17 unsigned table_select[3];
18 unsigned subblock_gain[3];
19 unsigned maxband[3];
20 unsigned maxbandl;
21 unsigned maxb;
22 unsigned region1start;
23 unsigned region2start;
24 unsigned preflag;
25 unsigned scalefac_scale;
26 unsigned count1table_select;
27 mpeg3_real_t *full_gain[3];
28 mpeg3_real_t *pow2gain;
29};
30
31struct mpeg3_III_sideinfo
32{
33 unsigned main_data_begin;
34 unsigned private_bits;
35 struct
36 {
37 struct gr_info_s gr[2];
38 } ch[2];
39};
40
41int mpeg3audio_III_get_scale_factors_1(mpeg3audio_t *audio,
42 int *scf,
43 struct gr_info_s *gr_info,
44 int ch,
45 int gr)
46{
47 static unsigned char slen[2][16] =
48 {{0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4},
49 {0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3}};
50 int numbits;
51 int num0 = slen[0][gr_info->scalefac_compress];
52 int num1 = slen[1][gr_info->scalefac_compress];
53
54 if (gr_info->block_type == 2)
55 {
56 int i = 18;
57 numbits = (num0 + num1) * 18;
58
59 if (gr_info->mixed_block_flag)
60 {
61 for(i = 8; i; i--)
62 *scf++ = mpeg3bits_getbits(audio->astream, num0);
63 i = 9;
64/* num0 * 17 + num1 * 18 */
65 numbits -= num0;
66 }
67
68 for( ; i; i--)
69 *scf++ = mpeg3bits_getbits(audio->astream, num0);
70 for(i = 18; i; i--)
71 *scf++ = mpeg3bits_getbits(audio->astream, num1);
72/* short[13][0..2] = 0 */
73 *scf++ = 0;
74 *scf++ = 0;
75 *scf++ = 0;
76 }
77 else
78 {
79 int i;
80 int scfsi = gr_info->scfsi;
81
82 if(scfsi < 0)
83 {
84/* scfsi < 0 => granule == 0 */
85 for(i = 11; i; i--)
86 {
87 *scf++ = mpeg3bits_getbits(audio->astream, num0);
88 }
89 for(i = 10; i; i--)
90 *scf++ = mpeg3bits_getbits(audio->astream, num1);
91 numbits = (num0 + num1) * 10 + num0;
92 *scf++ = 0;
93 }
94 else
95 {
96 numbits = 0;
97 if(!(scfsi & 0x8))
98 {
99 for(i = 0; i < 6; i++)
100 {
101 *scf++ = mpeg3bits_getbits(audio->astream, num0);
102 }
103 numbits += num0 * 6;
104 }
105 else
106 {
107 scf += 6;
108 }
109
110 if(!(scfsi & 0x4))
111 {
112 for(i = 0; i < 5; i++)
113 *scf++ = mpeg3bits_getbits(audio->astream, num0);
114 numbits += num0 * 5;
115 }
116 else
117 {
118 scf += 5;
119 }
120
121 if(!(scfsi & 0x2))
122 {
123 for(i = 0; i < 5; i++)
124 *scf++ = mpeg3bits_getbits(audio->astream, num1);
125 numbits += num1 * 5;
126 }
127 else
128 {
129 scf += 5;
130 }
131
132 if(!(scfsi & 0x1))
133 {
134 for(i = 0; i < 5; i++)
135 *scf++ = mpeg3bits_getbits(audio->astream, num1);
136 numbits += num1 * 5;
137 }
138 else
139 {
140 scf += 5;
141 }
142 *scf++ = 0; /* no l[21] in original sources */
143 }
144 }
145 return numbits;
146}
147
148int mpeg3audio_III_get_scale_factors_2(mpeg3audio_t *audio,
149 int *scf,
150 struct gr_info_s *gr_info,
151 int i_stereo)
152{
153 unsigned char *pnt;
154 int i, j, n = 0, numbits = 0;
155 unsigned int slen;
156 static unsigned char stab[3][6][4] =
157 {{{ 6, 5, 5,5 }, { 6, 5, 7,3 }, { 11,10,0,0},
158 { 7, 7, 7,0 }, { 6, 6, 6,3 }, { 8, 8,5,0}},
159 {{ 9, 9, 9,9 }, { 9, 9,12,6 }, { 18,18,0,0},
160 {12,12,12,0 }, {12, 9, 9,6 }, { 15,12,9,0}},
161 {{ 6, 9, 9,9 }, { 6, 9,12,6 }, { 15,18,0,0},
162 { 6,15,12,0 }, { 6,12, 9,6 }, { 6,18,9,0}}};
163
164/* i_stereo AND second channel -> do_layer3() checks this */
165 if(i_stereo)
166 slen = mpeg3_i_slen2[gr_info->scalefac_compress >> 1];
167 else
168 slen = mpeg3_n_slen2[gr_info->scalefac_compress];
169
170 gr_info->preflag = (slen >> 15) & 0x1;
171
172 n = 0;
173 if(gr_info->block_type == 2 )
174 {
175 n++;
176 if(gr_info->mixed_block_flag)
177 n++;
178 }
179
180 pnt = stab[n][(slen >> 12) & 0x7];
181
182 for(i = 0; i < 4; i++)
183 {
184 int num = slen & 0x7;
185 slen >>= 3;
186 if(num)
187 {
188 for(j = 0; j < (int)(pnt[i]); j++)
189 *scf++ = mpeg3bits_getbits(audio->astream, num);
190 numbits += pnt[i] * num;
191 }
192 else
193 {
194 for(j = 0; j < (int)(pnt[i]); j++)
195 *scf++ = 0;
196 }
197 }
198
199 n = (n << 1) + 1;
200 for(i = 0; i < n; i++)
201 *scf++ = 0;
202
203 return numbits;
204}
205
206static 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};
207static 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};
208
209/*
210 * Dequantize samples (includes huffman decoding)
211 *
212 * 24 is enough because tab13 has max. a 19 bit huffvector
213 */
214
215#define BITSHIFT ((sizeof(long) - 1) * 8)
216#define REFRESH_MASK \
217 while(num < BITSHIFT) \
218 { \
219 mask |= mpeg3bits_getbits(audio->astream, 8) << (BITSHIFT - num); \
220 num += 8; \
221 part2remain -= 8; \
222 }
223
224int mpeg3audio_III_dequantize_sample(mpeg3audio_t *audio,
225 mpeg3_real_t xr[SBLIMIT][SSLIMIT],
226 int *scf,
227 struct gr_info_s *gr_info,
228 int sfreq,
229 int part2bits)
230{
231 int shift = 1 + gr_info->scalefac_scale;
232 mpeg3_real_t *xrpnt = (mpeg3_real_t*)xr;
233 int l[3],l3;
234 int part2remain = gr_info->part2_3_length - part2bits;
235 int *me;
236 int num = mpeg3bits_getbitoffset(audio->astream);
237 long mask = mpeg3bits_getbits(audio->astream, num);
238//printf("III_dequantize_sample 1 %08x %d\n", mask, num);
239 mask = mask << (BITSHIFT + 8 - num);
240 part2remain -= num;
241
242 {
243 int bv = gr_info->big_values;
244 int region1 = gr_info->region1start;
245 int region2 = gr_info->region2start;
246
247 l3 = ((576 >> 1) - bv) >> 1;
248
249/*
250 * we may lose the 'odd' bit here !!
251 * check this later again
252 */
253
254 if(bv <= region1)
255 {
256 l[0] = bv;
257 l[1] = 0;
258 l[2] = 0;
259 }
260 else
261 {
262 l[0] = region1;
263 if(bv <= region2)
264 {
265 l[1] = bv - l[0]; l[2] = 0;
266 }
267 else
268 {
269 l[1] = region2 - l[0];
270 l[2] = bv - region2;
271 }
272 }
273 }
274
275 if(gr_info->block_type == 2)
276 {
277/*
278 * decoding with short or mixed mode BandIndex table
279 */
280 int i, max[4];
281 int step = 0, lwin = 3, cb = 0;
282 register mpeg3_real_t v = 0.0;
283 register int *m, mc;
284
285 if(gr_info->mixed_block_flag)
286 {
287 max[3] = -1;
288 max[0] = max[1] = max[2] = 2;
289 m = mpeg3_map[sfreq][0];
290 me = mpeg3_mapend[sfreq][0];
291 }
292 else
293 {
294 max[0] = max[1] = max[2] = max[3] = -1;
295/* max[3] not floatly needed in this case */
296 m = mpeg3_map[sfreq][1];
297 me = mpeg3_mapend[sfreq][1];
298 }
299
300 mc = 0;
301 for(i = 0; i < 2; i++)
302 {
303 int lp = l[i];
304 struct newhuff *h = mpeg3_ht + gr_info->table_select[i];
305 for( ; lp; lp--, mc--)
306 {
307 register int x,y;
308 if(!mc)
309 {
310 mc = *m++;
311 xrpnt = ((mpeg3_real_t*)xr) + (*m++);
312 lwin = *m++;
313 cb = *m++;
314 if(lwin == 3)
315 {
316 v = gr_info->pow2gain[(*scf++) << shift];
317 step = 1;
318 }
319 else
320 {
321 v = gr_info->full_gain[lwin][(*scf++) << shift];
322 step = 3;
323 }
324 }
325
326 {
327 register short *val = h->table;
328 REFRESH_MASK;
329 while((y = *val++) < 0)
330 {
331 if (mask < 0)
332 val -= y;
333 num--;
334 mask <<= 1;
335 }
336 x = y >> 4;
337 y &= 0xf;
338 }
339
340 if(x == 15 && h->linbits)
341 {
342 max[lwin] = cb;
343 REFRESH_MASK;
344 x += ((unsigned long)mask) >> (BITSHIFT + 8 - h->linbits);
345 num -= h->linbits + 1;
346 mask <<= h->linbits;
347 if(mask < 0)
348 *xrpnt = -mpeg3_ispow[x] * v;
349 else
350 *xrpnt = mpeg3_ispow[x] * v;
351 mask <<= 1;
352 }
353 else
354 if(x)
355 {
356 max[lwin] = cb;
357 if(mask < 0)
358 *xrpnt = -mpeg3_ispow[x] * v;
359 else
360 *xrpnt = mpeg3_ispow[x] * v;
361 num--;
362 mask <<= 1;
363 }
364 else
365 *xrpnt = 0.0;
366
367 xrpnt += step;
368 if(y == 15 && h->linbits)
369 {
370 max[lwin] = cb;
371 REFRESH_MASK;
372 y += ((unsigned long) mask) >> (BITSHIFT + 8 - h->linbits);
373 num -= h->linbits + 1;
374 mask <<= h->linbits;
375 if(mask < 0)
376 *xrpnt = -mpeg3_ispow[y] * v;
377 else
378 *xrpnt = mpeg3_ispow[y] * v;
379 mask <<= 1;
380 }
381 else
382 if(y)
383 {
384 max[lwin] = cb;
385 if(mask < 0)
386 *xrpnt = -mpeg3_ispow[y] * v;
387 else
388 *xrpnt = mpeg3_ispow[y] * v;
389 num--;
390 mask <<= 1;
391 }
392 else
393 *xrpnt = 0.0;
394 xrpnt += step;
395 }
396 }
397
398 for( ;l3 && (part2remain + num > 0); l3--)
399 {
400 struct newhuff *h = mpeg3_htc + gr_info->count1table_select;
401 register short *val = h->table, a;
402
403 REFRESH_MASK;
404 while((a = *val++) < 0)
405 {
406 if (mask < 0)
407 val -= a;
408 num--;
409 mask <<= 1;
410 }
411 if(part2remain + num <= 0)
412 {
413 num -= part2remain + num;
414 break;
415 }
416
417 for(i = 0; i < 4; i++)
418 {
419 if(!(i & 1))
420 {
421 if(!mc)
422 {
423 mc = *m++;
424 xrpnt = ((mpeg3_real_t*)xr) + (*m++);
425 lwin = *m++;
426 cb = *m++;
427 if(lwin == 3)
428 {
429 v = gr_info->pow2gain[(*scf++) << shift];
430 step = 1;
431 }
432 else
433 {
434 v = gr_info->full_gain[lwin][(*scf++) << shift];
435 step = 3;
436 }
437 }
438 mc--;
439 }
440 if((a & (0x8 >> i)))
441 {
442 max[lwin] = cb;
443 if(part2remain + num <= 0)
444 {
445 break;
446 }
447 if(mask < 0)
448 *xrpnt = -v;
449 else
450 *xrpnt = v;
451 num--;
452 mask <<= 1;
453 }
454 else
455 *xrpnt = 0.0;
456 xrpnt += step;
457 }
458 }
459
460 if(lwin < 3)
461 {
462/* short band? */
463 while(1)
464 {
465 for( ;mc > 0; mc--)
466 {
467/* short band -> step=3 */
468 *xrpnt = 0.0;
469 xrpnt += 3;
470 *xrpnt = 0.0;
471 xrpnt += 3;
472 }
473 if(m >= me)
474 break;
475 mc = *m++;
476 xrpnt = ((mpeg3_real_t*)xr) + *m++;
477/* optimize: field will be set to zero at the end of the function */
478 if(*m++ == 0)
479 break;
480/* cb */
481 m++;
482 }
483 }
484
485 gr_info->maxband[0] = max[0] + 1;
486 gr_info->maxband[1] = max[1] + 1;
487 gr_info->maxband[2] = max[2] + 1;
488 gr_info->maxbandl = max[3] + 1;
489
490 {
491 int rmax = max[0] > max[1] ? max[0] : max[1];
492 rmax = (rmax > max[2] ? rmax : max[2]) + 1;
493 gr_info->maxb = rmax ? mpeg3_shortLimit[sfreq][rmax] : mpeg3_longLimit[sfreq][max[3] + 1];
494 }
495
496 }
497 else
498 {
499/*
500 * decoding with 'long' BandIndex table (block_type != 2)
501 */
502 int *pretab = gr_info->preflag ? pretab1 : pretab2;
503 int i, max = -1;
504 int cb = 0;
505 int *m = mpeg3_map[sfreq][2];
506 register mpeg3_real_t v = 0.0;
507 int mc = 0;
508
509/*
510 * long hash table values
511 */
512 for(i = 0; i < 3; i++)
513 {
514 int lp = l[i];
515 struct newhuff *h = mpeg3_ht + gr_info->table_select[i];
516
517 for(; lp; lp--, mc--)
518 {
519 int x, y;
520
521 if(!mc)
522 {
523 mc = *m++;
524 cb = *m++;
525 if(cb == 21)
526 v = 0.0;
527 else
528 v = gr_info->pow2gain[((*scf++) + (*pretab++)) << shift];
529 }
530 {
531 register short *val = h->table;
532 REFRESH_MASK;
533 while((y = *val++) < 0)
534 {
535 if(mask < 0)
536 val -= y;
537 num--;
538 mask <<= 1;
539 }
540 x = y >> 4;
541 y &= 0xf;
542 }
543
544 if(x == 15 && h->linbits)
545 {
546 max = cb;
547 REFRESH_MASK;
548 x += ((unsigned long) mask) >> (BITSHIFT + 8 - h->linbits);
549 num -= h->linbits + 1;
550 mask <<= h->linbits;
551 if(mask < 0)
552 *xrpnt++ = -mpeg3_ispow[x] * v;
553 else
554 *xrpnt++ = mpeg3_ispow[x] * v;
555 mask <<= 1;
556 }
557 else
558 if(x)
559 {
560 max = cb;
561 if(mask < 0)
562 *xrpnt++ = -mpeg3_ispow[x] * v;
563 else
564 *xrpnt++ = mpeg3_ispow[x] * v;
565 num--;
566 mask <<= 1;
567 }
568 else
569 *xrpnt++ = 0.0;
570
571 if(y == 15 && h->linbits)
572 {
573 max = cb;
574 REFRESH_MASK;
575 y += ((unsigned long) mask) >> (BITSHIFT + 8 - h->linbits);
576 num -= h->linbits + 1;
577 mask <<= h->linbits;
578 if(mask < 0)
579 *xrpnt++ = -mpeg3_ispow[y] * v;
580 else
581 *xrpnt++ = mpeg3_ispow[y] * v;
582 mask <<= 1;
583 }
584 else
585 if(y)
586 {
587 max = cb;
588 if(mask < 0)
589 *xrpnt++ = -mpeg3_ispow[y] * v;
590 else
591 *xrpnt++ = mpeg3_ispow[y] * v;
592 num--;
593 mask <<= 1;
594 }
595 else
596 *xrpnt++ = 0.0;
597 }
598 }
599
600/*
601 * short (count1table) values
602 */
603 for( ; l3 && (part2remain + num > 0); l3--)
604 {
605 struct newhuff *h = mpeg3_htc + gr_info->count1table_select;
606 register short *val = h->table, a;
607
608 REFRESH_MASK;
609 while((a = *val++) < 0)
610 {
611 if(mask < 0)
612 val -= a;
613 num--;
614 mask <<= 1;
615 }
616 if(part2remain + num <= 0)
617 {
618 num -= part2remain + num;
619 break;
620 }
621
622 for(i = 0; i < 4; i++)
623 {
624 if(!(i & 1))
625 {
626 if(!mc)
627 {
628 mc = *m++;
629 cb = *m++;
630 if(cb == 21)
631 v = 0.0;
632 else
633 v = gr_info->pow2gain[((*scf++) + (*pretab++)) << shift];
634 }
635 mc--;
636 }
637 if((a & (0x8 >> i)))
638 {
639 max = cb;
640 if(part2remain + num <= 0)
641 {
642 break;
643 }
644 if(mask < 0)
645 *xrpnt++ = -v;
646 else
647 *xrpnt++ = v;
648 num--;
649 mask <<= 1;
650 }
651 else
652 *xrpnt++ = 0.0;
653 }
654 }
655
656 gr_info->maxbandl = max + 1;
657 gr_info->maxb = mpeg3_longLimit[sfreq][gr_info->maxbandl];
658 }
659
660 part2remain += num;
661
662//printf("III_dequantize_sample 2 %d %04x\n", num, mpeg3bits_showbits(audio->astream, 16));
663 mpeg3bits_start_reverse(audio->astream);
664 mpeg3bits_getbits_reverse(audio->astream, num);
665 mpeg3bits_start_forward(audio->astream);
666//printf("III_dequantize_sample 3 %d %04x\n", audio->astream->bit_number, mpeg3bits_showbits(audio->astream, 16));
667 num = 0;
668
669 while(xrpnt < &xr[SBLIMIT][0])
670 *xrpnt++ = 0.0;
671
672 while(part2remain > 16)
673 {
674 mpeg3bits_getbits(audio->astream, 16); /* Dismiss stuffing Bits */
675 part2remain -= 16;
676 }
677 if(part2remain > 0)
678 {
679 mpeg3bits_getbits(audio->astream, part2remain);
680 }
681 else
682 if(part2remain < 0)
683 {
684 fprintf(stderr,"mpeg3audio_III_dequantize_sample: Can't rewind stream %d bits!\n", -part2remain);
685 return 1; /* -> error */
686 }
687 return 0;
688}
689
690int mpeg3audio_III_get_side_info(mpeg3audio_t *audio,
691 struct mpeg3_III_sideinfo *si,
692 int channels,
693 int ms_stereo,
694 long sfreq,
695 int single,
696 int lsf)
697{
698 int ch, gr;
699 int powdiff = (single == 3) ? 4 : 0;
700 static const int tabs[2][5] = { { 2,9,5,3,4 } , { 1,8,1,2,9 } };
701 const int *tab = tabs[lsf];
702
703 si->main_data_begin = mpeg3bits_getbits(audio->astream, tab[1]);
704 if(channels == 1)
705 si->private_bits = mpeg3bits_getbits(audio->astream, tab[2]);
706 else
707 si->private_bits = mpeg3bits_getbits(audio->astream, tab[3]);
708 if(!lsf)
709 {
710 for(ch = 0; ch < channels; ch++)
711 {
712 si->ch[ch].gr[0].scfsi = -1;
713 si->ch[ch].gr[1].scfsi = mpeg3bits_getbits(audio->astream, 4);
714 }
715 }
716
717 for(gr = 0; gr < tab[0]; gr++)
718 {
719 for(ch = 0; ch < channels; ch++)
720 {
721 register struct gr_info_s *gr_info = &(si->ch[ch].gr[gr]);
722
723 gr_info->part2_3_length = mpeg3bits_getbits(audio->astream, 12);
724 gr_info->big_values = mpeg3bits_getbits(audio->astream, 9);
725 if(gr_info->big_values > 288)
726 {
727 fprintf(stderr,"mpeg3_III_get_side_info: big_values too large!\n");
728 gr_info->big_values = 288;
729 }
730 gr_info->pow2gain = mpeg3_gainpow2 + 256 - mpeg3bits_getbits(audio->astream, 8) + powdiff;
731 if(ms_stereo)
732 gr_info->pow2gain += 2;
733 gr_info->scalefac_compress = mpeg3bits_getbits(audio->astream, tab[4]);
734
735 if(mpeg3bits_getbits(audio->astream, 1))
736 {
737/* window switch flag */
738 int i;
739 gr_info->block_type = mpeg3bits_getbits(audio->astream, 2);
740 gr_info->mixed_block_flag = mpeg3bits_getbits(audio->astream, 1);
741 gr_info->table_select[0] = mpeg3bits_getbits(audio->astream, 5);
742 gr_info->table_select[1] = mpeg3bits_getbits(audio->astream, 5);
743/*
744 * table_select[2] not needed, because there is no region2,
745 * but to satisfy some verifications tools we set it either.
746 */
747 gr_info->table_select[2] = 0;
748 for(i = 0; i < 3; i++)
749 gr_info->full_gain[i] = gr_info->pow2gain + (mpeg3bits_getbits(audio->astream, 3) << 3);
750
751 if(gr_info->block_type == 0)
752 {
753 fprintf(stderr,"Blocktype == 0 and window-switching == 1 not allowed.\n");
754 return 1;
755 }
756
757/* region_count/start parameters are implicit in this case. */
758 if(!lsf || gr_info->block_type == 2)
759 gr_info->region1start = 36 >> 1;
760 else
761 {
762/* check this again for 2.5 and sfreq=8 */
763 if(sfreq == 8)
764 gr_info->region1start = 108 >> 1;
765 else
766 gr_info->region1start = 54 >> 1;
767 }
768 gr_info->region2start = 576 >> 1;
769 }
770 else
771 {
772 int i, r0c, r1c;
773 for(i = 0; i < 3; i++)
774 gr_info->table_select[i] = mpeg3bits_getbits(audio->astream, 5);
775
776 r0c = mpeg3bits_getbits(audio->astream, 4);
777 r1c = mpeg3bits_getbits(audio->astream, 3);
778 gr_info->region1start = mpeg3_bandInfo[sfreq].longIdx[r0c + 1] >> 1 ;
779 gr_info->region2start = mpeg3_bandInfo[sfreq].longIdx[r0c + 1 + r1c + 1] >> 1;
780 gr_info->block_type = 0;
781 gr_info->mixed_block_flag = 0;
782 }
783 if(!lsf) gr_info->preflag = mpeg3bits_getbits(audio->astream, 1);
784 gr_info->scalefac_scale = mpeg3bits_getbits(audio->astream, 1);
785 gr_info->count1table_select = mpeg3bits_getbits(audio->astream, 1);
786 }
787 }
788 return 0;
789}
790
791int mpeg3audio_III_hybrid(mpeg3audio_t *audio,
792 mpeg3_real_t fsIn[SBLIMIT][SSLIMIT],
793 mpeg3_real_t tsOut[SSLIMIT][SBLIMIT],
794 int ch,
795 struct gr_info_s *gr_info)
796{
797 mpeg3_real_t *tspnt = (mpeg3_real_t *) tsOut;
798 mpeg3_real_t *rawout1,*rawout2;
799 int bt, sb = 0;
800
801
802 {
803 int b = audio->mp3_blc[ch];
804 rawout1 = audio->mp3_block[b][ch];
805 b = -b + 1;
806 rawout2 = audio->mp3_block[b][ch];
807 audio->mp3_blc[ch] = b;
808 }
809
810 if(gr_info->mixed_block_flag)
811 {
812 sb = 2;
813 mpeg3audio_dct36(fsIn[0], rawout1, rawout2, mpeg3_win[0], tspnt);
814 mpeg3audio_dct36(fsIn[1], rawout1 + 18, rawout2 + 18, mpeg3_win1[0], tspnt + 1);
815 rawout1 += 36;
816 rawout2 += 36;
817 tspnt += 2;
818 }
819
820 bt = gr_info->block_type;
821 if(bt == 2)
822 {
823 for( ; sb < gr_info->maxb; sb += 2, tspnt += 2, rawout1 += 36, rawout2 += 36)
824 {
825 mpeg3audio_dct12(fsIn[sb] ,rawout1 ,rawout2 ,mpeg3_win[2] ,tspnt);
826 mpeg3audio_dct12(fsIn[sb + 1], rawout1 + 18, rawout2 + 18, mpeg3_win1[2], tspnt + 1);
827 }
828 }
829 else
830 {
831 for( ; sb < gr_info->maxb; sb += 2, tspnt += 2, rawout1 += 36, rawout2 += 36)
832 {
833 mpeg3audio_dct36(fsIn[sb], rawout1, rawout2, mpeg3_win[bt], tspnt);
834 mpeg3audio_dct36(fsIn[sb + 1], rawout1 + 18, rawout2 + 18, mpeg3_win1[bt], tspnt + 1);
835 }
836 }
837
838 for( ; sb < SBLIMIT; sb++, tspnt++)
839 {
840 int i;
841 for(i = 0; i < SSLIMIT; i++)
842 {
843 tspnt[i * SBLIMIT] = *rawout1++;
844 *rawout2++ = 0.0;
845 }
846 }
847 return 0;
848}
849
850int mpeg3audio_III_antialias(mpeg3audio_t *audio,
851 mpeg3_real_t xr[SBLIMIT][SSLIMIT],
852 struct gr_info_s *gr_info)
853{
854 int sblim;
855
856 if(gr_info->block_type == 2)
857 {
858 if(!gr_info->mixed_block_flag)
859 return 0;
860 sblim = 1;
861 }
862 else
863 {
864 sblim = gr_info->maxb-1;
865 }
866
867/* 31 alias-reduction operations between each pair of sub-bands */
868/* with 8 butterflies between each pair */
869
870 {
871 int sb;
872 mpeg3_real_t *xr1 = (mpeg3_real_t*)xr[1];
873
874 for(sb = sblim; sb; sb--, xr1 += 10)
875 {
876 int ss;
877 mpeg3_real_t *cs, *ca;
878 mpeg3_real_t *xr2;
879 cs = mpeg3_aa_cs;
880 ca = mpeg3_aa_ca;
881 xr2 = xr1;
882
883 for(ss = 7; ss >= 0; ss--)
884 {
885/* upper and lower butterfly inputs */
886 register mpeg3_real_t bu, bd;
887 bu = *--xr2;
888 bd = *xr1;
889 *xr2 = (bu * (*cs) ) - (bd * (*ca) );
890 *xr1++ = (bd * (*cs++) ) + (bu * (*ca++) );
891 }
892 }
893 }
894 return 0;
895}
896
897/*
898 * III_stereo: calculate mpeg3_real_t channel values for Joint-I-Stereo-mode
899 */
900int mpeg3audio_III_i_stereo(mpeg3audio_t *audio,
901 mpeg3_real_t xr_buf[2][SBLIMIT][SSLIMIT],
902 int *scalefac,
903 struct gr_info_s *gr_info,
904 int sfreq,
905 int ms_stereo,
906 int lsf)
907{
908 mpeg3_real_t (*xr)[SBLIMIT*SSLIMIT] = (mpeg3_real_t (*)[SBLIMIT*SSLIMIT] ) xr_buf;
909 struct mpeg3_bandInfoStruct *bi = &mpeg3_bandInfo[sfreq];
910 const mpeg3_real_t *tab1, *tab2;
911
912 int tab;
913/* TODO: optimize as static */
914 static const mpeg3_real_t *tabs[3][2][2] =
915 {
916 { { mpeg3_tan1_1, mpeg3_tan2_1 } , { mpeg3_tan1_2, mpeg3_tan2_2 } },
917 { { mpeg3_pow1_1[0], mpeg3_pow2_1[0] } , { mpeg3_pow1_2[0], mpeg3_pow2_2[0] } } ,
918 { { mpeg3_pow1_1[1], mpeg3_pow2_1[1] } , { mpeg3_pow1_2[1], mpeg3_pow2_2[1] } }
919 };
920
921 tab = lsf + (gr_info->scalefac_compress & lsf);
922 tab1 = tabs[tab][ms_stereo][0];
923 tab2 = tabs[tab][ms_stereo][1];
924
925 if(gr_info->block_type == 2)
926 {
927 int lwin,do_l = 0;
928 if(gr_info->mixed_block_flag)
929 do_l = 1;
930
931 for(lwin = 0; lwin < 3; lwin++)
932 {
933/* process each window */
934/* get first band with zero values */
935/* sfb is minimal 3 for mixed mode */
936 int is_p, sb, idx, sfb = gr_info->maxband[lwin];
937 if(sfb > 3) do_l = 0;
938
939 for( ; sfb < 12 ; sfb++)
940 {
941/* scale: 0-15 */
942 is_p = scalefac[sfb * 3 + lwin - gr_info->mixed_block_flag];
943 if(is_p != 7)
944 {
945 mpeg3_real_t t1, t2;
946 sb = bi->shortDiff[sfb];
947 idx = bi->shortIdx[sfb] + lwin;
948 t1 = tab1[is_p];
949 t2 = tab2[is_p];
950 for( ; sb > 0; sb--, idx += 3)
951 {
952 mpeg3_real_t v = xr[0][idx];
953 xr[0][idx] = v * t1;
954 xr[1][idx] = v * t2;
955 }
956 }
957 }
958
959/* in the original: copy 10 to 11 , here: copy 11 to 12
960maybe still wrong??? (copy 12 to 13?) */
961/* scale: 0-15 */
962 is_p = scalefac[11 * 3 + lwin - gr_info->mixed_block_flag];
963 sb = bi->shortDiff[12];
964 idx = bi->shortIdx[12] + lwin;
965 if(is_p != 7)
966 {
967 mpeg3_real_t t1, t2;
968 t1 = tab1[is_p];
969 t2 = tab2[is_p];
970 for( ; sb > 0; sb--, idx += 3)
971 {
972 mpeg3_real_t v = xr[0][idx];
973 xr[0][idx] = v * t1;
974 xr[1][idx] = v * t2;
975 }
976 }
977 } /* end for(lwin; .. ; . ) */
978
979/* also check l-part, if ALL bands in the three windows are 'empty'
980* and mode = mixed_mode
981*/
982 if(do_l)
983 {
984 int sfb = gr_info->maxbandl;
985 int idx = bi->longIdx[sfb];
986
987 for ( ; sfb < 8; sfb++)
988 {
989 int sb = bi->longDiff[sfb];
990/* scale: 0-15 */
991 int is_p = scalefac[sfb];
992 if(is_p != 7)
993 {
994 mpeg3_real_t t1, t2;
995 t1 = tab1[is_p];
996 t2 = tab2[is_p];
997 for( ; sb > 0; sb--, idx++)
998 {
999 mpeg3_real_t v = xr[0][idx];
1000 xr[0][idx] = v * t1;
1001 xr[1][idx] = v * t2;
1002 }
1003 }
1004 else
1005 idx += sb;
1006 }
1007 }
1008 }
1009 else
1010 {
1011/* ((gr_info->block_type != 2)) */
1012 int sfb = gr_info->maxbandl;
1013 int is_p, idx = bi->longIdx[sfb];
1014 for( ; sfb < 21; sfb++)
1015 {
1016 int sb = bi->longDiff[sfb];
1017/* scale: 0-15 */
1018 is_p = scalefac[sfb];
1019 if(is_p != 7)
1020 {
1021 mpeg3_real_t t1, t2;
1022 t1 = tab1[is_p];
1023 t2 = tab2[is_p];
1024 for( ; sb > 0; sb--, idx++)
1025 {
1026 mpeg3_real_t v = xr[0][idx];
1027 xr[0][idx] = v * t1;
1028 xr[1][idx] = v * t2;
1029 }
1030 }
1031 else
1032 idx += sb;
1033 }
1034
1035 is_p = scalefac[20];
1036 if(is_p != 7)
1037 {
1038/* copy l-band 20 to l-band 21 */
1039 int sb;
1040 mpeg3_real_t t1 = tab1[is_p], t2 = tab2[is_p];
1041
1042 for(sb = bi->longDiff[21]; sb > 0; sb--, idx++)
1043 {
1044 mpeg3_real_t v = xr[0][idx];
1045 xr[0][idx] = v * t1;
1046 xr[1][idx] = v * t2;
1047 }
1048 }
1049 } /* ... */
1050}
1051
1052/* Read just the frame after a seek. */
1053int mpeg3audio_read_layer3_frame(mpeg3audio_t *audio)
1054{
1055 int result = 0;
1056
1057 result = mpeg3audio_read_header(audio);
1058 if(!result)
1059 {
1060 audio->bsbufold = audio->bsbuf;
1061 audio->bsbuf = audio->bsspace[audio->bsnum] + 512;
1062 audio->bsnum ^= 1;
1063 result = mpeg3bits_read_buffer(audio->astream, audio->bsbuf, audio->framesize);
1064 }
1065
1066 return result;
1067}
1068
1069int mpeg3audio_dolayer3(mpeg3audio_t *audio)
1070{
1071 int gr, ch, ss;
1072 int scalefacs[2][39]; /* max 39 for short[13][3] mode, mixed: 38, long: 22 */
1073 struct mpeg3_III_sideinfo sideinfo;
1074 int channels = audio->channels;
1075 int single = audio->single;
1076 int ms_stereo, i_stereo;
1077 int sfreq = audio->sampling_frequency_code;
1078 int stereo1, granules;
1079 int i;
1080
1081/* flip/init buffer */
1082 audio->bsbufold = audio->bsbuf;
1083 audio->bsbuf = audio->bsspace[audio->bsnum] + 512;
1084 audio->bsnum ^= 1;
1085
1086/* read main data into memory */
1087 if(mpeg3bits_read_buffer(audio->astream, audio->bsbuf, audio->framesize))
1088 return 1;
1089 mpeg3bits_use_ptr(audio->astream, audio->bsbuf);
1090
1091/* CRC must be skipped here for proper alignment with the backstep */
1092 if(audio->error_protection)
1093 mpeg3bits_getbits(audio->astream, 16);
1094
1095 if(channels == 1)
1096 {
1097/* stream is mono */
1098 stereo1 = 1;
1099 single = 0;
1100 }
1101 else
1102 {
1103/* Stereo */
1104 stereo1 = 2;
1105 }
1106
1107 if(audio->mode == MPG_MD_JOINT_STEREO)
1108 {
1109 ms_stereo = (audio->mode_ext & 0x2) >> 1;
1110 i_stereo = audio->mode_ext & 0x1;
1111 }
1112 else
1113 ms_stereo = i_stereo = 0;
1114
1115 if(audio->lsf)
1116 {
1117 granules = 1;
1118 }
1119 else
1120 {
1121 granules = 2;
1122 }
1123
1124 if(mpeg3audio_III_get_side_info(audio, &sideinfo, channels, ms_stereo, sfreq, single, audio->lsf))
1125 return 1;
1126
1127/* Step back */
1128 if(sideinfo.main_data_begin >= 512)
1129 return 1;
1130
1131 if(sideinfo.main_data_begin)
1132 {
1133 memcpy(audio->bsbuf + audio->ssize - sideinfo.main_data_begin,
1134 audio->bsbufold + audio->prev_framesize - sideinfo.main_data_begin,
1135 sideinfo.main_data_begin);
1136 mpeg3bits_use_ptr(audio->astream, audio->bsbuf + audio->ssize - sideinfo.main_data_begin);
1137 }
1138
1139 for(gr = 0; gr < granules; gr++)
1140 {
1141 mpeg3_real_t hybridIn [2][SBLIMIT][SSLIMIT];
1142 mpeg3_real_t hybridOut[2][SSLIMIT][SBLIMIT];
1143
1144 {
1145 struct gr_info_s *gr_info = &(sideinfo.ch[0].gr[gr]);
1146 long part2bits;
1147 if(audio->lsf)
1148 part2bits = mpeg3audio_III_get_scale_factors_2(audio, scalefacs[0], gr_info, 0);
1149 else
1150 part2bits = mpeg3audio_III_get_scale_factors_1(audio, scalefacs[0], gr_info, 0, gr);
1151//printf("dolayer3 4 %04x\n", mpeg3bits_showbits(audio->astream, 16));
1152
1153 if(mpeg3audio_III_dequantize_sample(audio, hybridIn[0], scalefacs[0], gr_info, sfreq, part2bits))
1154 {
1155 mpeg3bits_use_demuxer(audio->astream);
1156 return 1;
1157 }
1158//printf("dolayer3 5 %04x\n", mpeg3bits_showbits(audio->astream, 16));
1159 }
1160
1161 if(channels == 2)
1162 {
1163 struct gr_info_s *gr_info = &(sideinfo.ch[1].gr[gr]);
1164 long part2bits;
1165 if(audio->lsf)
1166 part2bits = mpeg3audio_III_get_scale_factors_2(audio, scalefacs[1], gr_info, i_stereo);
1167 else
1168 part2bits = mpeg3audio_III_get_scale_factors_1(audio, scalefacs[1], gr_info, 1, gr);
1169
1170 if(mpeg3audio_III_dequantize_sample(audio, hybridIn[1], scalefacs[1], gr_info, sfreq, part2bits))
1171 {
1172 mpeg3bits_use_demuxer(audio->astream);
1173 return 1;
1174 }
1175
1176 if(ms_stereo)
1177 {
1178 int i;
1179 int maxb = sideinfo.ch[0].gr[gr].maxb;
1180 if(sideinfo.ch[1].gr[gr].maxb > maxb)
1181 maxb = sideinfo.ch[1].gr[gr].maxb;
1182 for(i = 0; i < SSLIMIT * maxb; i++)
1183 {
1184 mpeg3_real_t tmp0 = ((mpeg3_real_t*)hybridIn[0])[i];
1185 mpeg3_real_t tmp1 = ((mpeg3_real_t*)hybridIn[1])[i];
1186 ((mpeg3_real_t*)hybridIn[0])[i] = tmp0 + tmp1;
1187 ((mpeg3_real_t*)hybridIn[1])[i] = tmp0 - tmp1;
1188 }
1189 }
1190
1191 if(i_stereo)
1192 mpeg3audio_III_i_stereo(audio, hybridIn, scalefacs[1], gr_info, sfreq, ms_stereo, audio->lsf);
1193
1194 if(ms_stereo || i_stereo || (single == 3))
1195 {
1196 if(gr_info->maxb > sideinfo.ch[0].gr[gr].maxb)
1197 sideinfo.ch[0].gr[gr].maxb = gr_info->maxb;
1198 else
1199 gr_info->maxb = sideinfo.ch[0].gr[gr].maxb;
1200 }
1201
1202 switch(single)
1203 {
1204 case 3:
1205 {
1206 register int i;
1207 register mpeg3_real_t *in0 = (mpeg3_real_t*)hybridIn[0], *in1 = (mpeg3_real_t*)hybridIn[1];
1208/* *0.5 done by pow-scale */
1209 for(i = 0; i < SSLIMIT * gr_info->maxb; i++, in0++)
1210 *in0 = (*in0 + *in1++);
1211 }
1212 break;
1213 case 1:
1214 {
1215 register int i;
1216 register mpeg3_real_t *in0 = (mpeg3_real_t*)hybridIn[0], *in1 = (mpeg3_real_t*)hybridIn[1];
1217 for(i = 0; i < SSLIMIT * gr_info->maxb; i++)
1218 *in0++ = *in1++;
1219 }
1220 break;
1221 }
1222 }
1223
1224 for(ch = 0; ch < stereo1; ch++)
1225 {
1226 struct gr_info_s *gr_info = &(sideinfo.ch[ch].gr[gr]);
1227 mpeg3audio_III_antialias(audio, hybridIn[ch], gr_info);
1228 mpeg3audio_III_hybrid(audio, hybridIn[ch], hybridOut[ch], ch, gr_info);
1229 }
1230
1231 for(ss = 0; ss < SSLIMIT; ss++)
1232 {
1233 if(single >= 0)
1234 {
1235 mpeg3audio_synth_mono(audio, hybridOut[0][ss], audio->pcm_sample, &(audio->pcm_point));
1236 }
1237 else
1238 {
1239 int p1 = audio->pcm_point;
1240 mpeg3audio_synth_stereo(audio, hybridOut[0][ss], 0, audio->pcm_sample, &p1);
1241 mpeg3audio_synth_stereo(audio, hybridOut[1][ss], 1, audio->pcm_sample, &(audio->pcm_point));
1242 }
1243
1244 if(audio->pcm_point / audio->channels >= audio->pcm_allocated - MPEG3AUDIO_PADDING * audio->channels)
1245 {
1246/* Need more room */
1247 mpeg3audio_replace_buffer(audio, audio->pcm_allocated + MPEG3AUDIO_PADDING * audio->channels);
1248 }
1249 }
1250 }
1251
1252 mpeg3bits_use_demuxer(audio->astream);
1253 return 0;
1254}
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 @@
1/*
2 *
3 *mantissa.c Copyright (C) Aaron Holtzman - May 1999
4 *
5 *
6 * This file is part of libmpeg3
7 *
8 * libmpeg3 is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * libmpeg3 is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with GNU Make; see the file COPYING. If not, write to
20 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 */
23
24#include "mpeg3audio.h"
25#include "../libmpeg3.h"
26#include "../mpeg3protos.h"
27
28
29/* Lookup tables of 0.16 two's complement quantization values */
30static short mpeg3_q_1[3] =
31{
32 (-2 << 15) / 3,
33 0,
34 (2 << 15) / 3
35};
36
37static short mpeg3_q_2[5] =
38{
39 (-4 << 15) / 5,
40 ((-2 << 15) / 5) << 1,
41 0,
42 (2 << 15) / 5,
43 ((4 << 15) / 5) << 1
44};
45
46static short mpeg3_q_3[7] =
47{
48 (-6 << 15) / 7,
49 (-4 << 15) / 7,
50 (-2 << 15) / 7,
51 0,
52 (2 << 15) / 7,
53 (4 << 15) / 7,
54 (6 << 15) / 7
55};
56
57static short mpeg3_q_4[11] =
58{
59 (-10 << 15) / 11,
60 (-8 << 15) / 11,
61 (-6 << 15) / 11,
62 (-4 << 15) / 11,
63 (-2 << 15) / 11,
64 0,
65 ( 2 << 15) / 11,
66 ( 4 << 15) / 11,
67 ( 6 << 15) / 11,
68 ( 8 << 15) / 11,
69 (10 << 15) / 11
70};
71
72static short mpeg3_q_5[15] =
73{
74 (-14 << 15) / 15,
75 (-12 << 15) / 15,
76 (-10 << 15) / 15,
77 (-8 << 15) / 15,
78 (-6 << 15) / 15,
79 (-4 << 15) / 15,
80 (-2 << 15) / 15,
81 0,
82 ( 2 << 15) / 15,
83 ( 4 << 15) / 15,
84 ( 6 << 15) / 15,
85 ( 8 << 15) / 15,
86 (10 << 15) / 15,
87 (12 << 15) / 15,
88 (14 << 15) / 15
89};
90
91static short mpeg3_qnttztab[16] = {0, 0, 0, 3, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16};
92
93
94/* */
95/* Scale factors for tofloat */
96/* */
97
98static const unsigned MPEG3_INT32 mpeg3_scale_factors[25] =
99{
100 0x38000000, /*2 ^ -(0 + 15) */
101 0x37800000, /*2 ^ -(1 + 15) */
102 0x37000000, /*2 ^ -(2 + 15) */
103 0x36800000, /*2 ^ -(3 + 15) */
104 0x36000000, /*2 ^ -(4 + 15) */
105 0x35800000, /*2 ^ -(5 + 15) */
106 0x35000000, /*2 ^ -(6 + 15) */
107 0x34800000, /*2 ^ -(7 + 15) */
108 0x34000000, /*2 ^ -(8 + 15) */
109 0x33800000, /*2 ^ -(9 + 15) */
110 0x33000000, /*2 ^ -(10 + 15) */
111 0x32800000, /*2 ^ -(11 + 15) */
112 0x32000000, /*2 ^ -(12 + 15) */
113 0x31800000, /*2 ^ -(13 + 15) */
114 0x31000000, /*2 ^ -(14 + 15) */
115 0x30800000, /*2 ^ -(15 + 15) */
116 0x30000000, /*2 ^ -(16 + 15) */
117 0x2f800000, /*2 ^ -(17 + 15) */
118 0x2f000000, /*2 ^ -(18 + 15) */
119 0x2e800000, /*2 ^ -(19 + 15) */
120 0x2e000000, /*2 ^ -(20 + 15) */
121 0x2d800000, /*2 ^ -(21 + 15) */
122 0x2d000000, /*2 ^ -(22 + 15) */
123 0x2c800000, /*2 ^ -(23 + 15) */
124 0x2c000000 /*2 ^ -(24 + 15) */
125};
126
127static MPEG3_FLOAT32 *mpeg3_scale_factor = (MPEG3_FLOAT32*)mpeg3_scale_factors;
128
129static inline mpeg3_real_t mpeg3audio_ac3_tofloat(unsigned short exponent, int mantissa)
130{
131 mpeg3_real_t x;
132 x = mantissa * mpeg3_scale_factor[exponent];
133 return x;
134}
135
136static inline void mpeg3audio_ac3_mantissa_reset(mpeg3_ac3_mantissa_t *mantissa)
137{
138 mantissa->m_1[2] = mantissa->m_1[1] = mantissa->m_1[0] = 0;
139 mantissa->m_2[2] = mantissa->m_2[1] = mantissa->m_2[0] = 0;
140 mantissa->m_4[1] = mantissa->m_4[0] = 0;
141/* Force new groups to be loaded */
142 mantissa->m_1_pointer = mantissa->m_2_pointer = mantissa->m_4_pointer = 3;
143}
144
145/*
146 * Generate eight bits of pseudo-entropy using a 16 bit linear
147 * feedback shift register (LFSR). The primitive polynomial used
148 * is 1 + x^4 + x^14 + x^16.
149 *
150 * The distribution is uniform, over the range [-0.707,0.707]
151 *
152 */
153inline unsigned int mpeg3audio_ac3_dither_gen(mpeg3audio_t *audio)
154{
155 int i;
156 unsigned int state;
157
158/* explicitly bring the state into a local var as gcc > 3.0? */
159/* doesn't know how to optimize out the stores */
160 state = audio->ac3_lfsr_state;
161
162/* Generate eight pseudo random bits */
163 for(i = 0; i < 8; i++)
164 {
165 state <<= 1;
166
167 if(state & 0x10000)
168 state ^= 0xa011;
169 }
170
171 audio->ac3_lfsr_state = state;
172 return (((((int)state << 8) >> 8) * (int)(0.707106f * 256.0f)) >> 16);
173}
174
175
176/* Fetch an unpacked, left justified, and properly biased/dithered mantissa value */
177static inline unsigned short mpeg3audio_ac3_mantissa_get(mpeg3audio_t *audio,
178 unsigned short bap,
179 unsigned short dithflag)
180{
181 unsigned short mantissa;
182 unsigned int group_code;
183 mpeg3_ac3_mantissa_t *mantissa_struct = &(audio->ac3_mantissa);
184
185/* If the bap is 0-5 then we have special cases to take care of */
186 switch(bap)
187 {
188 case 0:
189 if(dithflag)
190 mantissa = mpeg3audio_ac3_dither_gen(audio);
191 else
192 mantissa = 0;
193 break;
194
195 case 1:
196 if(mantissa_struct->m_1_pointer > 2)
197 {
198 group_code = mpeg3bits_getbits(audio->astream, 5);
199
200 if(group_code > 26)
201 {
202/* FIXME do proper block error handling */
203 fprintf(stderr, "mpeg3audio_ac3_mantissa_get: Invalid mantissa 1 %d\n", group_code);
204 return 0;
205 }
206
207 mantissa_struct->m_1[0] = group_code / 9;
208 mantissa_struct->m_1[1] = (group_code % 9) / 3;
209 mantissa_struct->m_1[2] = (group_code % 9) % 3;
210 mantissa_struct->m_1_pointer = 0;
211 }
212 mantissa = mantissa_struct->m_1[mantissa_struct->m_1_pointer++];
213 mantissa = mpeg3_q_1[mantissa];
214 break;
215
216 case 2:
217 if(mantissa_struct->m_2_pointer > 2)
218 {
219 group_code = mpeg3bits_getbits(audio->astream, 7);
220
221 if(group_code > 124)
222 {
223 fprintf(stderr, "mpeg3audio_ac3_mantissa_get: Invalid mantissa 2 %d\n", group_code);
224 return 0;
225 }
226
227 mantissa_struct->m_2[0] = group_code / 25;
228 mantissa_struct->m_2[1] = (group_code % 25) / 5;
229 mantissa_struct->m_2[2] = (group_code % 25) % 5;
230 mantissa_struct->m_2_pointer = 0;
231 }
232 mantissa = mantissa_struct->m_2[mantissa_struct->m_2_pointer++];
233 mantissa = mpeg3_q_2[mantissa];
234 break;
235
236 case 3:
237 mantissa = mpeg3bits_getbits(audio->astream, 3);
238
239 if(mantissa > 6)
240 {
241 fprintf(stderr, "mpeg3audio_ac3_mantissa_get: Invalid mantissa 3 %d\n", mantissa);
242 return 0;
243 }
244
245 mantissa = mpeg3_q_3[mantissa];
246 break;
247
248 case 4:
249 if(mantissa_struct->m_4_pointer > 1)
250 {
251 group_code = mpeg3bits_getbits(audio->astream, 7);
252
253 if(group_code > 120)
254 {
255 fprintf(stderr, "mpeg3audio_ac3_mantissa_get: Invalid mantissa 4 %d\n", group_code);
256 return 0;
257 }
258
259 mantissa_struct->m_4[0] = group_code / 11;
260 mantissa_struct->m_4[1] = group_code % 11;
261 mantissa_struct->m_4_pointer = 0;
262 }
263 mantissa = mantissa_struct->m_4[mantissa_struct->m_4_pointer++];
264 mantissa = mpeg3_q_4[mantissa];
265 break;
266
267 case 5:
268 mantissa = mpeg3bits_getbits(audio->astream, 4);
269
270 if(mantissa > 14)
271 {
272/* FIXME do proper block error handling */
273 fprintf(stderr, "mpeg3audio_ac3_mantissa_get: Invalid mantissa 5 %d\n", mantissa);
274 return 0;
275 }
276
277 mantissa = mpeg3_q_5[mantissa];
278 break;
279
280 default:
281 mantissa = mpeg3bits_getbits(audio->astream, mpeg3_qnttztab[bap]);
282 mantissa <<= 16 - mpeg3_qnttztab[bap];
283 }
284 return mantissa;
285}
286
287void mpeg3audio_ac3_uncouple_channel(mpeg3audio_t *audio,
288 mpeg3_real_t samples[],
289 mpeg3_ac3bsi_t *bsi,
290 mpeg3_ac3audblk_t *audblk,
291 unsigned int ch)
292{
293 unsigned int bnd = 0;
294 unsigned int sub_bnd = 0;
295 unsigned int i, j;
296 MPEG3_FLOAT32 cpl_coord = 1.0;
297 unsigned int cpl_exp_tmp;
298 unsigned int cpl_mant_tmp;
299 short mantissa;
300
301 for(i = audblk->cplstrtmant; i < audblk->cplendmant; )
302 {
303 if(!audblk->cplbndstrc[sub_bnd++])
304 {
305 cpl_exp_tmp = audblk->cplcoexp[ch][bnd] + 3 * audblk->mstrcplco[ch];
306 if(audblk->cplcoexp[ch][bnd] == 15)
307 cpl_mant_tmp = (audblk->cplcomant[ch][bnd]) << 11;
308 else
309 cpl_mant_tmp = ((0x10) | audblk->cplcomant[ch][bnd]) << 10;
310
311 cpl_coord = mpeg3audio_ac3_tofloat(cpl_exp_tmp, cpl_mant_tmp) * 8.0f;
312
313/*Invert the phase for the right channel if necessary */
314 if(bsi->acmod == 0x2 && audblk->phsflginu && ch == 1 && audblk->phsflg[bnd])
315 cpl_coord *= -1;
316
317 bnd++;
318 }
319
320 for(j = 0; j < 12; j++)
321 {
322/* Get new dither values for each channel if necessary, so */
323/* the channels are uncorrelated */
324 if(audblk->dithflag[ch] && audblk->cpl_bap[i] == 0)
325 mantissa = mpeg3audio_ac3_dither_gen(audio);
326 else
327 mantissa = audblk->cplmant[i];
328
329 samples[i] = cpl_coord * mpeg3audio_ac3_tofloat(audblk->cpl_exp[i], mantissa);;
330
331 i++;
332 }
333 }
334 return;
335}
336
337int mpeg3audio_ac3_coeff_unpack(mpeg3audio_t *audio,
338 mpeg3_ac3bsi_t *bsi,
339 mpeg3_ac3audblk_t *audblk,
340 mpeg3ac3_stream_samples_t samples)
341{
342 int i, j;
343 int done_cpl = 0;
344 short mantissa;
345
346 mpeg3audio_ac3_mantissa_reset(&(audio->ac3_mantissa));
347
348 for(i = 0; i < bsi->nfchans && !mpeg3bits_error(audio->astream); i++)
349 {
350 for(j = 0; j < audblk->endmant[i] && !mpeg3bits_error(audio->astream); j++)
351 {
352 mantissa = mpeg3audio_ac3_mantissa_get(audio, audblk->fbw_bap[i][j], audblk->dithflag[i]);
353 samples[i][j] = mpeg3audio_ac3_tofloat(audblk->fbw_exp[i][j], mantissa);
354 }
355
356 if(audblk->cplinu && audblk->chincpl[i] && !(done_cpl) && !mpeg3bits_error(audio->astream))
357 {
358/* ncplmant is equal to 12 * ncplsubnd */
359/* Don't dither coupling channel until channel separation so that
360 * interchannel noise is uncorrelated */
361 for(j = audblk->cplstrtmant;
362 j < audblk->cplendmant && !mpeg3bits_error(audio->astream);
363 j++)
364 {
365 audblk->cplmant[j] = mpeg3audio_ac3_mantissa_get(audio, audblk->cpl_bap[j], 0);
366 }
367 done_cpl = 1;
368 }
369 }
370
371/* Uncouple the channel */
372 if(audblk->cplinu)
373 {
374 if(audblk->chincpl[i])
375 mpeg3audio_ac3_uncouple_channel(audio, samples[i], bsi, audblk, i);
376 }
377
378 if(bsi->lfeon && !mpeg3bits_error(audio->astream))
379 {
380/* There are always 7 mantissas for lfe, no dither for lfe */
381 for(j = 0; j < 7 && !mpeg3bits_error(audio->astream); j++)
382 mantissa = mpeg3audio_ac3_mantissa_get(audio, audblk->lfe_bap[j], 0);
383 samples[5][j] = mpeg3audio_ac3_tofloat(audblk->lfe_exp[j], mantissa);
384 }
385
386 return mpeg3bits_error(audio->astream);
387}
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 @@
1#include "../libmpeg3.h"
2#include "../mpeg3protos.h"
3#include "mpeg3audio.h"
4#include "tables.h"
5
6#include <math.h>
7#include <stdlib.h>
8
9mpeg3audio_t* mpeg3audio_allocate_struct(mpeg3_t *file, mpeg3_atrack_t *track)
10{
11 mpeg3audio_t *audio = (mpeg3audio_t*)calloc(1, sizeof(mpeg3audio_t));
12 audio->file = file;
13 audio->track = track;
14 audio->astream = mpeg3bits_new_stream(file, track->demuxer);
15 audio->outscale = 1;
16 audio->bsbuf = audio->bsspace[1];
17 audio->init = 1;
18 audio->bo = 1;
19 audio->channels = 1;
20 return audio;
21}
22
23
24int mpeg3audio_delete_struct(mpeg3audio_t *audio)
25{
26 mpeg3bits_delete_stream(audio->astream);
27 if(audio->pcm_sample) free(audio->pcm_sample);
28 free(audio);
29 return 0;
30}
31
32int mpeg3audio_replace_buffer(mpeg3audio_t *audio, long new_allocation)
33{
34 long i;
35
36 audio->pcm_sample = (mpeg3_real_t*)realloc( audio->pcm_sample, sizeof(mpeg3_real_t) * new_allocation * audio->channels );
37 audio->pcm_allocated = new_allocation;
38/*
39 // Isn't this exactly the same as what the ANSI C function call realloc does,
40 // or did I miss C Programming 101 ?
41
42 if(!audio->pcm_sample)
43 {
44 audio->pcm_sample = (mpeg3_real_t*)malloc(sizeof(mpeg3_real_t) * new_allocation * audio->channels);
45 audio->pcm_allocated = new_allocation;
46 }
47 else
48 {
49 mpeg3_real_t *new_samples = (mpeg3_real_t*)malloc(sizeof(mpeg3_real_t) * new_allocation * audio->channels);
50 for(i = 0; i < audio->pcm_allocated * audio->channels; i++)
51 {
52 new_samples[i] = audio->pcm_sample[i];
53 }
54 free(audio->pcm_sample);
55 audio->pcm_sample = new_samples;
56 audio->pcm_allocated = new_allocation;
57 }
58*/
59 return 0;
60}
61
62int mpeg3audio_read_frame(mpeg3audio_t *audio)
63{
64 int result = 0;
65 result = mpeg3audio_read_header(audio);
66
67 if(!result)
68 {
69 switch(audio->format)
70 {
71 case AUDIO_AC3:
72 result = mpeg3audio_do_ac3(audio);
73 break;
74
75 case AUDIO_MPEG:
76 switch(audio->layer)
77 {
78 case 1:
79 break;
80
81 case 2:
82 result = mpeg3audio_dolayer2(audio);
83 break;
84
85 case 3:
86 result = mpeg3audio_dolayer3(audio);
87 break;
88
89 default:
90 result = 1;
91 break;
92 }
93 break;
94
95 case AUDIO_PCM:
96 result = mpeg3audio_do_pcm(audio);
97 break;
98 }
99 }
100
101 if(!result)
102 {
103/* Byte align the stream */
104 mpeg3bits_byte_align(audio->astream);
105 }
106 return result;
107}
108
109/* Get the length but also initialize the frame sizes. */
110int mpeg3audio_get_length(mpeg3audio_t *audio, mpeg3_atrack_t *track)
111{
112 long result = 0;
113 long framesize1 = 0, total1 = 0;
114 long framesize2 = 0, total2 = 0;
115 long total_framesize = 0, total_frames = 0;
116 long byte_limit = 131072; /* Total bytes to gather information from */
117 long total_bytes = 0;
118 long major_framesize; /* Bigger framesize + header */
119 long minor_framesize; /* Smaller framesize + header */
120 long major_total;
121 long minor_total;
122 mpeg3_t *file = audio->file;
123
124/* Get the frame sizes */
125 mpeg3bits_seek_start(audio->astream);
126 audio->pcm_point = 0;
127 result = mpeg3audio_read_frame(audio); /* Stores the framesize */
128 audio->samples_per_frame = audio->pcm_point / audio->channels;
129
130 switch(audio->format)
131 {
132 case AUDIO_AC3:
133 audio->avg_framesize = audio->framesize;
134 break;
135
136 case AUDIO_MPEG:
137 framesize1 = audio->framesize;
138 total_bytes += audio->framesize;
139 total1 = 1;
140
141 while(!result && total_bytes < byte_limit)
142 {
143 audio->pcm_point = 0;
144 result = mpeg3audio_read_frame(audio);
145 total_bytes += audio->framesize;
146 if(audio->framesize != framesize1)
147 {
148 framesize2 = audio->framesize;
149 total2 = 1;
150 break;
151 }
152 else
153 {
154 total1++;
155 }
156 }
157
158 while(!result && total_bytes < byte_limit)
159 {
160 audio->pcm_point = 0;
161 result = mpeg3audio_read_frame(audio);
162 total_bytes += audio->framesize;
163 if(audio->framesize != framesize2)
164 {
165 break;
166 }
167 else
168 {
169 total2++;
170 }
171 }
172
173 audio->pcm_point = 0;
174 result = mpeg3audio_read_frame(audio);
175 if(audio->framesize != framesize1 && audio->framesize != framesize2)
176 {
177/* Variable bit rate. Get the average frame size. */
178 while(!result && total_bytes < byte_limit)
179 {
180 audio->pcm_point = 0;
181 result = mpeg3audio_read_frame(audio);
182 total_bytes += audio->framesize;
183 if(!result)
184 {
185 total_framesize += audio->framesize;
186 total_frames++;
187 }
188 }
189 audio->avg_framesize = 4 + (total_framesize + framesize1 + framesize2) / (total_frames + total1 + total2);
190 }
191 else
192 {
193 major_framesize = framesize2 > framesize1 ? framesize2 : framesize1;
194 major_total = framesize2 > framesize1 ? total2 : total1;
195 minor_framesize = framesize2 > framesize1 ? framesize1 : framesize2;
196 minor_total = framesize2 > framesize1 ? total1 : total2;
197/* Add the headers to the framesizes */
198 audio->avg_framesize = 4 + (major_framesize * major_total + minor_framesize * minor_total) / (major_total + minor_total);
199 }
200 break;
201
202 case AUDIO_PCM:
203 break;
204 }
205
206/* Estimate the total samples */
207 if(file->is_audio_stream)
208 {
209/* From the raw file */
210 result = (long)((float)mpeg3demuxer_total_bytes(audio->astream->demuxer) / audio->avg_framesize * audio->samples_per_frame);
211 }
212 else
213 {
214/* Gross approximation from a multiplexed file. */
215 result = (long)(mpeg3demux_length(audio->astream->demuxer) * track->sample_rate);
216 /* result = (long)((mpeg3_real_t)mpeg3_video_frames(file, 0) / mpeg3_frame_rate(file, 0) * track->sample_rate); */
217/* We would scan the multiplexed packets here for the right timecode if only */
218/* they had meaningful timecode. */
219 }
220
221 audio->pcm_point = 0;
222 mpeg3bits_seek_start(audio->astream);
223 mpeg3audio_reset_synths(audio);
224 return result;
225}
226
227int mpeg3audio_seek(mpeg3audio_t *audio, long position)
228{
229 int result = 0;
230 mpeg3_t *file = audio->file;
231 mpeg3_atrack_t *track = audio->track;
232 long frame_number;
233 long byte_position;
234 double time_position;
235
236/* Sample seek wasn't requested */
237 if(audio->sample_seek < 0)
238 {
239 audio->pcm_position = position;
240 audio->pcm_size = 0;
241 return 0;
242 }
243
244/* Can't slide buffer. Seek instead. */
245 if(!file->is_audio_stream)
246 {
247/* Seek in a multiplexed stream using the multiplexer. */
248 time_position = (double)position / track->sample_rate;
249 result |= mpeg3bits_seek_time(audio->astream, time_position);
250 audio->pcm_position = (long)mpeg3bits_packet_time(audio->astream) * track->sample_rate;
251/*printf("wanted %f got %f\n", time_position, mpeg3bits_packet_time(audio->astream)); */
252 }
253 else
254 {
255/* Seek in an elemental stream. This algorithm achieves sample accuracy on fixed bitrates. */
256/* Forget about variable bitrates or program streams. */
257 frame_number = position / audio->samples_per_frame;
258 byte_position = (long)(audio->avg_framesize * frame_number);
259 audio->pcm_position = frame_number * audio->samples_per_frame;
260
261 if(byte_position < audio->avg_framesize * 2)
262 {
263 result |= mpeg3bits_seek_start(audio->astream);
264 audio->pcm_position = 0;
265 }
266 else
267 {
268 result |= mpeg3bits_seek_byte(audio->astream, byte_position);
269 }
270 }
271
272/* Arm the backstep buffer for layer 3 if not at the beginning already. */
273 if(byte_position >= audio->avg_framesize * 2 && audio->layer == 3 && !result)
274 {
275 result |= mpeg3audio_prev_header(audio);
276 result |= mpeg3audio_read_layer3_frame(audio);
277 }
278
279/* Reset the tables. */
280 mpeg3audio_reset_synths(audio);
281 audio->pcm_size = 0;
282 audio->pcm_point = 0;
283 return result;
284}
285
286/* ================================================================ */
287/* ENTRY POINTS */
288/* ================================================================ */
289
290
291
292
293mpeg3audio_t* mpeg3audio_new(mpeg3_t *file, mpeg3_atrack_t *track, int format)
294{
295 mpeg3audio_t *audio = mpeg3audio_allocate_struct(file, track);
296 int result = 0;
297
298/* Init tables */
299 mpeg3audio_new_decode_tables(audio);
300 audio->percentage_seek = -1;
301 audio->sample_seek = -1;
302 audio->format = format;
303
304/* Determine the format of the stream */
305 if(format == AUDIO_UNKNOWN)
306 {
307 if(((mpeg3bits_showbits(audio->astream, 32) & 0xffff0000) >> 16) == MPEG3_AC3_START_CODE)
308 audio->format = AUDIO_AC3;
309 else
310 audio->format = AUDIO_MPEG;
311 }
312
313/* get channel count */
314 result = mpeg3audio_read_header(audio);
315
316/* Set up the sample buffer */
317 mpeg3audio_replace_buffer(audio, 262144);
318
319/* Copy information to the mpeg struct */
320 if(!result)
321 {
322 track->channels = audio->channels;
323
324 switch(audio->format)
325 {
326 case AUDIO_AC3:
327 track->sample_rate = mpeg3_ac3_samplerates[audio->sampling_frequency_code];
328 break;
329
330 case AUDIO_MPEG:
331 track->sample_rate = mpeg3_freqs[audio->sampling_frequency_code];
332 break;
333
334 case AUDIO_PCM:
335 track->sample_rate = 48000;
336 break;
337 }
338
339 track->total_samples = mpeg3audio_get_length(audio, track);
340 result |= mpeg3bits_seek_start(audio->astream);
341 }
342 else
343 {
344 mpeg3audio_delete_struct(audio);
345 audio = 0;
346 }
347
348 return audio;
349}
350
351int mpeg3audio_delete(mpeg3audio_t *audio)
352{
353 mpeg3audio_delete_struct(audio);
354 return 0;
355}
356
357int mpeg3audio_seek_percentage(mpeg3audio_t *audio, double percentage)
358{
359 audio->percentage_seek = percentage;
360 return 0;
361}
362
363int mpeg3audio_seek_sample(mpeg3audio_t *audio, long sample)
364{
365 audio->sample_seek = sample;
366 return 0;
367}
368
369/* Read raw frames for concatenation purposes */
370int mpeg3audio_read_raw(mpeg3audio_t *audio, unsigned char *output, long *size, long max_size)
371{
372 int result = 0;
373 int i;
374 *size = 0;
375
376 switch(audio->format)
377 {
378 case AUDIO_AC3:
379/* Just write the AC3 stream */
380 if(mpeg3bits_read_buffer(audio->astream, output, audio->framesize))
381 return 1;
382 *size = audio->framesize;
383 break;
384
385 case AUDIO_MPEG:
386/* Fix the mpeg stream */
387 result = mpeg3audio_read_header(audio);
388 if(!result)
389 {
390 if(max_size < 4) return 1;
391 *output++ = (audio->newhead & 0xff000000) >> 24;
392 *output++ = (audio->newhead & 0xff0000) >> 16;
393 *output++ = (audio->newhead & 0xff00) >> 8;
394 *output++ = (audio->newhead & 0xff);
395 *size += 4;
396
397 if(max_size < 4 + audio->framesize) return 1;
398 if(mpeg3bits_read_buffer(audio->astream, output, audio->framesize))
399 return 1;
400
401 *size += audio->framesize;
402 }
403 break;
404
405 case AUDIO_PCM:
406 if(mpeg3bits_read_buffer(audio->astream, output, audio->framesize))
407 return 1;
408 *size = audio->framesize;
409 break;
410 }
411 return result;
412}
413
414/* Channel is 0 to channels - 1 */
415int mpeg3audio_decode_audio(mpeg3audio_t *audio,
416 mpeg3_real_t *output_f,
417 short *output_i, int sampleSpacing,
418 int channel,
419 long start_position,
420 long len)
421{
422 long allocation_needed = len + MPEG3AUDIO_PADDING;
423 long i, j, result = 0;
424 mpeg3_t *file = audio->file;
425 mpeg3_atrack_t *atrack = audio->track;
426 long attempts;
427
428/* Create new buffer */
429 if(audio->pcm_allocated < allocation_needed)
430 {
431 mpeg3audio_replace_buffer(audio, allocation_needed);
432 }
433
434/* There was a percentage seek */
435 if(audio->percentage_seek >= 0)
436 {
437 mpeg3bits_seek_percentage(audio->astream, audio->percentage_seek);
438/* Force the pcm buffer to be reread. */
439 audio->pcm_position = start_position;
440 audio->pcm_size = 0;
441 audio->percentage_seek = -1;
442 }
443 else
444 {
445/* Entire output is in buffer so don't do anything. */
446 if(start_position >= audio->pcm_position && start_position < audio->pcm_position + audio->pcm_size &&
447 start_position + len <= audio->pcm_size)
448 {
449 ;
450 }
451 else
452/* Output starts in buffer but ends later so slide it back. */
453 if(start_position <= audio->pcm_position + audio->pcm_size &&
454 start_position >= audio->pcm_position)
455 {
456 for(i = 0, j = (start_position - audio->pcm_position) * audio->channels;
457 j < audio->pcm_size * audio->channels;
458 i++, j++)
459 {
460 audio->pcm_sample[i] = audio->pcm_sample[j];
461 }
462
463 audio->pcm_point = i;
464 audio->pcm_size -= start_position - audio->pcm_position;
465 audio->pcm_position = start_position;
466 }
467 else
468 {
469/* Output is outside buffer completely. */
470 result = mpeg3audio_seek(audio, start_position);
471 audio->sample_seek = -1;
472/* Check sanity */
473 if(start_position < audio->pcm_position) audio->pcm_position = start_position;
474 }
475 audio->sample_seek = -1;
476 }
477
478/* Read packets until the buffer is full. */
479 if(!result)
480 {
481 attempts = 0;
482 result = 1;
483 while(attempts < 6 &&
484 !mpeg3bits_eof(audio->astream) &&
485 audio->pcm_size + audio->pcm_position < start_position + len)
486 {
487 result = mpeg3audio_read_frame(audio);
488 if(result) attempts++;
489 audio->pcm_size = audio->pcm_point / audio->channels;
490 }
491 }
492
493
494
495/* Copy the buffer to the output */
496 if(output_f)
497 {
498 for(i = 0, j = (start_position - audio->pcm_position) * audio->channels + channel;
499 i < len && j < audio->pcm_size * audio->channels;
500 i++, j += audio->channels)
501 {
502 output_f[i] = audio->pcm_sample[j];
503 }
504 for( ; i < len; i++)
505 {
506 output_f[i] = 0;
507 }
508 }
509 else
510 if(output_i)
511 {
512 int sample;
513 for(i = 0, j = (start_position - audio->pcm_position) * audio->channels + channel;
514 i < (len*(sampleSpacing+1)) && j < audio->pcm_size * audio->channels;
515 i++, j += audio->channels)
516 {
517 sample = (int)(audio->pcm_sample[j] * 32767);
518 if(sample > 32767) sample = 32767;
519 else
520 if(sample < -32768) sample = -32768;
521
522 output_i[i] = sample;
523 i += sampleSpacing;
524 }
525 for( ; i < (len*(sampleSpacing+1)); i++)
526 {
527 output_i[i] = 0;
528 i += sampleSpacing;
529 }
530 }
531
532 if(audio->pcm_point > 0)
533 return 0;
534 else
535 return result;
536}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef MPEG3AUDIO_H
21#define MPEG3AUDIO_H
22
23#include "ac3.h"
24#include "../bitstream.h"
25typedef struct mpeg3_atrack_rec mpeg3_atrack_t;
26
27#define MAXFRAMESIZE 1792
28#define HDRCMPMASK 0xfffffd00
29#define SBLIMIT 32
30#define SSLIMIT 18
31#define SCALE_BLOCK 12
32#define MPEG3AUDIO_PADDING 1024
33
34/* Values for mode */
35 #define MPG_MD_STEREO 0
36 #define MPG_MD_JOINT_STEREO 1
37 #define MPG_MD_DUAL_CHANNEL 2
38 #define MPG_MD_MONO 3
39
40/* IMDCT variables */
41typedef struct
42{
43 mpeg3_real_t real;
44 mpeg3_real_t imag;
45} mpeg3_complex_t;
46
47#define AC3_N 512
48
49struct al_table
50{
51 short bits;
52 short d;
53};
54
55typedef struct
56{
57 struct mpeg3_rec* file;
58 mpeg3_atrack_t* track;
59 mpeg3_bits_t *astream;
60
61/* In order of importance */
62 int format; /* format of audio */
63 int layer; /* layer if mpeg */
64 int channels;
65 long outscale;
66 long framenum;
67 long prev_framesize;
68 long framesize; /* For mp3 current framesize without header. For AC3 current framesize with header. */
69 int avg_framesize; /* Includes the 4 byte header */
70 mpeg3_real_t *pcm_sample; /* Interlaced output from synthesizer in floats */
71 int pcm_point; /* Float offset in pcm_sample to write to */
72 long pcm_position; /* Sample start of pcm_samples in file */
73 long pcm_size; /* Number of pcm samples in the buffer */
74 long pcm_allocated; /* Allocated number of samples in pcm_samples */
75 int sample_seek;
76 double percentage_seek;
77 unsigned long oldhead;
78 unsigned long newhead;
79 unsigned long firsthead;
80 int bsnum;
81 int lsf;
82 int mpeg35;
83 int sampling_frequency_code;
84 int bitrate_index;
85 int bitrate;
86 int samples_per_frame;
87 int padding;
88 int extension;
89 int mode;
90 int mode_ext;
91 int copyright;
92 int original;
93 int emphasis;
94 int error_protection;
95
96/* Back step buffers for mp3 */
97 unsigned char bsspace[2][MAXFRAMESIZE + 512]; /* MAXFRAMESIZE */
98 unsigned char *bsbuf, *bsbufold;
99 long ssize;
100 int init;
101 int single;
102 struct al_table *alloc;
103 int II_sblimit;
104 int jsbound;
105 int bo; /* Static variable in synthesizer */
106
107/* MP3 Static arrays here */
108 mpeg3_real_t synth_stereo_buffs[2][2][0x110];
109 mpeg3_real_t synth_mono_buff[64];
110 unsigned int layer2_scfsi_buf[64];
111
112 mpeg3_real_t mp3_block[2][2][SBLIMIT * SSLIMIT];
113 int mp3_blc[2];
114
115/* AC3 specific stuff. AC3 also shares objects with MPEG */
116 unsigned int ac3_framesize_code;
117 mpeg3_ac3bsi_t ac3_bsi;
118 mpeg3_ac3audblk_t ac3_audblk;
119 mpeg3_ac3_bitallocation_t ac3_bit_allocation;
120 mpeg3_ac3_mantissa_t ac3_mantissa;
121 mpeg3_complex_t ac3_imdct_buf[AC3_N / 4];
122
123/* Delay buffer for DCT interleaving */
124 mpeg3_real_t ac3_delay[6][AC3_N / 2];
125/* Twiddle factor LUT */
126 mpeg3_complex_t *ac3_w[7];
127#if !defined(USE_FIXED_POINT) || defined(PRINT_FIXED_POINT_TABLES)
128 /* Just for allocated memory */
129 mpeg3_complex_t ac3_w_1[1];
130 mpeg3_complex_t ac3_w_2[2];
131 mpeg3_complex_t ac3_w_4[4];
132 mpeg3_complex_t ac3_w_8[8];
133 mpeg3_complex_t ac3_w_16[16];
134 mpeg3_complex_t ac3_w_32[32];
135 mpeg3_complex_t ac3_w_64[64];
136#endif
137 int ac3_lfsr_state;
138 unsigned char ac3_buffer[MAX_AC3_FRAMESIZE];
139 mpeg3ac3_stream_samples_t ac3_samples;
140} mpeg3audio_t;
141
142
143
144#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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef MPEG3REAL_H
21#define MPEG3REAL_H
22
23#ifdef USE_FIXED_POINT
24
25#include <limits.h>
26#include <stdio.h>
27
28#ifndef LONGLONG
29#define LONGLONG long long
30#endif
31
32//#define SC (1<<16)
33#define SC (1<<15)
34
35class mpeg3_real_t {
36 long v;
37public:
38 mpeg3_real_t() { } // Uninitialized, just like a float
39 mpeg3_real_t(double d) { v=long(d*SC); }
40 mpeg3_real_t(float f) { v=long(f*SC); }
41 mpeg3_real_t(int i) { v=long(i*SC); }
42 long fixedPoint() const { return v; }
43 operator float() const { return ((float)v)/SC; }
44 operator int() const { return (int)(v/SC); }
45 mpeg3_real_t operator+() const;
46 mpeg3_real_t operator-() const;
47 mpeg3_real_t& operator= (const mpeg3_real_t&);
48 mpeg3_real_t& operator+= (const mpeg3_real_t&);
49 mpeg3_real_t& operator-= (const mpeg3_real_t&);
50 mpeg3_real_t& operator*= (const mpeg3_real_t&);
51 mpeg3_real_t& operator/= (const mpeg3_real_t&);
52 friend mpeg3_real_t operator+ (const mpeg3_real_t&, const mpeg3_real_t&);
53 friend mpeg3_real_t operator- (const mpeg3_real_t&, const mpeg3_real_t&);
54 friend mpeg3_real_t operator* (const mpeg3_real_t&, const mpeg3_real_t&);
55 friend mpeg3_real_t operator/ (const mpeg3_real_t&, const mpeg3_real_t&);
56 friend mpeg3_real_t operator+ (const mpeg3_real_t&, const float&);
57 friend mpeg3_real_t operator- (const mpeg3_real_t&, const float&);
58 friend mpeg3_real_t operator* (const mpeg3_real_t&, const float&);
59 friend mpeg3_real_t operator/ (const mpeg3_real_t&, const float&);
60 friend mpeg3_real_t operator+ (const float&, const mpeg3_real_t&);
61 friend mpeg3_real_t operator- (const float&, const mpeg3_real_t&);
62 friend mpeg3_real_t operator* (const float&, const mpeg3_real_t&);
63 friend mpeg3_real_t operator/ (const float&, const mpeg3_real_t&);
64 friend mpeg3_real_t operator+ (const mpeg3_real_t&, const int&);
65 friend mpeg3_real_t operator- (const mpeg3_real_t&, const int&);
66 friend mpeg3_real_t operator* (const mpeg3_real_t&, const int&);
67 friend mpeg3_real_t operator/ (const mpeg3_real_t&, const int&);
68 friend mpeg3_real_t operator+ (const int&, const mpeg3_real_t&);
69 friend mpeg3_real_t operator- (const int&, const mpeg3_real_t&);
70 friend mpeg3_real_t operator* (const int&, const mpeg3_real_t&);
71 friend mpeg3_real_t operator/ (const int&, const mpeg3_real_t&);
72};
73
74inline mpeg3_real_t mpeg3_real_t::operator+() const
75{
76 return *this;
77}
78
79inline mpeg3_real_t mpeg3_real_t::operator-() const
80{
81 mpeg3_real_t r;
82 r.v=-v;
83 return r;
84}
85
86inline mpeg3_real_t& mpeg3_real_t::operator= (const mpeg3_real_t& o)
87{
88 v=o.v;
89 return *this;
90}
91
92inline mpeg3_real_t& mpeg3_real_t::operator+= (const mpeg3_real_t& o)
93{
94 v += o.v;
95 return *this;
96}
97
98inline mpeg3_real_t& mpeg3_real_t::operator-= (const mpeg3_real_t& o)
99{
100 v -= o.v;
101 return *this;
102}
103
104inline mpeg3_real_t& mpeg3_real_t::operator*= (const mpeg3_real_t& o)
105{
106 *this = *this * o;
107 return *this;
108}
109
110inline mpeg3_real_t& mpeg3_real_t::operator/= (const mpeg3_real_t& o)
111{
112 *this = *this / o;
113 return *this;
114}
115
116
117inline mpeg3_real_t operator+ (const mpeg3_real_t&a, const mpeg3_real_t&b)
118{
119 mpeg3_real_t r;
120 r.v=a.v+b.v;
121 return r;
122}
123
124inline mpeg3_real_t operator- (const mpeg3_real_t&a, const mpeg3_real_t&b)
125{
126 mpeg3_real_t r;
127 r.v=a.v-b.v;
128 return r;
129}
130
131inline mpeg3_real_t operator* (const mpeg3_real_t&a, const mpeg3_real_t&b)
132{
133 mpeg3_real_t r;
134 r.v = (LONGLONG)a.v * b.v / SC;
135 return r;
136}
137
138inline mpeg3_real_t operator/ (const mpeg3_real_t&a, const mpeg3_real_t&b)
139{
140 mpeg3_real_t r;
141 r.v = (LONGLONG)a.v * SC / b.v;
142 return r;
143}
144
145inline mpeg3_real_t operator+ (const mpeg3_real_t&a, const float&b)
146{
147 return a+mpeg3_real_t(b);
148}
149
150inline mpeg3_real_t operator- (const mpeg3_real_t&a, const float&b)
151{
152 return a-mpeg3_real_t(b);
153}
154
155inline mpeg3_real_t operator* (const mpeg3_real_t&a, const float&b)
156{
157 return a*mpeg3_real_t(b);
158}
159
160inline mpeg3_real_t operator/ (const mpeg3_real_t&a, const float&b)
161{
162 return a/mpeg3_real_t(b);
163}
164
165
166inline mpeg3_real_t operator+ (const float&a, const mpeg3_real_t&b)
167{
168 return mpeg3_real_t(a)+b;
169}
170
171inline mpeg3_real_t operator- (const float&a, const mpeg3_real_t&b)
172{
173 return mpeg3_real_t(a)-b;
174}
175
176inline mpeg3_real_t operator* (const float&a, const mpeg3_real_t&b)
177{
178 return mpeg3_real_t(a)*b;
179}
180
181inline mpeg3_real_t operator/ (const float&a, const mpeg3_real_t&b)
182{
183 return mpeg3_real_t(a)/b;
184}
185
186
187inline mpeg3_real_t operator+ (const mpeg3_real_t&a, const int&b)
188{
189 return a+mpeg3_real_t(b);
190}
191
192inline mpeg3_real_t operator- (const mpeg3_real_t&a, const int&b)
193{
194 return a-mpeg3_real_t(b);
195}
196
197inline mpeg3_real_t operator* (const mpeg3_real_t&a, const int&b)
198{
199 return a*mpeg3_real_t(b);
200}
201
202inline mpeg3_real_t operator/ (const mpeg3_real_t&a, const int&b)
203{
204 return a/mpeg3_real_t(b);
205}
206
207
208inline mpeg3_real_t operator+ (const int&a, const mpeg3_real_t&b)
209{
210 return mpeg3_real_t(a)+b;
211}
212
213inline mpeg3_real_t operator- (const int&a, const mpeg3_real_t&b)
214{
215 return mpeg3_real_t(a)-b;
216}
217
218inline mpeg3_real_t operator* (const int&a, const mpeg3_real_t&b)
219{
220 return mpeg3_real_t(a)*b;
221}
222
223inline mpeg3_real_t operator/ (const int&a, const mpeg3_real_t&b)
224{
225 return mpeg3_real_t(a)/b;
226}
227
228#else
229typedef float mpeg3_real_t;
230#endif
231
232#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 @@
1#include "mpeg3audio.h"
2#include "../libmpeg3.h"
3#include "../mpeg3protos.h"
4
5int mpeg3audio_read_pcm_header(mpeg3audio_t *audio)
6{
7 unsigned int code;
8
9 code = mpeg3bits_getbits(audio->astream, 16);
10 while(!mpeg3bits_eof(audio->astream) && code != MPEG3_PCM_START_CODE)
11 {
12 code <<= 8;
13 code &= 0xffff;
14 code |= mpeg3bits_getbits(audio->astream, 8);
15 }
16
17 audio->avg_framesize = audio->framesize = 0x7db;
18 audio->channels = 2;
19
20 return mpeg3bits_eof(audio->astream);
21}
22
23int mpeg3audio_do_pcm(mpeg3audio_t *audio)
24{
25 int i, j, k;
26 MPEG3_INT16 sample;
27 int frame_samples = (audio->framesize - 3) / audio->channels / 2;
28
29 if(mpeg3bits_read_buffer(audio->astream, audio->ac3_buffer, frame_samples * audio->channels * 2))
30 return 1;
31
32/* Need more room */
33 if(audio->pcm_point / audio->channels >= audio->pcm_allocated - MPEG3AUDIO_PADDING * audio->channels)
34 {
35 mpeg3audio_replace_buffer(audio, audio->pcm_allocated + MPEG3AUDIO_PADDING * audio->channels);
36 }
37
38 k = 0;
39 for(i = 0; i < frame_samples; i++)
40 {
41 for(j = 0; j < audio->channels; j++)
42 {
43 sample = ((MPEG3_INT16)(audio->ac3_buffer[k++])) << 8;
44 sample |= audio->ac3_buffer[k++];
45 audio->pcm_sample[audio->pcm_point + i * audio->channels + j] =
46 (mpeg3_real_t)sample / 32767;
47 }
48 }
49 audio->pcm_point += frame_samples * audio->channels;
50 return 0;
51}
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 @@
1#include "mpeg3audio.h"
2#include "../libmpeg3.h"
3#include "../mpeg3protos.h"
4#include "tables.h"
5
6#define WRITE_SAMPLE(samples, sum) \
7{ \
8 (*samples) = (sum); \
9}
10
11int mpeg3audio_synth_stereo(mpeg3audio_t *audio, mpeg3_real_t *bandPtr, int channel, mpeg3_real_t *out, int *pnt)
12{
13 const int step = 2;
14 mpeg3_real_t *samples = out + *pnt;
15 register mpeg3_real_t sum;
16 mpeg3_real_t *b0, (*buf)[0x110];
17 int bo1;
18
19 if(!channel)
20 {
21 audio->bo--;
22 audio->bo &= 0xf;
23 buf = audio->synth_stereo_buffs[0];
24 }
25 else
26 {
27 samples++;
28 buf = audio->synth_stereo_buffs[1];
29 }
30
31 if(audio->bo & 0x1)
32 {
33 b0 = buf[0];
34 bo1 = audio->bo;
35 mpeg3audio_dct64(buf[1] + ((audio->bo + 1) & 0xf), buf[0] + audio->bo, bandPtr);
36 }
37 else
38 {
39 b0 = buf[1];
40 bo1 = audio->bo + 1;
41 mpeg3audio_dct64(buf[0] + audio->bo, buf[1] + audio->bo + 1, bandPtr);
42 }
43
44/*printf("%f %f %f\n", buf[0][0], buf[1][0], bandPtr[0]); */
45
46 {
47 register int j;
48 mpeg3_real_t *window = mpeg3_decwin + 16 - bo1;
49
50 for(j = 16; j; j--, b0 += 0x10, window += 0x20, samples += step)
51 {
52 sum = window[0x0] * b0[0x0];
53 sum -= window[0x1] * b0[0x1];
54 sum += window[0x2] * b0[0x2];
55 sum -= window[0x3] * b0[0x3];
56 sum += window[0x4] * b0[0x4];
57 sum -= window[0x5] * b0[0x5];
58 sum += window[0x6] * b0[0x6];
59 sum -= window[0x7] * b0[0x7];
60 sum += window[0x8] * b0[0x8];
61 sum -= window[0x9] * b0[0x9];
62 sum += window[0xA] * b0[0xA];
63 sum -= window[0xB] * b0[0xB];
64 sum += window[0xC] * b0[0xC];
65 sum -= window[0xD] * b0[0xD];
66 sum += window[0xE] * b0[0xE];
67 sum -= window[0xF] * b0[0xF];
68
69 WRITE_SAMPLE(samples, sum);
70 }
71
72 sum = window[0x0] * b0[0x0];
73 sum += window[0x2] * b0[0x2];
74 sum += window[0x4] * b0[0x4];
75 sum += window[0x6] * b0[0x6];
76 sum += window[0x8] * b0[0x8];
77 sum += window[0xA] * b0[0xA];
78 sum += window[0xC] * b0[0xC];
79 sum += window[0xE] * b0[0xE];
80 WRITE_SAMPLE(samples, sum);
81 b0 -= 0x10;
82 window -= 0x20;
83 samples += step;
84 window += bo1 << 1;
85
86 for(j = 15; j; j--, b0 -= 0x10, window -= 0x20, samples += step)
87 {
88 sum = -window[-0x1] * b0[0x0];
89 sum -= window[-0x2] * b0[0x1];
90 sum -= window[-0x3] * b0[0x2];
91 sum -= window[-0x4] * b0[0x3];
92 sum -= window[-0x5] * b0[0x4];
93 sum -= window[-0x6] * b0[0x5];
94 sum -= window[-0x7] * b0[0x6];
95 sum -= window[-0x8] * b0[0x7];
96 sum -= window[-0x9] * b0[0x8];
97 sum -= window[-0xA] * b0[0x9];
98 sum -= window[-0xB] * b0[0xA];
99 sum -= window[-0xC] * b0[0xB];
100 sum -= window[-0xD] * b0[0xC];
101 sum -= window[-0xE] * b0[0xD];
102 sum -= window[-0xF] * b0[0xE];
103 sum -= window[-0x0] * b0[0xF];
104
105 WRITE_SAMPLE(samples, sum);
106 }
107 }
108 *pnt += 64;
109
110 return 0;
111}
112
113int mpeg3audio_synth_mono(mpeg3audio_t *audio, mpeg3_real_t *bandPtr, mpeg3_real_t *samples, int *pnt)
114{
115 mpeg3_real_t *samples_tmp = audio->synth_mono_buff;
116 mpeg3_real_t *tmp1 = samples_tmp;
117 int i, ret;
118 int pnt1 = 0;
119
120 ret = mpeg3audio_synth_stereo(audio, bandPtr, 0, samples_tmp, &pnt1);
121 samples += *pnt;
122
123 for(i = 0; i < 32; i++)
124 {
125 *samples = *tmp1;
126 samples++;
127 tmp1 += 2;
128 }
129 *pnt += 32;
130
131 return ret;
132}
133
134
135/* Call this after every seek to reset the buffers */
136int mpeg3audio_reset_synths(mpeg3audio_t *audio)
137{
138 int i, j, k;
139 for(i = 0; i < 2; i++)
140 {
141 for(j = 0; j < 2; j++)
142 {
143 for(k = 0; k < 0x110; k++)
144 {
145 audio->synth_stereo_buffs[i][j][k] = 0;
146 }
147 }
148 }
149 for(i = 0; i < 64; i++)
150 {
151 audio->synth_mono_buff[i] = 0;
152 audio->layer2_scfsi_buf[i] = 0;
153 }
154 for(i = 0; i < 2; i++)
155 {
156 for(j = 0; j < 2; j++)
157 {
158 for(k = 0; k < SBLIMIT * SSLIMIT; k++)
159 {
160 audio->mp3_block[i][j][k] = 0;
161 }
162 }
163 }
164 audio->mp3_blc[0] = 0;
165 audio->mp3_blc[1] = 0;
166 for(i = 0; i < audio->channels; i++)
167 {
168 for(j = 0; j < AC3_N / 2; j++)
169 {
170 audio->ac3_delay[i][j] = 0;
171 }
172 }
173 return 0;
174}
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 @@
1#include "mpeg3audio.h"
2#include "../libmpeg3.h"
3#include "../mpeg3protos.h"
4#include "tables.h"
5
6#include <math.h>
7
8/* Bitrate indexes */
9int mpeg3_tabsel_123[2][3][16] = {
10 { {0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,},
11 {0,32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384,},
12 {0,32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320,} },
13
14 { {0,32,48,56,64,80,96,112,128,144,160,176,192,224,256,},
15 {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,},
16 {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,} }
17};
18
19long mpeg3_freqs[9] = { 44100, 48000, 32000, 22050, 24000, 16000 , 11025 , 12000 , 8000 };
20
21#ifdef USE_3DNOW
22mpeg3_real_t mpeg3_decwin[2 * (512 + 32)];
23mpeg3_real_t mpeg3_cos64[32], mpeg3_cos32[16], mpeg3_cos16[8], mpeg3_cos8[4], mpeg3_cos4[2];
24#else
25mpeg3_real_t mpeg3_decwin[512 + 32];
26mpeg3_real_t mpeg3_cos64[16], mpeg3_cos32[8], mpeg3_cos16[4], mpeg3_cos8[2], mpeg3_cos4[1];
27#endif
28
29mpeg3_real_t *mpeg3_pnts[] = { mpeg3_cos64, mpeg3_cos32, mpeg3_cos16, mpeg3_cos8, mpeg3_cos4 };
30
31int mpeg3_grp_3tab[32 * 3] = { 0, }; /* used: 27 */
32int mpeg3_grp_5tab[128 * 3] = { 0, }; /* used: 125 */
33int mpeg3_grp_9tab[1024 * 3] = { 0, }; /* used: 729 */
34
35 REAL_MATRIX(mpeg3_muls, [27], [64]);/* also used by layer 1 */
36REAL_MATRIX(mpeg3_gainpow2, [256 + 118 + 4], );
37REAL_MATRIX(mpeg3_ispow, [8207], );
38REAL_MATRIX(mpeg3_aa_ca, [8], );
39REAL_MATRIX(mpeg3_aa_cs, [8], );
40REAL_MATRIX(mpeg3_win, [4], [36]);
41REAL_MATRIX(mpeg3_win1, [4], [36]);
42REAL_MATRIX(mpeg3_COS1, [12], [6]);
43REAL_MATRIX(mpeg3_COS9, [9], );
44REAL_MATRIX(mpeg3_tfcos36, [9], );
45REAL_MATRIX(mpeg3_tfcos12, [3], );
46REAL_MATRIX(mpeg3_cos9, [3], );
47REAL_MATRIX(mpeg3_cos18, [3], );
48REAL_MATRIX(mpeg3_tan1_1, [16], );
49REAL_MATRIX(mpeg3_tan2_1, [16], );
50REAL_MATRIX(mpeg3_tan1_2, [16], );
51REAL_MATRIX(mpeg3_tan2_2, [16], );
52REAL_MATRIX(mpeg3_pow1_1, [2], [16]);
53REAL_MATRIX(mpeg3_pow2_1, [2], [16]);
54REAL_MATRIX(mpeg3_pow1_2, [2], [16]);
55REAL_MATRIX(mpeg3_pow2_2, [2], [16]);
56
57mpeg3_real_t mpeg3_COS6_1, mpeg3_COS6_2;
58
59#ifdef PRINT_FIXED_POINT_TABLES
60static void print_table(const char* var, mpeg3_real_t* data, int count)
61{
62 int i;
63 printf("#ifdef USE_DATA_TABLES\n");
64 printf("static long %s_data[] = {",var);
65 for(i = 0; i < count; i++) {
66 printf("%c0x%08x,", i%8?' ':'\n', data[i].fixedPoint());
67 }
68 printf("};\n");
69 printf("#endif\n");
70}
71#endif
72
73#ifdef PRINT_FIXED_POINT_TABLES
74# define DO_TABLE(T) print_table(#T, T, sizeof(T)/sizeof(mpeg3_real_t))
75# define DO_TABLE2(T,DIM) print_table(#T, (mpeg3_real_t*)T, sizeof(T)/sizeof(mpeg3_real_t))
76#elif USE_FIXED_POINT
77# define DO_TABLE(T) T = (mpeg3_real_t*)T##_data
78 // multidimensional
79# define DO_TABLE2(T,DIM) T = (mpeg3_real_t(*)DIM)T##_data
80#else
81# define DO_TABLE(T)
82# define DO_TABLE2(T,DIM)
83#endif
84
85#if defined(USE_FIXED_POINT) && !defined(PRINT_FIXED_POINT_TABLES)
86#define USE_DATA_TABLES
87#include "fptables.h"
88#endif
89
90long mpeg3_intwinbase[] = {
91 0, -1, -1, -1, -1, -1, -1, -2, -2, -2,
92 -2, -3, -3, -4, -4, -5, -5, -6, -7, -7,
93 -8, -9, -10, -11, -13, -14, -16, -17, -19, -21,
94 -24, -26, -29, -31, -35, -38, -41, -45, -49, -53,
95 -58, -63, -68, -73, -79, -85, -91, -97, -104, -111,
96 -117, -125, -132, -139, -147, -154, -161, -169, -176, -183,
97 -190, -196, -202, -208, -213, -218, -222, -225, -227, -228,
98 -228, -227, -224, -221, -215, -208, -200, -189, -177, -163,
99 -146, -127, -106, -83, -57, -29, 2, 36, 72, 111,
100 153, 197, 244, 294, 347, 401, 459, 519, 581, 645,
101 711, 779, 848, 919, 991, 1064, 1137, 1210, 1283, 1356,
102 1428, 1498, 1567, 1634, 1698, 1759, 1817, 1870, 1919, 1962,
103 2001, 2032, 2057, 2075, 2085, 2087, 2080, 2063, 2037, 2000,
104 1952, 1893, 1822, 1739, 1644, 1535, 1414, 1280, 1131, 970,
105 794, 605, 402, 185, -45, -288, -545, -814, -1095, -1388,
106 -1692, -2006, -2330, -2663, -3004, -3351, -3705, -4063, -4425, -4788,
107 -5153, -5517, -5879, -6237, -6589, -6935, -7271, -7597, -7910, -8209,
108 -8491, -8755, -8998, -9219, -9416, -9585, -9727, -9838, -9916, -9959,
109 -9966, -9935, -9863, -9750, -9592, -9389, -9139, -8840, -8492, -8092,
110 -7640, -7134, -6574, -5959, -5288, -4561, -3776, -2935, -2037, -1082,
111 -70, 998, 2122, 3300, 4533, 5818, 7154, 8540, 9975, 11455,
112 12980, 14548, 16155, 17799, 19478, 21189, 22929, 24694, 26482, 28289,
113 30112, 31947, 33791, 35640, 37489, 39336, 41176, 43006, 44821, 46617,
114 48390, 50137, 51853, 53534, 55178, 56778, 58333, 59838, 61289, 62684,
115 64019, 65290, 66494, 67629, 68692, 69679, 70590, 71420, 72169, 72835,
116 73415, 73908, 74313, 74630, 74856, 74992, 75038 };
117
118int mpeg3_longLimit[9][23];
119int mpeg3_shortLimit[9][14];
120
121struct mpeg3_bandInfoStruct mpeg3_bandInfo[9] =
122{
123
124/* MPEG 1.0 */
125 { {0,4,8,12,16,20,24,30,36,44,52,62,74, 90,110,134,162,196,238,288,342,418,576},
126 {4,4,4,4,4,4,6,6,8, 8,10,12,16,20,24,28,34,42,50,54, 76,158},
127 {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},
128 {4,4,4,4,6,8,10,12,14,18,22,30,56} } ,
129
130 { {0,4,8,12,16,20,24,30,36,42,50,60,72, 88,106,128,156,190,230,276,330,384,576},
131 {4,4,4,4,4,4,6,6,6, 8,10,12,16,18,22,28,34,40,46,54, 54,192},
132 {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},
133 {4,4,4,4,6,6,10,12,14,16,20,26,66} } ,
134
135 { {0,4,8,12,16,20,24,30,36,44,54,66,82,102,126,156,194,240,296,364,448,550,576} ,
136 {4,4,4,4,4,4,6,6,8,10,12,16,20,24,30,38,46,56,68,84,102, 26} ,
137 {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} ,
138 {4,4,4,4,6,8,12,16,20,26,34,42,12} } ,
139
140/* MPEG 2.0 */
141 { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576},
142 {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 } ,
143 {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} ,
144 {4,4,4,6,6,8,10,14,18,26,32,42,18 } } ,
145
146 { {0,6,12,18,24,30,36,44,54,66,80,96,114,136,162,194,232,278,330,394,464,540,576},
147 {6,6,6,6,6,6,8,10,12,14,16,18,22,26,32,38,46,52,64,70,76,36 } ,
148 {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} ,
149 {4,4,4,6,8,10,12,14,18,24,32,44,12 } } ,
150
151 { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576},
152 {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 },
153 {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},
154 {4,4,4,6,8,10,12,14,18,24,30,40,18 } } ,
155/* MPEG 2.5 */
156 { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576} ,
157 {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54},
158 {0,12,24,36,54,78,108,144,186,240,312,402,522,576},
159 {4,4,4,6,8,10,12,14,18,24,30,40,18} },
160 { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576} ,
161 {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54},
162 {0,12,24,36,54,78,108,144,186,240,312,402,522,576},
163 {4,4,4,6,8,10,12,14,18,24,30,40,18} },
164 { {0,12,24,36,48,60,72,88,108,132,160,192,232,280,336,400,476,566,568,570,572,574,576},
165 {12,12,12,12,12,12,16,20,24,28,32,40,48,56,64,76,90,2,2,2,2,2},
166 {0, 24, 48, 72,108,156,216,288,372,480,486,492,498,576},
167 {8,8,8,12,16,20,24,28,36,2,2,2,26} } ,
168};
169
170int mpeg3_mapbuf0[9][152];
171int mpeg3_mapbuf1[9][156];
172int mpeg3_mapbuf2[9][44];
173int *mpeg3_map[9][3];
174int *mpeg3_mapend[9][3];
175
176unsigned int mpeg3_n_slen2[512]; /* MPEG 2.0 slen for 'normal' mode */
177unsigned int mpeg3_i_slen2[256]; /* MPEG 2.0 slen for intensity stereo */
178
179int mpeg3audio_init_layer3(mpeg3audio_t *audio);
180
181int mpeg3audio_init_layer2(mpeg3audio_t *audio)
182{
183 static double mulmul[27] =
184 {
185 0.0 , -2.0/3.0 , 2.0/3.0 ,
186 2.0/7.0 , 2.0/15.0 , 2.0/31.0, 2.0/63.0 , 2.0/127.0 , 2.0/255.0 ,
187 2.0/511.0 , 2.0/1023.0 , 2.0/2047.0 , 2.0/4095.0 , 2.0/8191.0 ,
188 2.0/16383.0 , 2.0/32767.0 , 2.0/65535.0 ,
189 -4.0/5.0 , -2.0/5.0 , 2.0/5.0, 4.0/5.0 ,
190 -8.0/9.0 , -4.0/9.0 , -2.0/9.0 , 2.0/9.0 , 4.0/9.0 , 8.0/9.0
191 };
192 static int base[3][9] =
193 {
194 { 1 , 0, 2 , } ,
195 { 17, 18, 0 , 19, 20 , } ,
196 { 21, 1, 22, 23, 0, 24, 25, 2, 26 }
197 };
198 static int tablen[3] = { 3, 5, 9 };
199 static int *itable, *tables[3] = {mpeg3_grp_3tab, mpeg3_grp_5tab, mpeg3_grp_9tab};
200 int i, j, k, l, len;
201 mpeg3_real_t *table;
202
203 for(i = 0; i < 3; i++)
204 {
205 itable = tables[i];
206 len = tablen[i];
207 for(j = 0; j < len; j++)
208 for(k = 0; k < len; k++)
209 for(l = 0; l < len; l++)
210 {
211 *itable++ = base[i][l];
212 *itable++ = base[i][k];
213 *itable++ = base[i][j];
214 }
215 }
216
217#if !defined(USE_FIXED_POINT) || defined(PRINT_FIXED_POINT_TABLES)
218#if defined(PRINT_FIXED_POINT_TABLES)
219 //mpeg3audio_init_layer3(audio); // we depend on mpeg3_muls table
220#endif
221 for(k = 0; k < 27; k++)
222 {
223 double m = mulmul[k];
224 table = mpeg3_muls[k];
225 for(j = 3, i = 0; i < 63; i++, j--)
226 *table++ = m * pow(2.0, (double)j / 3.0);
227 *table++ = 0.0;
228 }
229#endif
230 DO_TABLE2(mpeg3_muls,[64]);
231 return 0;
232}
233
234int mpeg3audio_init_layer3(mpeg3audio_t *audio)
235{
236 int i, j, k, l;
237 int down_sample_sblimit = 32;
238
239 audio->mp3_block[0][0][0] = 0;
240 audio->mp3_blc[0] = 0;
241 audio->mp3_blc[1] = 0;
242
243#if !defined(USE_FIXED_POINT) || defined(PRINT_FIXED_POINT_TABLES)
244 for(i = -256; i < 118 + 4; i++)
245 mpeg3_gainpow2[i + 256] = pow((double)2.0, -0.25 * (double)(i + 210));
246
247 for(i = 0; i < 8207; i++)
248 mpeg3_ispow[i] = pow((double)i, (double)4.0 / 3.0);
249
250 for(i = 0; i < 8; i++)
251 {
252 static double Ci[8] = {-0.6,-0.535,-0.33,-0.185,-0.095,-0.041,-0.0142,-0.0037};
253 double sq = sqrt(1.0+Ci[i]*Ci[i]);
254 mpeg3_aa_cs[i] = 1.0/sq;
255 mpeg3_aa_ca[i] = Ci[i]/sq;
256 }
257
258 for(i = 0; i < 18; i++)
259 {
260 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);
261 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);
262 }
263 for(i = 0; i < 6; i++)
264 {
265 mpeg3_win[1][i + 18] = 0.5 / cos ( M_PI * (double) (2*(i+18)+19) / 72.0 );
266 mpeg3_win[3][i + 12] = 0.5 / cos ( M_PI * (double) (2*(i+12)+19) / 72.0 );
267 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 );
268 mpeg3_win[1][i + 30] = mpeg3_win[3][i] = 0.0;
269 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 );
270 }
271
272 for(i = 0; i < 9; i++)
273 mpeg3_COS9[i] = cos(M_PI / 18.0 * (double)i);
274
275 for(i = 0; i < 9; i++)
276 mpeg3_tfcos36[i] = 0.5 / cos (M_PI * (double) (i*2+1) / 36.0);
277 for(i = 0; i < 3; i++)
278 mpeg3_tfcos12[i] = 0.5 / cos (M_PI * (double) (i*2+1) / 12.0);
279
280 mpeg3_cos9[0] = cos(1.0 * M_PI / 9.0);
281 mpeg3_cos9[1] = cos(5.0 * M_PI / 9.0);
282 mpeg3_cos9[2] = cos(7.0 * M_PI / 9.0);
283 mpeg3_cos18[0] = cos(1.0 * M_PI / 18.0);
284 mpeg3_cos18[1] = cos(11.0 * M_PI / 18.0);
285 mpeg3_cos18[2] = cos(13.0 * M_PI / 18.0);
286
287 for(i = 0; i < 12; i++)
288 {
289 mpeg3_win[2][i] = 0.5 * sin(M_PI / 24.0 * (double) (2 * i + 1)) / cos(M_PI * (double)(2 * i + 7) / 24.0);
290 for(j = 0; j < 6; j++)
291 mpeg3_COS1[i][j] = cos(M_PI / 24.0 * (double) ((2 * i + 7) * (2 * j + 1)));
292 }
293
294 for(j = 0; j < 4; j++)
295 {
296 static int len[4] = {36, 36, 12, 36};
297 for(i = 0; i < len[j]; i += 2)
298 mpeg3_win1[j][i] = + mpeg3_win[j][i];
299 for(i = 1; i < len[j]; i += 2)
300 mpeg3_win1[j][i] = - mpeg3_win[j][i];
301 }
302
303 for(i = 0; i < 16; i++)
304 {
305 double t = tan( (double) i * M_PI / 12.0 );
306 mpeg3_tan1_1[i] = t / (1.0 + t);
307 mpeg3_tan2_1[i] = 1.0 / (1.0 + t);
308 mpeg3_tan1_2[i] = M_SQRT2 * t / (1.0 + t);
309 mpeg3_tan2_2[i] = M_SQRT2 / (1.0 + t);
310
311 for(j = 0; j < 2; j++)
312 {
313 double base = pow(2.0, -0.25 * (j + 1.0));
314 double p1 = 1.0,p2 = 1.0;
315 if(i > 0)
316 {
317 if( i & 1 )
318 p1 = pow(base, (i + 1.0) * 0.5);
319 else
320 p2 = pow(base, i * 0.5);
321 }
322 mpeg3_pow1_1[j][i] = p1;
323 mpeg3_pow2_1[j][i] = p2;
324 mpeg3_pow1_2[j][i] = M_SQRT2 * p1;
325 mpeg3_pow2_2[j][i] = M_SQRT2 * p2;
326 }
327 }
328
329#endif
330
331 DO_TABLE(mpeg3_gainpow2);
332 DO_TABLE(mpeg3_ispow);
333 DO_TABLE(mpeg3_aa_cs);
334 DO_TABLE(mpeg3_aa_ca);
335 DO_TABLE2(mpeg3_win,[36]);
336 DO_TABLE(mpeg3_COS9);
337 DO_TABLE(mpeg3_tfcos36);
338 DO_TABLE(mpeg3_tfcos12);
339 DO_TABLE(mpeg3_cos9);
340 DO_TABLE(mpeg3_cos18);
341 DO_TABLE2(mpeg3_COS1,[6]);
342 DO_TABLE2(mpeg3_win1,[36]);
343 DO_TABLE(mpeg3_tan1_1);
344 DO_TABLE(mpeg3_tan2_1);
345 DO_TABLE(mpeg3_tan1_2);
346 DO_TABLE(mpeg3_tan2_2);
347 DO_TABLE2(mpeg3_pow1_1,[16]);
348 DO_TABLE2(mpeg3_pow2_1,[16]);
349 DO_TABLE2(mpeg3_pow1_2,[16]);
350 DO_TABLE2(mpeg3_pow2_2,[16]);
351
352 mpeg3_COS6_1 = cos( M_PI / 6.0 * (double) 1);
353 mpeg3_COS6_2 = cos( M_PI / 6.0 * (double) 2);
354
355 for(j = 0; j < 9; j++)
356 {
357 struct mpeg3_bandInfoStruct *bi = &mpeg3_bandInfo[j];
358 int *mp;
359 int cb,lwin;
360 int *bdf;
361
362 mp = mpeg3_map[j][0] = mpeg3_mapbuf0[j];
363 bdf = bi->longDiff;
364 for(i = 0, cb = 0; cb < 8; cb++, i += *bdf++)
365 {
366 *mp++ = (*bdf) >> 1;
367 *mp++ = i;
368 *mp++ = 3;
369 *mp++ = cb;
370 }
371 bdf = bi->shortDiff + 3;
372 for(cb = 3; cb < 13; cb++)
373 {
374 int l = (*bdf++) >> 1;
375 for(lwin = 0; lwin < 3; lwin++)
376 {
377 *mp++ = l;
378 *mp++ = i + lwin;
379 *mp++ = lwin;
380 *mp++ = cb;
381 }
382 i += 6 * l;
383 }
384 mpeg3_mapend[j][0] = mp;
385
386 mp = mpeg3_map[j][1] = mpeg3_mapbuf1[j];
387 bdf = bi->shortDiff+0;
388 for(i = 0,cb = 0; cb < 13; cb++)
389 {
390 int l = (*bdf++) >> 1;
391 for(lwin = 0; lwin < 3; lwin++)
392 {
393 *mp++ = l;
394 *mp++ = i + lwin;
395 *mp++ = lwin;
396 *mp++ = cb;
397 }
398 i += 6 * l;
399 }
400 mpeg3_mapend[j][1] = mp;
401
402 mp = mpeg3_map[j][2] = mpeg3_mapbuf2[j];
403 bdf = bi->longDiff;
404 for(cb = 0; cb < 22 ; cb++)
405 {
406 *mp++ = (*bdf++) >> 1;
407 *mp++ = cb;
408 }
409 mpeg3_mapend[j][2] = mp;
410 }
411
412 for(j = 0; j < 9; j++)
413 {
414 for(i = 0; i < 23; i++)
415 {
416 mpeg3_longLimit[j][i] = (mpeg3_bandInfo[j].longIdx[i] - 1 + 8) / 18 + 1;
417 if(mpeg3_longLimit[j][i] > (down_sample_sblimit))
418 mpeg3_longLimit[j][i] = down_sample_sblimit;
419 }
420 for(i = 0; i < 14; i++)
421 {
422 mpeg3_shortLimit[j][i] = (mpeg3_bandInfo[j].shortIdx[i] - 1) / 18 + 1;
423 if(mpeg3_shortLimit[j][i] > (down_sample_sblimit) )
424 mpeg3_shortLimit[j][i] = down_sample_sblimit;
425 }
426 }
427
428 for(i = 0; i < 5; i++)
429 {
430 for(j = 0; j < 6; j++)
431 {
432 for(k = 0; k < 6; k++)
433 {
434 int n = k + j * 6 + i * 36;
435 mpeg3_i_slen2[n] = i | (j << 3) | (k << 6) | (3 << 12);
436 }
437 }
438 }
439 for(i = 0; i < 4; i++)
440 {
441 for(j = 0; j < 4; j++)
442 {
443 for(k = 0; k < 4; k++)
444 {
445 int n = k + j * 4 + i * 16;
446 mpeg3_i_slen2[n+180] = i | (j << 3) | (k << 6) | (4 << 12);
447 }
448 }
449 }
450 for(i = 0; i < 4; i++)
451 {
452 for(j = 0; j < 3; j++)
453 {
454 int n = j + i * 3;
455 mpeg3_i_slen2[n + 244] = i | (j << 3) | (5 << 12);
456 mpeg3_n_slen2[n + 500] = i | (j << 3) | (2 << 12) | (1 << 15);
457 }
458 }
459
460 for(i = 0; i < 5; i++)
461 {
462 for(j = 0; j < 5; j++)
463 {
464 for(k = 0; k < 4; k++)
465 {
466 for(l = 0; l < 4; l++)
467 {
468 int n = l + k * 4 + j * 16 + i * 80;
469 mpeg3_n_slen2[n] = i | (j << 3) | ( k << 6) | (l << 9) | (0 << 12);
470 }
471 }
472 }
473 }
474 for(i = 0; i < 5; i++)
475 {
476 for(j = 0; j < 5; j++)
477 {
478 for(k = 0; k < 4; k++)
479 {
480 int n = k + j * 4 + i * 20;
481 mpeg3_n_slen2[n + 400] = i | (j << 3) | (k << 6) | (1 << 12);
482 }
483 }
484 }
485
486 return 0;
487}
488
489int mpeg3audio_new_decode_tables(mpeg3audio_t *audio)
490{
491 int i, j, k, kr, divv;
492 mpeg3_real_t *costab;
493 int idx;
494 long scaleval = audio->outscale;
495
496
497 for(i = 0; i < 5; i++)
498 {
499 kr = 0x10 >> i;
500 divv = 0x40 >> i;
501 costab = mpeg3_pnts[i];
502 for(k = 0; k < kr; k++)
503 costab[k] = 1.0 / (2.0 * cos(M_PI * ((double)k * 2.0 + 1.0) / (double)divv));
504
505#ifdef USE_3DNOW
506 for(k = 0; k < kr; k++)
507 costab[k + kr] = -costab[k];
508#endif
509
510 }
511
512 idx = 0;
513 scaleval = -scaleval;
514 for(i = 0, j = 0; i < 256; i++, j++,idx += 32)
515 {
516 if(idx < 512 + 16)
517 mpeg3_decwin[idx+16] = mpeg3_decwin[idx] = (double)mpeg3_intwinbase[j] / 65536.0 * (double)scaleval;
518
519 if(i % 32 == 31)
520 idx -= 1023;
521 if(i % 64 == 63)
522 scaleval = -scaleval;
523 }
524
525 for( ; i < 512; i++, j--, idx += 32)
526 {
527 if(idx < 512 + 16)
528 mpeg3_decwin[idx + 16] = mpeg3_decwin[idx] = (double)mpeg3_intwinbase[j] / 65536.0 * (double)scaleval;
529
530 if(i % 32 == 31)
531 idx -= 1023;
532 if(i % 64 == 63)
533 scaleval = -scaleval;
534 }
535
536#ifdef USE_3DNOW
537 if(!param.down_sample)
538 {
539 for(i = 0; i < 512 + 32; i++)
540 {
541 mpeg3_decwin[512 + 31 - i] *= 65536.0; /* allows faster clipping in 3dnow code */
542 mpeg3_decwin[512 + 32 + i] = mpeg3_decwin[512 + 31 - i];
543 }
544 }
545#endif
546
547/* Initialize AC3 */
548 audio->ac3_lfsr_state = 1;
549 mpeg3audio_imdct_init(audio);
550/* Initialize MPEG */
551 mpeg3audio_init_layer2(audio); /* inits also shared tables with layer1 */
552 mpeg3audio_init_layer3(audio);
553 return 0;
554}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef TABLES_H
21#define TABLES_H
22
23extern int mpeg3_tabsel_123[2][3][16];
24
25extern long mpeg3_freqs[9];
26
27struct mpeg3_bandInfoStruct
28{
29 int longIdx[23];
30 int longDiff[22];
31 int shortIdx[14];
32 int shortDiff[13];
33};
34
35
36extern mpeg3_real_t mpeg3_decwin[512 + 32];
37extern mpeg3_real_t mpeg3_cos64[16], mpeg3_cos32[8], mpeg3_cos16[4], mpeg3_cos8[2], mpeg3_cos4[1];
38
39extern mpeg3_real_t *mpeg3_pnts[5];
40
41extern int mpeg3_grp_3tab[32 * 3]; /* used: 27 */
42extern int mpeg3_grp_5tab[128 * 3]; /* used: 125 */
43extern int mpeg3_grp_9tab[1024 * 3]; /* used: 729 */
44extern long mpeg3_intwinbase[257];
45extern mpeg3_real_t mpeg3_COS6_1, mpeg3_COS6_2;
46
47#if defined(USE_FIXED_POINT) && !defined(PRINT_FIXED_POINT_TABLES)
48# define REAL_MATRIX(var,dim1,dimn) mpeg3_real_t (*var)dimn
49#else
50# define REAL_MATRIX(var,dim1,dimn) mpeg3_real_t var dim1 dimn
51#endif
52 extern REAL_MATRIX(mpeg3_muls, [27], [64]);/* also used by layer 1 */
53extern REAL_MATRIX(mpeg3_gainpow2, [256 + 118 + 4], );
54extern REAL_MATRIX(mpeg3_ispow, [8207], );
55extern REAL_MATRIX(mpeg3_aa_ca, [8], );
56extern REAL_MATRIX(mpeg3_aa_cs, [8], );
57extern REAL_MATRIX(mpeg3_win, [4], [36]);
58extern REAL_MATRIX(mpeg3_win1, [4], [36]);
59extern REAL_MATRIX(mpeg3_COS1, [12], [6]);
60extern REAL_MATRIX(mpeg3_COS9, [9], );
61extern REAL_MATRIX(mpeg3_tfcos36, [9], );
62extern REAL_MATRIX(mpeg3_tfcos12, [3], );
63extern REAL_MATRIX(mpeg3_cos9, [3], );
64extern REAL_MATRIX(mpeg3_cos18, [3], );
65extern REAL_MATRIX(mpeg3_tan1_1, [16], );
66extern REAL_MATRIX(mpeg3_tan2_1, [16], );
67extern REAL_MATRIX(mpeg3_tan1_2, [16], );
68extern REAL_MATRIX(mpeg3_tan2_2, [16], );
69extern REAL_MATRIX(mpeg3_pow1_1, [2], [16]);
70extern REAL_MATRIX(mpeg3_pow2_1, [2], [16]);
71extern REAL_MATRIX(mpeg3_pow1_2, [2], [16]);
72extern REAL_MATRIX(mpeg3_pow2_2, [2], [16]);
73
74extern int mpeg3_longLimit[9][23];
75extern int mpeg3_shortLimit[9][14];
76
77extern struct mpeg3_bandInfoStruct mpeg3_bandInfo[9];
78
79extern int mpeg3_mapbuf0[9][152];
80extern int mpeg3_mapbuf1[9][156];
81extern int mpeg3_mapbuf2[9][44];
82extern int *mpeg3_map[9][3];
83extern int *mpeg3_mapend[9][3];
84
85extern unsigned int mpeg3_n_slen2[512]; /* MPEG 2.0 slen for 'normal' mode */
86extern unsigned int mpeg3_i_slen2[256]; /* MPEG 2.0 slen for intensity stereo */
87
88#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 @@
1/*
2 *
3 *uncouple.c Copyright (C) Aaron Holtzman - May 1999
4 *
5 * This file is part of libmpeg3
6 *
7 * libmpeg3 is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
10 * any later version.
11 *
12 * libmpeg3 is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Make; see the file COPYING. If not, write to
19 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 */
22
23#include "../bitstream.h"
24#include "mpeg3audio.h"
25
26static unsigned char mpeg3_first_bit_lut[256] =
27{
28 0, 8, 7, 7, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5,
29 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
30 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
31 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
32 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
33 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
34 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
35 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
36 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
37 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
38 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
39 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
40 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
41 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
42 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
43 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
44};
45
46/* Converts an unsigned exponent in the range of 0-24 and a 16 bit mantissa
47 * to an IEEE single precision floating point value */
48static inline void mpeg3audio_ac3_convert_to_float(unsigned short exp,
49 unsigned short mantissa,
50 unsigned MPEG3_INT32 *dest)
51{
52 int num;
53 short exponent;
54 int i;
55
56/* If the mantissa is zero we can simply return zero */
57 if(mantissa == 0)
58 {
59 *dest = 0;
60 return;
61 }
62
63/* Exponent is offset by 127 in IEEE format minus the shift to
64 * align the mantissa to 1.f (subtracted in the final result) */
65 exponent = 127 - exp;
66
67/* Take care of the one asymmetric negative number */
68 if(mantissa == 0x8000)
69 mantissa++;
70
71/* Extract the sign bit, invert the mantissa if it's negative, and
72 shift out the sign bit */
73 if(mantissa & 0x8000)
74 {
75 mantissa *= -1;
76 num = 0x80000000 + (exponent << 23);
77 }
78 else
79 {
80 mantissa *= 1;
81 num = exponent << 23;
82 }
83
84/* Find the index of the most significant one bit */
85 i = mpeg3_first_bit_lut[mantissa >> 8];
86
87 if(i == 0)
88 i = mpeg3_first_bit_lut[mantissa & 0xff] + 8;
89
90 *dest = num - (i << 23) + (mantissa << (7 + i));
91 return;
92}
93
94
95int mpeg3audio_ac3_uncouple(mpeg3audio_t *audio,
96 mpeg3_ac3bsi_t *bsi,
97 mpeg3_ac3audblk_t *audblk,
98 mpeg3_stream_coeffs_t *coeffs)
99{
100 int i, j;
101
102 for(i = 0; i < bsi->nfchans; i++)
103 {
104 for(j = 0; j < audblk->endmant[i]; j++)
105 mpeg3audio_ac3_convert_to_float(audblk->fbw_exp[i][j],
106 audblk->chmant[i][j],
107 (unsigned MPEG3_INT32*)&coeffs->fbw[i][j]);
108 }
109
110 if(audblk->cplinu)
111 {
112 for(i = 0; i < bsi->nfchans; i++)
113 {
114 if(audblk->chincpl[i])
115 {
116 mpeg3audio_ac3_uncouple_channel(audio,
117 coeffs,
118 audblk,
119 i);
120 }
121 }
122
123 }
124
125 if(bsi->lfeon)
126 {
127/* There are always 7 mantissas for lfe */
128 for(j = 0; j < 7 ; j++)
129 mpeg3audio_ac3_convert_to_float(audblk->lfe_exp[j],
130 audblk->lfemant[j],
131 (unsigned MPEG3_INT32*)&coeffs->lfe[j]);
132
133 }
134 return 0;
135}
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 @@
1#include "mpeg3private.h"
2#include "mpeg3protos.h"
3
4#include <stdlib.h>
5
6mpeg3_bits_t* mpeg3bits_new_stream(mpeg3_t *file, mpeg3_demuxer_t *demuxer)
7{
8 mpeg3_bits_t *stream = (mpeg3_bits_t*)malloc(sizeof(mpeg3_bits_t));
9 stream->bfr = 0;
10 stream->bfr_size = 0;
11 stream->bit_number = 0;
12 stream->file = file;
13 stream->demuxer = demuxer;
14 stream->input_ptr = 0;
15 return stream;
16}
17
18int mpeg3bits_delete_stream(mpeg3_bits_t* stream)
19{
20 free(stream);
21 return 0;
22}
23
24
25/* Fill a buffer. Only works if bit_number is on an 8 bit boundary */
26int mpeg3bits_read_buffer(mpeg3_bits_t* stream, unsigned char *buffer, int bytes)
27{
28 int result, i = 0;
29 while(stream->bit_number > 0)
30 {
31 stream->bit_number -= 8;
32 mpeg3demux_read_prev_char(stream->demuxer);
33 }
34
35 stream->bit_number = 0;
36 stream->bfr_size = 0;
37 stream->bfr = 0;
38 result = mpeg3demux_read_data(stream->demuxer, buffer, bytes);
39 return result;
40}
41
42/* For mp3 decompression use a pointer in a buffer for getbits. */
43int mpeg3bits_use_ptr(mpeg3_bits_t* stream, unsigned char *buffer)
44{
45 stream->bfr_size = stream->bit_number = 0;
46 stream->bfr = 0;
47 stream->input_ptr = buffer;
48 return 0;
49}
50
51/* Go back to using the demuxer for getbits in mp3. */
52int mpeg3bits_use_demuxer(mpeg3_bits_t* stream)
53{
54 if(stream->input_ptr)
55 {
56 stream->bfr_size = stream->bit_number = 0;
57 stream->input_ptr = 0;
58 stream->bfr = 0;
59 }
60
61 return 0;
62}
63
64/* Reconfigure for reverse operation */
65/* Default is forward operation */
66void mpeg3bits_start_reverse(mpeg3_bits_t* stream)
67{
68 int i;
69 for(i = 0; i < stream->bfr_size; i += 8)
70 if(stream->input_ptr)
71 stream->input_ptr--;
72 else
73 mpeg3demux_read_prev_char(stream->demuxer);
74}
75
76/* Reconfigure for forward operation */
77void mpeg3bits_start_forward(mpeg3_bits_t* stream)
78{
79 int i;
80 for(i = 0; i < stream->bfr_size; i += 8)
81 if(stream->input_ptr)
82 stream->input_ptr++;
83 else
84 mpeg3demux_read_char(stream->demuxer);
85}
86
87/* Erase the buffer with the next 4 bytes in the file. */
88int mpeg3bits_refill(mpeg3_bits_t* stream)
89{
90 stream->bit_number = 32;
91 stream->bfr_size = 32;
92
93 if(stream->input_ptr)
94 {
95 stream->bfr = (unsigned int)(*stream->input_ptr++) << 24;
96 stream->bfr |= (unsigned int)(*stream->input_ptr++) << 16;
97 stream->bfr |= (unsigned int)(*stream->input_ptr++) << 8;
98 stream->bfr |= *stream->input_ptr++;
99 }
100 else
101 {
102 stream->bfr = mpeg3demux_read_char(stream->demuxer) << 24;
103 stream->bfr |= mpeg3demux_read_char(stream->demuxer) << 16;
104 stream->bfr |= mpeg3demux_read_char(stream->demuxer) << 8;
105 stream->bfr |= mpeg3demux_read_char(stream->demuxer);
106 }
107 return mpeg3demux_eof(stream->demuxer);
108}
109
110/* Erase the buffer with the previous 4 bytes in the file. */
111int mpeg3bits_refill_backwards(mpeg3_bits_t* stream)
112{
113 stream->bit_number = 0;
114 stream->bfr_size = 32;
115 stream->bfr = mpeg3demux_read_prev_char(stream->demuxer);
116 stream->bfr |= (unsigned int)mpeg3demux_read_prev_char(stream->demuxer) << 8;
117 stream->bfr |= (unsigned int)mpeg3demux_read_prev_char(stream->demuxer) << 16;
118 stream->bfr |= (unsigned int)mpeg3demux_read_prev_char(stream->demuxer) << 24;
119 return mpeg3demux_eof(stream->demuxer);
120}
121
122int mpeg3bits_byte_align(mpeg3_bits_t *stream)
123{
124 stream->bit_number = (stream->bit_number + 7) & 0xf8;
125 return 0;
126}
127
128int mpeg3bits_seek_end(mpeg3_bits_t* stream)
129{
130 stream->bfr_size = stream->bit_number = 0;
131 return mpeg3demux_seek_byte(stream->demuxer, mpeg3demuxer_total_bytes(stream->demuxer));
132}
133
134int mpeg3bits_seek_start(mpeg3_bits_t* stream)
135{
136 stream->bfr_size = stream->bit_number = 0;
137 return mpeg3demux_seek_byte(stream->demuxer, 0);
138}
139
140int mpeg3bits_seek_time(mpeg3_bits_t* stream, double time_position)
141{
142 stream->bfr_size = stream->bit_number = 0;
143 return mpeg3demux_seek_time(stream->demuxer, time_position);
144}
145
146int mpeg3bits_seek_byte(mpeg3_bits_t* stream, long position)
147{
148 stream->bfr_size = stream->bit_number = 0;
149 return mpeg3demux_seek_byte(stream->demuxer, position);
150}
151
152int mpeg3bits_seek_percentage(mpeg3_bits_t* stream, double percentage)
153{
154 stream->bfr_size = stream->bit_number = 0;
155 return mpeg3demux_seek_percentage(stream->demuxer, percentage);
156}
157
158int mpeg3bits_tell(mpeg3_bits_t* stream)
159{
160 return mpeg3demux_tell(stream->demuxer);
161}
162
163int mpeg3bits_getbitoffset(mpeg3_bits_t *stream)
164{
165 return stream->bit_number & 7;
166}
167
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef BITSTREAM_H
21#define BITSTREAM_H
22
23#include "mpeg3demux.h"
24
25#if defined(__cplusplus)
26extern "C" {
27#endif
28
29// next bit in forward direction
30// next bit in reverse direction |
31// v v
32// | | | | | | | | | | | | | | | | | | | | | | | | | | |1|1|1|1|1|1| */
33// ^ ^
34// | bit_number = 1
35// bfr_size = 6
36
37typedef struct
38{
39 unsigned MPEG3_INT32 bfr; /* bfr = buffer for bits */
40 int bit_number; /* position of pointer in bfr */
41 int bfr_size; /* number of bits in bfr. Should always be a multiple of 8 */
42 struct mpeg3_rec *file; /* Mpeg2 file */
43 mpeg3_demuxer_t *demuxer; /* Mpeg2 demuxer */
44/* If the input ptr is true, data is read from it instead of the demuxer. */
45 unsigned char *input_ptr;
46} mpeg3_bits_t;
47
48LIBMPEG_EXPORT unsigned int mpeg3demux_read_char_packet(mpeg3_demuxer_t *demuxer);
49LIBMPEG_EXPORT unsigned int mpeg3demux_read_prev_char_packet(mpeg3_demuxer_t *demuxer);
50
51/* ======================================================================== */
52/* Entry Points */
53/* ======================================================================== */
54
55#define mpeg3bits_tell_percentage(stream) mpeg3demux_tell_percentage((stream)->demuxer)
56
57#define mpeg3bits_packet_time(stream) mpeg3demux_current_time((stream)->demuxer)
58
59#define mpeg3bits_time_offset(stream) mepg2demux_time_offset((stream)->demuxer)
60
61#define mpeg3bits_error(stream) mpeg3demux_error((stream)->demuxer)
62
63#define mpeg3bits_eof(stream) mpeg3demux_eof((stream)->demuxer)
64
65#define mpeg3bits_bof(stream) mpeg3demux_bof((stream)->demuxer)
66
67/* Read bytes backward from the file until the reverse_bits is full. */
68static inline void mpeg3bits_fill_reverse_bits(mpeg3_bits_t* stream, int bits)
69{
70// Right justify
71 while(stream->bit_number > 7)
72 {
73 stream->bfr >>= 8;
74 stream->bfr_size -= 8;
75 stream->bit_number -= 8;
76 }
77
78// Insert bytes before bfr_size
79 while(stream->bfr_size - stream->bit_number < bits)
80 {
81 if(stream->input_ptr)
82 stream->bfr |= (unsigned int)(*--stream->input_ptr) << stream->bfr_size;
83 else
84 stream->bfr |= (unsigned int)mpeg3demux_read_prev_char(stream->demuxer) << stream->bfr_size;
85 stream->bfr_size += 8;
86 }
87}
88
89/* Read bytes forward from the file until the forward_bits is full. */
90extern inline void mpeg3bits_fill_bits(mpeg3_bits_t* stream, int bits)
91{
92 while(stream->bit_number < bits)
93 {
94 stream->bfr <<= 8;
95 if(stream->input_ptr)
96 {
97 stream->bfr |= *stream->input_ptr++;
98 }
99 else
100 {
101 stream->bfr |= mpeg3demux_read_char(stream->demuxer);
102 }
103 stream->bit_number += 8;
104 stream->bfr_size += 8;
105 if(stream->bfr_size > 32) stream->bfr_size = 32;
106 }
107}
108
109/* Return 8 bits, advancing the file position. */
110extern inline unsigned int mpeg3bits_getbyte_noptr(mpeg3_bits_t* stream)
111{
112 if(stream->bit_number < 8)
113 {
114 stream->bfr <<= 8;
115 if(stream->input_ptr)
116 stream->bfr |= *stream->input_ptr++;
117 else
118 stream->bfr |= mpeg3demux_read_char(stream->demuxer);
119
120 stream->bfr_size += 8;
121 if(stream->bfr_size > 32) stream->bfr_size = 32;
122
123 return (stream->bfr >> stream->bit_number) & 0xff;
124 }
125 return (stream->bfr >> (stream->bit_number -= 8)) & 0xff;
126}
127
128extern inline unsigned int mpeg3bits_getbit_noptr(mpeg3_bits_t* stream)
129{
130 if(!stream->bit_number)
131 {
132 stream->bfr <<= 8;
133 stream->bfr |= mpeg3demux_read_char(stream->demuxer);
134
135 stream->bfr_size += 8;
136 if(stream->bfr_size > 32) stream->bfr_size = 32;
137
138 stream->bit_number = 7;
139
140 return (stream->bfr >> 7) & 0x1;
141 }
142 return (stream->bfr >> (--stream->bit_number)) & (0x1);
143}
144
145/* Return n number of bits, advancing the file position. */
146/* Use in place of flushbits */
147extern inline unsigned int mpeg3bits_getbits(mpeg3_bits_t* stream, int bits)
148{
149 if(bits <= 0) return 0;
150 mpeg3bits_fill_bits(stream, bits);
151 return (stream->bfr >> (stream->bit_number -= bits)) & (0xffffffff >> (32 - bits));
152}
153
154extern inline unsigned int mpeg3bits_showbits24_noptr(mpeg3_bits_t* stream)
155{
156 while(stream->bit_number < 24)
157 {
158 stream->bfr <<= 8;
159 stream->bfr |= mpeg3demux_read_char(stream->demuxer);
160 stream->bit_number += 8;
161 stream->bfr_size += 8;
162 if(stream->bfr_size > 32) stream->bfr_size = 32;
163 }
164 return (stream->bfr >> (stream->bit_number - 24)) & 0xffffff;
165}
166
167extern inline unsigned int mpeg3bits_showbits32_noptr(mpeg3_bits_t* stream)
168{
169 while(stream->bit_number < 32)
170 {
171 stream->bfr <<= 8;
172 stream->bfr |= mpeg3demux_read_char(stream->demuxer);
173 stream->bit_number += 8;
174 stream->bfr_size += 8;
175 if(stream->bfr_size > 32) stream->bfr_size = 32;
176 }
177 return stream->bfr;
178}
179
180extern inline unsigned int mpeg3bits_showbits(mpeg3_bits_t* stream, int bits)
181{
182 mpeg3bits_fill_bits(stream, bits);
183 return (stream->bfr >> (stream->bit_number - bits)) & (0xffffffff >> (32 - bits));
184}
185
186extern inline unsigned int mpeg3bits_getbits_reverse(mpeg3_bits_t* stream, int bits)
187{
188 unsigned int result;
189 mpeg3bits_fill_reverse_bits(stream, bits);
190 result = (stream->bfr >> stream->bit_number) & (0xffffffff >> (32 - bits));
191 stream->bit_number += bits;
192 return result;
193}
194
195extern inline unsigned int mpeg3bits_showbits_reverse(mpeg3_bits_t* stream, int bits)
196{
197 unsigned int result;
198 mpeg3bits_fill_reverse_bits(stream, bits);
199 result = (stream->bfr >> stream->bit_number) & (0xffffffff >> (32 - bits));
200 return result;
201}
202
203#if defined(__cplusplus)
204}
205#endif
206
207#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 @@
1case "$1" in
2 *.c) echo $CFLAGS_lessopt
3;; *) echo $CFLAGS
4esac
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 @@
1#!/bin/sh
2
3USE_MMX=1
4USE_CSS=1
5LESS_OPT=
6PLATFORM_CFLAGS="-malign-loops=2 -malign-jumps=2 -malign-functions=2 -march=i486"
7DEBUG=
8OPTIMIZE=-O2
9OPTIMIZE_less=-O
10DEFINES=
11CC=gcc
12
13for ac_option
14do
15case "$ac_option" in
16 --fixed-point)
17 CC=g++
18 DEFINES="$DEFINES -DUSE_FIXED_POINT"
19 ;;
20
21 --lessopt)
22 LESS_OPT=1
23 ;;
24
25 --no-mmx)
26 USE_MMX=0
27 ;;
28
29 --no-css)
30 USE_CSS=0
31 ;;
32
33 --debug)
34 DEBUG=-g
35 ;;
36
37 --gcc-prefix=*)
38 CROSS=${ac_option#--gcc-prefix=}
39 PLATFORM_CFLAGS=""
40 ;;
41 -h | --help | -help)
42 cat << EOF
43Options:
44 --no-mmx Compile libmpeg3 with no MMX support.
45 --no-css Compile libmpeg3 with no CSS support.
46 --fixed-point Compile libmpeg3 to use integers instead of floats.
47 --debug Compile libmpeg3 with debug support.
48EOF
49 exit 0
50 ;;
51
52 *)
53 ;;
54esac
55done
56
57
58echo "Configuring libmpeg3"
59
60cat > global_config << EOF
61# DO NOT EDIT. EDIT ./configure INSTEAD AND RERUN IT.
62EOF
63
64
65if test -z "$CFLAGS"; then
66 CF="$DEFINES $DEBUG -funroll-loops -fomit-frame-pointer $PLATFORM_CFLAGS"
67 echo >> global_config "CFLAGS = $CF $OPTIMIZE"
68 if test -z "$LESS_OPT"; then
69 echo >> global_config "CFLAGS_lessopt = $CF $OPTIMIZE_less"
70 else
71 echo >> global_config "CFLAGS_lessopt = $CF $OPTIMIZE_less"
72 fi
73fi
74
75cat >> global_config << EOF
76CC = ${CROSS}$CC
77AR = ${CROSS}ar
78NASM = nasm
79EOF
80
81if [ ${USE_CSS} = 1 ]; then
82cat >> global_config << EOF
83CFLAGS += -DHAVE_CSS
84EOF
85fi
86
87if [ ${USE_MMX} = 1 ]; then
88cat >> global_config << EOF
89CFLAGS += -DHAVE_MMX
90MMXOBJS = \
91 video/mmxidct.o \
92 video/reconmmx.o
93MMXOBJS2 = \
94 mmxidct.o \
95 reconmmx.o
96EOF
97fi
98
99
100
101
102echo "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 @@
1<TITLE>LibMPEG3</TITLE>
2
3<CENTER>
4<FONT FACE=HELVETICA SIZE=+4><B>Using LibMPEG3 to make your own MPEG applications</B></FONT><P>
5
6<TABLE>
7<TR>
8<TD>
9<CODE>
10Author: Adam Williams broadcast@earthling.net<BR>
11Homepage: heroinewarrior.com<BR>
12</CODE>
13</TD>
14</TR>
15</TABLE>
16</CENTER>
17
18<P>
19
20
21LibMPEG3 decodes the many many derivatives of MPEG standards into
22uncompressed data suitable for editing and playback.<P>
23
24libmpeg3 currently decodes:<P>
25
26<BLOCKQUOTE>MPEG-2 video<BR>
27MPEG-1 video<BR>
28mp3 audio<BR>
29mp2 audio<BR>
30ac3 audio<BR>
31MPEG-2 system streams<BR>
32MPEG-1 system streams
33</BLOCKQUOTE><P>
34
35The video output can be in many different color models and frame
36sizes. The audio output can be in twos compliment or floating
37point.<P>
38
39
40
41
42
43
44
45
46
47<FONT FACE=HELVETICA SIZE=+4><B>STEP 1: Verifying file compatibility</B></FONT><P>
48
49Programs using libmpeg3 must <CODE>#include "libmpeg3.h"</CODE>.<P>
50
51Call <CODE>mpeg3_check_sig</CODE> to verify if the file can be read by
52libmpeg3. This returns a 1 if it is compatible and 0 if it isn't.<P>
53
54
55
56
57
58
59
60
61
62
63
64<FONT FACE=HELVETICA SIZE=+4><B>STEP 2: Open the file</B></FONT><P>
65
66You need an <CODE>mpeg3_t*</CODE> file descriptor:<P>
67<CODE>
68mpeg3_t* file;
69</CODE>
70<P>
71
72Then you need to open the file:<P>
73
74<CODE>file = mpeg3_open(char *path);</CODE><P>
75
76<CODE>mpeg3_open</CODE> returns a NULL if the file couldn't be opened
77for some reason. Be sure to check this. Everything you do with
78libmpeg3 requires passing the <CODE>file</CODE> pointer.<P>
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93<FONT FACE=HELVETICA SIZE=+4><B>STEP 3: How many CPUs do you want to use?</B></FONT><P>
94
95Call <CODE>mpeg3_set_cpus(mpeg3_t *file, int cpus)</CODE> to set how
96many CPUs should be devoted to video decompression. LibMPEG3 can use
97any number. If you don't call this right after opening the file, the
98CPU number defaults to 1.<P>
99
100
101
102
103
104
105
106<FONT FACE=HELVETICA SIZE=+4><B>STEP 4: Get some information about the file.</B></FONT><P>
107
108There are a number of queries for the audio components of the stream:<P>
109
110<CODE><PRE>
111int mpeg3_has_audio(mpeg3_t *file);
112int mpeg3_total_astreams(mpeg3_t *file); // Number of multiplexed audio streams
113int mpeg3_audio_channels(mpeg3_t *file, int stream);
114int mpeg3_sample_rate(mpeg3_t *file, int stream);
115long mpeg3_audio_samples(mpeg3_t *file, int stream); // Total length
116</PRE></CODE>
117
118The audio is presented as a number of <B>streams</B> starting at 0 and
119including <CODE>mpeg3_total_astreams</CODE> - 1. Each stream contains a
120certain number of <B>channels</B> starting at 0 and including
121<CODE>mpeg3_audio_channels</CODE> - 1.
122
123The methodology is first determine if the file has audio, then get
124the number of streams in the file, then for each stream get the number
125of channels, sample rate, and length.<P>
126
127There are also queries for the video components:<P>
128
129<CODE><PRE>
130int mpeg3_has_video(mpeg3_t *file);
131int mpeg3_total_vstreams(mpeg3_t *file); // Number of multiplexed video streams
132int mpeg3_video_width(mpeg3_t *file, int stream);
133int mpeg3_video_height(mpeg3_t *file, int stream);
134float mpeg3_frame_rate(mpeg3_t *file, int stream); // Frames/sec
135long mpeg3_video_frames(mpeg3_t *file, int stream); // Total length
136</PRE></CODE>
137
138The video behavior is the same as with audio, except that video has no
139subdivision under <B>streams</B>. Frame rate is a floating point
140number of frames per second.<P>
141
142
143
144
145
146
147
148<FONT FACE=HELVETICA SIZE=+4><B>STEP 5: Seeking to a point in the file</B></FONT><P>
149
150Each audio stream and each video stream has a position in the file
151independant of each other stream. A variety of methods are available
152for specifying the position of a stream: percentage, frame, sample.
153Which method you use depends on whether you're seeking audio or video
154and whether you're seeking all tracks to a percentage of the file.<P>
155
156The preferred seeking method if you're writing a player is:<P>
157
158<CODE><PRE>
159int mpeg3_seek_percentage(mpeg3_t *file, double percentage);
160double mpeg3_tell_percentage(mpeg3_t *file);
161</PRE></CODE>
162
163This seeks all tracks to a percentage of the file length. The
164percentage is from 0 to 1.<P>
165
166The alternative is absolute seeking. The audio seeking is handled
167by:<P>
168
169<CODE><PRE>
170int mpeg3_set_sample(mpeg3_t *file, long sample, int stream); // Seek
171long mpeg3_get_sample(mpeg3_t *file, int stream); // Tell current position
172</PRE></CODE>
173
174and the video seeking is handled by:<P>
175
176<CODE><PRE>
177int mpeg3_set_frame(mpeg3_t *file, long frame, int stream); // Seek
178long mpeg3_get_frame(mpeg3_t *file, int stream); // Tell current position
179</PRE></CODE>
180
181
182You can either perform percentage seeking or absolute seeking but not
183both on the same file handle. Once you perform either method, the file
184becomes configured for that method.<P>
185
186If you're in percentage seeking mode and you want the current time
187stamp in the file you can't use mpeg3_tell_percentage because you don't
188know how many seconds the total length is. The
189<CODE>mpeg3_audio_samples</CODE> and <CODE>mpeg3_video_frames</CODE>
190commands don't work in percentage seeking. Instead use
191
192<CODE><PRE>
193double mpeg3_get_time(mpeg3_t *file);
194</PRE></CODE>
195
196which gives you the last timecode read in seconds. The MPEG standard
197specifies timecodes being placed in the streams.<P>
198
199
200
201
202
203
204
205
206
207
208
209<FONT FACE=HELVETICA SIZE=+4><B>STEP 6: Read the data</B></FONT><P>
210
211To read <B>audio</B> data use:<P>
212
213<CODE><PRE>
214int mpeg3_read_audio(mpeg3_t *file,
215 float *output_f, // Pointer to pre-allocated buffer of floats
216 short *output_i, // Pointer to pre-allocated buffer if int16's
217 int channel, // Channel to decode
218 long samples, // Number of samples to decode
219 int stream); // Stream containing the channel
220</PRE></CODE>
221
222This decodes a buffer of sequential floats or int16's for a single
223channel, depending on which *output... parameter has a nonzero
224argument. To get a floating point buffer pass a pre-allocated buffer
225to <CODE>output_f</CODE> and NULL to <CODE>output_i</CODE>. To get an
226int16 buffer pass NULL to <CODE>output_f</CODE> and a pre-allocated
227buffer to <CODE>output_i</CODE>.<P>
228
229After reading an audio buffer, the current position in the one stream
230is advanced. How then, do you read more than one channel of audio
231data? Use
232
233<CODE><PRE>
234mpeg3_reread_audio(mpeg3_t *file,
235 float *output_f, /* Pointer to pre-allocated buffer of floats */
236 short *output_i, /* Pointer to pre-allocated buffer of int16's */
237 int channel, /* Channel to decode */
238 long samples, /* Number of samples to decode */
239 int stream);
240</PRE></CODE>
241
242to read each remaining channel after the first channel.<P>
243
244To read <B>video</B> data there are two methods. RGB frames or YUV
245frames. To get an RGB frame use:<BR>
246
247<CODE><PRE>
248int mpeg3_read_frame(mpeg3_t *file,
249 unsigned char **output_rows, // Array of pointers to the start of each output row
250 int in_x, // Location in input frame to take picture
251 int in_y,
252 int in_w,
253 int in_h,
254 int out_w, // Dimensions of output_rows
255 int out_h,
256 int color_model, // One of the color model #defines given above.
257 int stream);
258</PRE></CODE>
259
260The video decoding works like a camcorder taking copy of a movie
261screen. The decoder "sees" a region of the movie screen defined by
262<CODE>in_x, in_y, in_w, in_h</CODE> and transfers it to the frame
263buffer defined by <CODE>**output_rows</CODE>. The input values must be
264within the boundaries given by <CODE>mpeg3_video_width</CODE> and
265<CODE>mpeg3_video_height</CODE>. The size of the frame buffer is
266defined by <CODE>out_w, out_h</CODE>. Although the input dimensions
267are constrained, the frame buffer can be any size.<P>
268
269<CODE>color_model</CODE> defines which RGB color model the picture
270should be decoded to and the possible values are given in
271<B>libmpeg3.h</B>. The frame buffer pointed to by
272<CODE>output_rows</CODE> must have enough memory allocated to store the
273color model you select.<P>
274
275<B>You must allocate 4 extra bytes in the last output_row.</B> This is
276scratch area for the MMX routines.<P>
277
278<CODE>mpeg3_read_frame</CODE> advances the position in the one stream by 1 frame.<P>
279
280The alternative is YUV frames:<BR>
281
282<CODE><PRE>
283int mpeg3_read_yuvframe(mpeg3_t *file,
284 char *y_output,
285 char *u_output,
286 char *v_output,
287 int in_x,
288 int in_y,
289 int in_w,
290 int in_h,
291 int stream);
292</PRE></CODE>
293
294The behavior of in_x, in_y, in_w, in_h is identical to mpeg3_read_frame
295except here you have no control over the output frame size. <B>You
296must allocate in_w * in_h for the y_output, and in_w * in_h / 4 for the
297chroma outputs.</B><P>
298
299
300
301
302
303<FONT FACE=HELVETICA SIZE=+4><B>STEP 7: Close the file</B></FONT><P>
304
305Be sure to close the file with <CODE>mpeg3_close(mpeg3_t *file)</CODE>
306when 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 @@
1#include "libmpeg3.h"
2#include <stdlib.h>
3
4#define BUFSIZE 4096
5
6int main(int argc, char *argv[])
7{
8 mpeg3_t *file;
9 int i, result = 0;
10 unsigned char *output, **output_rows;
11 float *audio_output_f;
12 short *audio_output_i;
13 long total_samples = 0;
14
15 if(argc < 2)
16 {
17 printf("Need an MPEG stream.\n");
18 exit(1);
19 }
20
21 file = mpeg3_open(argv[1]);
22 if(file)
23 {
24 fprintf(stderr, "MMX supported %d\n", file->have_mmx);
25 fprintf(stderr, "Audio streams: %d\n", mpeg3_total_astreams(file));
26 for(i = 0; i < mpeg3_total_astreams(file); i++)
27 {
28 fprintf(stderr, " Stream %d: channels %d sample rate %d total samples %ld\n",
29 i,
30 mpeg3_audio_channels(file, i),
31 mpeg3_sample_rate(file, i),
32 mpeg3_audio_samples(file, i));
33 }
34 fprintf(stderr, "Video streams: %d\n", mpeg3_total_vstreams(file));
35 for(i = 0; i < mpeg3_total_vstreams(file); i++)
36 {
37 fprintf(stderr, " Stream %d: width %d height %d frame rate %0.3f total frames %ld\n",
38 i,
39 mpeg3_video_width(file, i),
40 mpeg3_video_height(file, i),
41 mpeg3_frame_rate(file, i),
42 mpeg3_video_frames(file, i));
43 }
44fprintf(stderr,"S");
45
46 mpeg3_set_cpus(file, 1);
47fprintf(stderr,"s");
48 /* audio_output_f = malloc(BUFSIZE * sizeof(float)); */
49 audio_output_i = (short*)malloc(BUFSIZE * 2 * sizeof(short));
50fprintf(stderr,"x");
51 /* mpeg3_set_sample(file, 11229518, 0); */
52 /*result = mpeg3_read_audio(file, audio_output_f, 0, 0, BUFSIZE, 0);*/
53 for (i=0; i<100; i++) {
54fprintf(stderr,"c");
55 result = mpeg3_read_audio(file, 0, audio_output_i, 0, BUFSIZE, 0);
56fprintf(stderr,"read\n");
57 }
58 //fwrite(audio_output_i, BUFSIZE, 1, stdout);
59
60 output = (unsigned char*)malloc(mpeg3_video_width(file, 0) * mpeg3_video_height(file, 0) * 3 + 4);
61 output_rows = (unsigned char**)malloc(sizeof(unsigned char*) * mpeg3_video_height(file, 0));
62 for(i = 0; i < mpeg3_video_height(file, 0); i++)
63 output_rows[i] = &output[i * mpeg3_video_width(file, 0) * 3];
64 // mpeg3_set_frame(file, 1000, 0);
65 result = mpeg3_read_frame(file,
66 output_rows,
67 0,
68 0,
69 mpeg3_video_width(file, 0),
70 mpeg3_video_height(file, 0),
71 mpeg3_video_width(file, 0),
72 mpeg3_video_height(file, 0),
73 MPEG3_RGB888,
74 0);
75
76 mpeg3_close(file);
77 }
78 return 0;
79}
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 @@
1#include "libmpeg3.h"
2#include "mpeg3protos.h"
3
4#include <stdlib.h>
5#include <string.h>
6
7#define MAX(a, b) ((a) > (b) ? (a) : (b))
8
9mpeg3_t* mpeg3_new(char *path)
10{
11 int i;
12 mpeg3_t *file = (mpeg3_t*)calloc(1, sizeof(mpeg3_t));
13 file->cpus = 1;
14 file->fs = mpeg3_new_fs(path);
15 file->have_mmx = mpeg3_mmx_test();
16 file->demuxer = mpeg3_new_demuxer(file, 0, 0, -1);
17 return file;
18}
19
20int mpeg3_delete(mpeg3_t *file)
21{
22 int i;
23
24 for(i = 0; i < file->total_vstreams; i++)
25 mpeg3_delete_vtrack(file, file->vtrack[i]);
26
27 for(i = 0; i < file->total_astreams; i++)
28 mpeg3_delete_atrack(file, file->atrack[i]);
29
30 mpeg3_delete_fs(file->fs);
31 mpeg3_delete_demuxer(file->demuxer);
32 free(file);
33}
34
35int mpeg3_check_sig(char *path)
36{
37 mpeg3_fs_t *fs;
38 unsigned int bits;
39 char *ext;
40 int result = 0;
41
42 fs = mpeg3_new_fs(path);
43 if(mpeg3io_open_file(fs))
44 {
45/* File not found */
46 return 0;
47 }
48
49 bits = mpeg3io_read_int32(fs);
50/* Test header */
51 if(bits == MPEG3_TOC_PREFIX || bits == MPEG3_TOC_PREFIXLOWER)
52 {
53 result = 1;
54 }
55 else
56 if((((bits >> 24) & 0xff) == MPEG3_SYNC_BYTE) ||
57 (bits == MPEG3_PACK_START_CODE) ||
58 ((bits & 0xfff00000) == 0xfff00000) ||
59 (bits == MPEG3_SEQUENCE_START_CODE) ||
60 (bits == MPEG3_PICTURE_START_CODE) ||
61 (((bits & 0xffff0000) >> 16) == MPEG3_AC3_START_CODE) ||
62 ((bits >> 8) == MPEG3_ID3_PREFIX) ||
63 (bits == MPEG3_RIFF_CODE))
64 {
65 result = 1;
66
67 ext = strrchr(path, '.');
68 if(ext)
69 {
70/* Test file extension. */
71 if(strncasecmp(ext, ".mp2", 4) &&
72 strncasecmp(ext, ".mp3", 4) &&
73 strncasecmp(ext, ".m1v", 4) &&
74 strncasecmp(ext, ".m2v", 4) &&
75 strncasecmp(ext, ".m2s", 4) &&
76 strncasecmp(ext, ".mpg", 4) &&
77 strncasecmp(ext, ".vob", 4) &&
78 strncasecmp(ext, ".mpeg", 4) &&
79 strncasecmp(ext, ".ac3", 4))
80 result = 0;
81 }
82 }
83
84 mpeg3io_close_file(fs);
85 mpeg3_delete_fs(fs);
86 return result;
87}
88
89mpeg3_t* mpeg3_open_copy(char *path, mpeg3_t *old_file)
90{
91 mpeg3_t *file = 0;
92 unsigned int bits;
93 int i, done;
94
95/* Initialize the file structure */
96 file = mpeg3_new(path);
97
98/* Need to perform authentication before reading a single byte. */
99 if(mpeg3io_open_file(file->fs))
100 {
101 mpeg3_delete(file);
102 return 0;
103 }
104
105/* =============================== Create the title objects ========================= */
106 bits = mpeg3io_read_int32(file->fs);
107
108 if(bits == MPEG3_TOC_PREFIX || bits == MPEG3_TOC_PREFIXLOWER) /* TOCV */
109 {
110/* Table of contents for another file */
111 if(mpeg3_read_toc(file))
112 {
113 mpeg3_delete(file);
114 return 0;
115 }
116 mpeg3io_close_file(file->fs);
117 }
118 else
119 if(((bits >> 24) & 0xff) == MPEG3_SYNC_BYTE)
120 {
121/* Transport stream */
122 file->packet_size = MPEG3_TS_PACKET_SIZE;
123 file->is_transport_stream = 1;
124 }
125 else
126 if(bits == MPEG3_PACK_START_CODE)
127 {
128/* Program stream */
129 file->packet_size = MPEG3_DVD_PACKET_SIZE;
130 file->is_program_stream = 1;
131 }
132 else
133 if((bits & 0xfff00000) == 0xfff00000 ||
134 ((bits >> 8) == MPEG3_ID3_PREFIX) ||
135 (bits == MPEG3_RIFF_CODE))
136 {
137/* MPEG Audio only */
138 file->packet_size = MPEG3_DVD_PACKET_SIZE;
139 file->has_audio = 1;
140 file->is_audio_stream = 1;
141 }
142 else
143 if(bits == MPEG3_SEQUENCE_START_CODE ||
144 bits == MPEG3_PICTURE_START_CODE)
145 {
146/* Video only */
147 file->packet_size = MPEG3_DVD_PACKET_SIZE;
148 file->is_video_stream = 1;
149 }
150 else
151 if(((bits & 0xffff0000) >> 16) == MPEG3_AC3_START_CODE)
152 {
153/* AC3 Audio only */
154 file->packet_size = MPEG3_DVD_PACKET_SIZE;
155 file->has_audio = 1;
156 file->is_audio_stream = 1;
157 }
158 else
159 {
160/* file->packet_size = MPEG3_DVD_PACKET_SIZE; */
161/* file->is_audio_stream = 1; */
162 mpeg3_delete(file);
163 fprintf(stderr, "mpeg3_open: not an MPEG 2 stream\n");
164 return 0;
165 }
166
167/* Create title */
168/* Copy timecodes from an old demuxer */
169 if(old_file && mpeg3_get_demuxer(old_file))
170 {
171 mpeg3demux_copy_titles(file->demuxer, mpeg3_get_demuxer(old_file));
172 }
173 else
174/* Start from scratch */
175 if(!file->demuxer->total_titles)
176 {
177 mpeg3demux_create_title(file->demuxer, 0, 0);
178 }
179
180/* =============================== Get title information ========================= */
181 if(file->is_transport_stream || file->is_program_stream)
182 {
183/* Create video tracks */
184/* Video must be created before audio because audio uses the video timecode */
185/* to get its length. */
186 for(i = 0; i < MPEG3_MAX_STREAMS; i++)
187 {
188 if(file->demuxer->vstream_table[i])
189 {
190 file->vtrack[file->total_vstreams] = mpeg3_new_vtrack(file, i, file->demuxer);
191 if(file->vtrack[file->total_vstreams]) file->total_vstreams++;
192 }
193 }
194
195/* Create audio tracks */
196 for(i = 0; i < MPEG3_MAX_STREAMS; i++)
197 {
198 if(file->demuxer->astream_table[i])
199 {
200 file->atrack[file->total_astreams] = mpeg3_new_atrack(file,
201 i,
202 file->demuxer->astream_table[i],
203 file->demuxer);
204 if(file->atrack[file->total_astreams]) file->total_astreams++;
205 }
206 }
207 }
208 else
209 if(file->is_video_stream)
210 {
211/* Create video tracks */
212 file->vtrack[0] = mpeg3_new_vtrack(file, -1, file->demuxer);
213 if(file->vtrack[0]) file->total_vstreams++;
214 }
215 else
216 if(file->is_audio_stream)
217 {
218/* Create audio tracks */
219 file->atrack[0] = mpeg3_new_atrack(file, -1, AUDIO_UNKNOWN, file->demuxer);
220 if(file->atrack[0]) file->total_astreams++;
221 }
222
223 if(file->total_vstreams) file->has_video = 1;
224 if(file->total_astreams) file->has_audio = 1;
225
226 mpeg3io_close_file(file->fs);
227 return file;
228}
229
230mpeg3_t* mpeg3_open(char *path)
231{
232 return mpeg3_open_copy(path, 0);
233}
234
235int mpeg3_close(mpeg3_t *file)
236{
237/* File is closed in the same procedure it is opened in. */
238 mpeg3_delete(file);
239 return 0;
240}
241
242int mpeg3_set_cpus(mpeg3_t *file, int cpus)
243{
244 int i;
245 file->cpus = cpus;
246 for(i = 0; i < file->total_vstreams; i++)
247 mpeg3video_set_cpus(file->vtrack[i]->video, cpus);
248 return 0;
249}
250
251int mpeg3_set_mmx(mpeg3_t *file, int use_mmx)
252{
253 int i;
254 file->have_mmx = use_mmx;
255 for(i = 0; i < file->total_vstreams; i++)
256 mpeg3video_set_mmx(file->vtrack[i]->video, use_mmx);
257 return 0;
258}
259
260int mpeg3_generate_toc(FILE *output, char *path, int timecode_search, int print_streams)
261{
262 mpeg3_t *file = mpeg3_open(path);
263 mpeg3_demuxer_t *demuxer;
264 int i;
265
266 if(file)
267 {
268 fprintf(output, "TOCVERSION 2\n"
269 "PATH: %s\n", path);
270 demuxer = mpeg3_new_demuxer(file, 0, 0, -1);
271 mpeg3demux_create_title(demuxer, timecode_search, output);
272/* Just print the first title's streams */
273 if(print_streams) mpeg3demux_print_streams(demuxer, output);
274
275 fprintf(output, "SIZE: %ld\n", demuxer->titles[demuxer->current_title]->total_bytes);
276 fprintf(output, "PACKETSIZE: %ld\n", demuxer->packet_size);
277
278 mpeg3demux_print_timecodes(demuxer->titles[demuxer->current_title], output);
279
280 mpeg3_delete_demuxer(demuxer);
281 mpeg3_close(file);
282 return 0;
283 }
284 return 1;
285}
286
287int mpeg3_read_toc(mpeg3_t *file)
288{
289 char string[MPEG3_STRLEN];
290 int number1;
291
292/* Test version number */
293 file->is_program_stream = 1;
294 mpeg3io_seek(file->fs, 0);
295 fscanf(file->fs->fd, "%s %d", string, &number1);
296 if(number1 > 2 || number1 < 2) return 1;
297
298/* Read titles */
299 mpeg3demux_read_titles(file->demuxer);
300 return 0;
301}
302
303int mpeg3_has_audio(mpeg3_t *file)
304{
305 return file->has_audio;
306}
307
308int mpeg3_total_astreams(mpeg3_t *file)
309{
310 return file->total_astreams;
311}
312
313int mpeg3_audio_channels(mpeg3_t *file,
314 int stream)
315{
316 if(file->has_audio)
317 return file->atrack[stream]->channels;
318 return -1;
319}
320
321int mpeg3_sample_rate(mpeg3_t *file,
322 int stream)
323{
324 if(file->has_audio)
325 return file->atrack[stream]->sample_rate;
326 return -1;
327}
328
329long mpeg3_get_sample(mpeg3_t *file,
330 int stream)
331{
332 if(file->has_audio)
333 return file->atrack[stream]->current_position;
334 return -1;
335}
336
337int mpeg3_set_sample(mpeg3_t *file,
338 long sample,
339 int stream)
340{
341 if(file->has_audio)
342 {
343 file->atrack[stream]->current_position = sample;
344 mpeg3audio_seek_sample(file->atrack[stream]->audio, sample);
345 return 0;
346 }
347 return -1;
348}
349
350long mpeg3_audio_samples(mpeg3_t *file,
351 int stream)
352{
353 if(file->has_audio)
354 return file->atrack[stream]->total_samples;
355 return -1;
356}
357
358int mpeg3_has_video(mpeg3_t *file)
359{
360 return file->has_video;
361}
362
363int mpeg3_total_vstreams(mpeg3_t *file)
364{
365 return file->total_vstreams;
366}
367
368int mpeg3_video_width(mpeg3_t *file,
369 int stream)
370{
371 if(file->has_video)
372 return file->vtrack[stream]->width;
373 return -1;
374}
375
376int mpeg3_video_height(mpeg3_t *file,
377 int stream)
378{
379 if(file->has_video)
380 return file->vtrack[stream]->height;
381 return -1;
382}
383
384float mpeg3_frame_rate(mpeg3_t *file,
385 int stream)
386{
387 if(file->has_video)
388 return file->vtrack[stream]->frame_rate;
389 return -1;
390}
391
392long mpeg3_video_frames(mpeg3_t *file,
393 int stream)
394{
395 if(file->has_video)
396 return file->vtrack[stream]->total_frames;
397 return -1;
398}
399
400long mpeg3_get_frame(mpeg3_t *file,
401 int stream)
402{
403 if(file->has_video)
404 return file->vtrack[stream]->current_position;
405 return -1;
406}
407
408int mpeg3_set_frame(mpeg3_t *file,
409 long frame,
410 int stream)
411{
412 if(file->has_video)
413 {
414 file->vtrack[stream]->current_position = frame;
415 mpeg3video_seek_frame(file->vtrack[stream]->video, frame);
416 return 0;
417 }
418 return -1;
419}
420
421int mpeg3_seek_percentage(mpeg3_t *file, double percentage)
422{
423 int i;
424 for(i = 0; i < file->total_astreams; i++)
425 {
426 mpeg3audio_seek_percentage(file->atrack[i]->audio, percentage);
427 }
428
429 for(i = 0; i < file->total_vstreams; i++)
430 {
431 mpeg3video_seek_percentage(file->vtrack[i]->video, percentage);
432 }
433 return 0;
434}
435
436int mpeg3_previous_frame(mpeg3_t *file, int stream)
437{
438 file->last_type_read = 2;
439 file->last_stream_read = stream;
440
441 if(file->has_video)
442 return mpeg3video_previous_frame(file->vtrack[stream]->video);
443}
444
445double mpeg3_tell_percentage(mpeg3_t *file)
446{
447 double percent = 0;
448 if(file->last_type_read == 1)
449 {
450 percent = mpeg3demux_tell_percentage(file->atrack[file->last_stream_read]->demuxer);
451 }
452
453 if(file->last_type_read == 2)
454 {
455 percent = mpeg3demux_tell_percentage(file->vtrack[file->last_stream_read]->demuxer);
456 }
457 return percent;
458}
459
460double mpeg3_get_time(mpeg3_t *file)
461{
462 double atime = 0, vtime = 0;
463
464 if(file->is_transport_stream || file->is_program_stream)
465 {
466/* Timecode only available in transport stream */
467 if(file->last_type_read == 1)
468 {
469 atime = mpeg3demux_get_time(file->atrack[file->last_stream_read]->demuxer);
470 }
471 else
472 if(file->last_type_read == 2)
473 {
474 vtime = mpeg3demux_get_time(file->vtrack[file->last_stream_read]->demuxer);
475 }
476 }
477 else
478 {
479/* Use percentage and total time */
480 if(file->has_audio)
481 {
482 atime = mpeg3demux_tell_percentage(file->atrack[0]->demuxer) *
483 mpeg3_audio_samples(file, 0) / mpeg3_sample_rate(file, 0);
484 }
485
486 if(file->has_video)
487 {
488 vtime = mpeg3demux_tell_percentage(file->vtrack[0]->demuxer) *
489 mpeg3_video_frames(file, 0) / mpeg3_frame_rate(file, 0);
490 }
491 }
492
493 return MAX(atime, vtime);
494}
495
496int mpeg3_end_of_audio(mpeg3_t *file, int stream)
497{
498 int result = 0;
499 result = mpeg3demux_eof(file->atrack[stream]->demuxer);
500 return result;
501}
502
503int mpeg3_end_of_video(mpeg3_t *file, int stream)
504{
505 int result = 0;
506 result = mpeg3demux_eof(file->vtrack[stream]->demuxer);
507 return result;
508}
509
510
511int mpeg3_read_frame(mpeg3_t *file,
512 unsigned char **output_rows,
513 int in_x,
514 int in_y,
515 int in_w,
516 int in_h,
517 int out_w,
518 int out_h,
519 int color_model,
520 int stream)
521{
522 int result = -1;
523
524 if(file->has_video)
525 {
526 result = mpeg3video_read_frame(file->vtrack[stream]->video,
527 file->vtrack[stream]->current_position,
528 output_rows,
529 in_x,
530 in_y,
531 in_w,
532 in_h,
533 out_w,
534 out_h,
535 color_model);
536 file->last_type_read = 2;
537 file->last_stream_read = stream;
538 file->vtrack[stream]->current_position++;
539 }
540 return result;
541}
542
543int mpeg3_drop_frames(mpeg3_t *file, long frames, int stream)
544{
545 int result = -1;
546
547 if(file->has_video)
548 {
549 result = mpeg3video_drop_frames(file->vtrack[stream]->video,
550 frames);
551 if(frames > 0) file->vtrack[stream]->current_position += frames;
552 file->last_type_read = 2;
553 file->last_stream_read = stream;
554 }
555 return result;
556}
557
558int mpeg3_read_yuvframe(mpeg3_t *file,
559 char *y_output,
560 char *u_output,
561 char *v_output,
562 int in_x,
563 int in_y,
564 int in_w,
565 int in_h,
566 int stream)
567{
568 int result = -1;
569
570//printf("mpeg3_read_yuvframe 1 %d %d\n", mpeg3demux_tell(file->vtrack[stream]->demuxer), mpeg3demuxer_total_bytes(file->vtrack[stream]->demuxer));
571 if(file->has_video)
572 {
573 result = mpeg3video_read_yuvframe(file->vtrack[stream]->video,
574 file->vtrack[stream]->current_position,
575 y_output,
576 u_output,
577 v_output,
578 in_x,
579 in_y,
580 in_w,
581 in_h);
582 file->last_type_read = 2;
583 file->last_stream_read = stream;
584 file->vtrack[stream]->current_position++;
585 }
586//printf("mpeg3_read_yuvframe 2 %d %d\n", mpeg3demux_tell(file->vtrack[stream]->demuxer), mpeg3demuxer_total_bytes(file->vtrack[stream]->demuxer));
587 return result;
588}
589
590
591int mpeg3_read_audio(mpeg3_t *file,
592 mpeg3_real_t *output_f,
593 short *output_i, int sampleSpacing,
594 int channel,
595 long samples,
596 int stream)
597{
598 int result = -1;
599
600//printf("mpeg3_read_audio 1 %d %d\n", mpeg3demux_tell(file->atrack[stream]->demuxer), mpeg3demuxer_total_bytes(file->atrack[stream]->demuxer));
601 if(file->has_audio)
602 {
603 result = mpeg3audio_decode_audio(file->atrack[stream]->audio,
604 output_f,
605 output_i, sampleSpacing,
606 channel,
607 file->atrack[stream]->current_position,
608 samples);
609 file->last_type_read = 1;
610 file->last_stream_read = stream;
611 file->atrack[stream]->current_position += samples;
612 }
613//printf("mpeg3_read_audio 2 %d %d\n", mpeg3demux_tell(file->atrack[stream]->demuxer), mpeg3demuxer_total_bytes(file->atrack[stream]->demuxer));
614
615 return result;
616}
617
618int mpeg3_reread_audio(mpeg3_t *file,
619 mpeg3_real_t *output_f,
620 short *output_i, int sampleSpacing,
621 int channel,
622 long samples,
623 int stream)
624{
625 if(file->has_audio)
626 {
627 mpeg3_set_sample(file,
628 file->atrack[stream]->current_position - samples,
629 stream);
630 file->last_type_read = 1;
631 file->last_stream_read = stream;
632 return mpeg3_read_audio(file,
633 output_f,
634 output_i, sampleSpacing,
635 channel,
636 samples,
637 stream);
638 }
639 return -1;
640}
641
642int mpeg3_read_audio_chunk(mpeg3_t *file,
643 unsigned char *output,
644 long *size,
645 long max_size,
646 int stream)
647{
648 int result = 0;
649 if(file->has_audio)
650 {
651 result = mpeg3audio_read_raw(file->atrack[stream]->audio, output, size, max_size);
652 file->last_type_read = 1;
653 file->last_stream_read = stream;
654 }
655 return result;
656}
657
658int mpeg3_read_video_chunk(mpeg3_t *file,
659 unsigned char *output,
660 long *size,
661 long max_size,
662 int stream)
663{
664 int result = 0;
665 if(file->has_video)
666 {
667 result = mpeg3video_read_raw(file->vtrack[stream]->video, output, size, max_size);
668 file->last_type_read = 2;
669 file->last_stream_read = stream;
670 }
671 return result;
672}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef LIBMPEG3_H
21#define LIBMPEG3_H
22
23#include "mpeg3private.h"
24
25#if defined(__cplusplus)
26extern "C" {
27#endif
28
29/* Supported color models for mpeg3_read_frame */
30#define MPEG3_RGB565 2
31#define MPEG3_BGR888 0
32#define MPEG3_BGRA8888 1
33#define MPEG3_RGB888 3
34#define MPEG3_RGBA8888 4
35#define MPEG3_RGBA16161616 5
36
37/* Color models for the 601 to RGB conversion */
38/* 601 not implemented for scalar code */
39#define MPEG3_601_RGB565 11
40#define MPEG3_601_BGR888 7
41#define MPEG3_601_BGRA8888 8
42#define MPEG3_601_RGB888 9
43#define MPEG3_601_RGBA8888 10
44
45/* Check for file compatibility. Return 1 if compatible. */
46LIBMPEG_EXPORT int mpeg3_check_sig(char *path);
47
48/* Open the MPEG3 stream. */
49LIBMPEG_EXPORT mpeg3_t* mpeg3_open(char *path);
50
51/* Open the MPEG3 stream and copy the tables from an already open stream. */
52/* Eliminates the initial timecode search. */
53LIBMPEG_EXPORT mpeg3_t* mpeg3_open_copy(char *path, mpeg3_t *old_file);
54LIBMPEG_EXPORT int mpeg3_close(mpeg3_t *file);
55
56/* Performance */
57LIBMPEG_EXPORT int mpeg3_set_cpus(mpeg3_t *file, int cpus);
58LIBMPEG_EXPORT int mpeg3_set_mmx(mpeg3_t *file, int use_mmx);
59
60/* Query the MPEG3 stream about audio. */
61LIBMPEG_EXPORT int mpeg3_has_audio(mpeg3_t *file);
62LIBMPEG_EXPORT int mpeg3_total_astreams(mpeg3_t *file); /* Number of multiplexed audio streams */
63LIBMPEG_EXPORT int mpeg3_audio_channels(mpeg3_t *file, int stream);
64LIBMPEG_EXPORT int mpeg3_sample_rate(mpeg3_t *file, int stream);
65
66/* Total length obtained from the timecode. */
67/* For DVD files, this is unreliable. */
68LIBMPEG_EXPORT long mpeg3_audio_samples(mpeg3_t *file, int stream);
69LIBMPEG_EXPORT int mpeg3_set_sample(mpeg3_t *file, long sample, int stream); /* Seek to a sample */
70LIBMPEG_EXPORT long mpeg3_get_sample(mpeg3_t *file, int stream); /* Tell current position */
71
72/* Read a PCM buffer of audio from 1 channel and advance the position. */
73/* Return a 1 if error. */
74/* Stream defines the number of the multiplexed stream to read. */
75LIBMPEG_EXPORT int mpeg3_read_audio(mpeg3_t *file,
76 mpeg3_real_t *output_f, /* Pointer to pre-allocated buffer of floats */
77 short *output_i, /* Pointer to pre-allocated buffer of int16's */
78 int sampleSpacing, // how many bytes to skip over inbetween samples
79 int channel, /* Channel to decode */
80 long samples, /* Number of samples to decode */
81 int stream); /* Stream containing the channel */
82
83/* Reread the last PCM buffer from a different channel and advance the position */
84LIBMPEG_EXPORT int mpeg3_reread_audio(mpeg3_t *file,
85 mpeg3_real_t *output_f, /* Pointer to pre-allocated buffer of floats */
86 short *output_i, /* Pointer to pre-allocated buffer of int16's */
87 int sampleSpacing, // how many bytes to skip over inbetween samples
88 int channel, /* Channel to decode */
89 long samples, /* Number of samples to decode */
90 int stream); /* Stream containing the channel */
91
92/* Read the next compressed audio chunk. Store the size in size and return a */
93/* 1 if error. */
94/* Stream defines the number of the multiplexed stream to read. */
95LIBMPEG_EXPORT int mpeg3_read_audio_chunk(mpeg3_t *file,
96 unsigned char *output,
97 long *size,
98 long max_size,
99 int stream);
100
101/* Query the stream about video. */
102LIBMPEG_EXPORT int mpeg3_has_video(mpeg3_t *file);
103LIBMPEG_EXPORT int mpeg3_total_vstreams(mpeg3_t *file); /* Number of multiplexed video streams */
104LIBMPEG_EXPORT int mpeg3_video_width(mpeg3_t *file, int stream);
105LIBMPEG_EXPORT int mpeg3_video_height(mpeg3_t *file, int stream);
106LIBMPEG_EXPORT float mpeg3_frame_rate(mpeg3_t *file, int stream); /* Frames/sec */
107
108/* Total length. */
109/* For DVD files, this is 1 indicating only percentage seeking is available. */
110LIBMPEG_EXPORT long mpeg3_video_frames(mpeg3_t *file, int stream);
111LIBMPEG_EXPORT int mpeg3_set_frame(mpeg3_t *file, long frame, int stream); /* Seek to a frame */
112LIBMPEG_EXPORT int mpeg3_skip_frames();
113LIBMPEG_EXPORT long mpeg3_get_frame(mpeg3_t *file, int stream); /* Tell current position */
114
115/* Seek all the tracks based on a percentage of the total bytes in the */
116/* file or the total */
117/* time in a toc if one exists. Percentage is a 0 to 1 double. */
118/* This eliminates the need for tocs and 64 bit longs but doesn't */
119/* give frame accuracy. */
120LIBMPEG_EXPORT int mpeg3_seek_percentage(mpeg3_t *file, double percentage);
121LIBMPEG_EXPORT double mpeg3_tell_percentage(mpeg3_t *file);
122LIBMPEG_EXPORT int mpeg3_previous_frame(mpeg3_t *file, int stream);
123LIBMPEG_EXPORT int mpeg3_end_of_audio(mpeg3_t *file, int stream);
124LIBMPEG_EXPORT int mpeg3_end_of_video(mpeg3_t *file, int stream);
125
126/* Give the seconds time in the last packet read */
127LIBMPEG_EXPORT double mpeg3_get_time(mpeg3_t *file);
128
129/* Read a frame. The dimensions of the input area and output frame must be supplied. */
130/* The frame is taken from the input area and scaled to fit the output frame in 1 step. */
131/* Stream defines the number of the multiplexed stream to read. */
132/* The last row of **output_rows must contain 4 extra bytes for scratch work. */
133LIBMPEG_EXPORT int mpeg3_read_frame(mpeg3_t *file,
134 unsigned char **output_rows, /* Array of pointers to the start of each output row */
135 int in_x, /* Location in input frame to take picture */
136 int in_y,
137 int in_w,
138 int in_h,
139 int out_w, /* Dimensions of output_rows */
140 int out_h,
141 int color_model, /* One of the color model #defines */
142 int stream);
143
144/* Read a YUV frame. The 3 planes are copied into the y, u, and v buffers provided. */
145/* The input is cropped to the dimensions given but not scaled. */
146LIBMPEG_EXPORT int mpeg3_read_yuvframe(mpeg3_t *file,
147 char *y_output,
148 char *u_output,
149 char *v_output,
150 int in_x,
151 int in_y,
152 int in_w,
153 int in_h,
154 int stream);
155
156LIBMPEG_EXPORT int mpeg3_drop_frames(mpeg3_t *file, long frames, int stream);
157
158/* Read the next compressed frame including headers. */
159/* Store the size in size and return a 1 if error. */
160/* Stream defines the number of the multiplexed stream to read. */
161LIBMPEG_EXPORT int mpeg3_read_video_chunk(mpeg3_t *file,
162 unsigned char *output,
163 long *size,
164 long max_size,
165 int stream);
166
167/* Master control */
168LIBMPEG_EXPORT int mpeg3_total_programs();
169LIBMPEG_EXPORT int mpeg3_set_program(int program);
170
171#if defined(__cplusplus)
172}
173#endif
174
175#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 @@
1 TEMPLATE= lib
2 CONFIG += qt warn_on release
3 HEADERS = libmpeg3plugin.h libmpeg3pluginimpl.h
4 SOURCES = libmpeg3plugin.cpp libmpeg3pluginimpl.cpp \
5 bitstream.c \
6 libmpeg3.c \
7 mpeg3atrack.c \
8 mpeg3css.c \
9 mpeg3demux.c \
10 mpeg3io.c \
11 mpeg3title.c \
12 mpeg3vtrack.c \
13 audio/ac3.c \
14 audio/bit_allocation.c \
15 audio/dct.c \
16 audio/exponents.c \
17 audio/header.c \
18 audio/layer2.c \
19 audio/layer3.c \
20 audio/mantissa.c \
21 audio/mpeg3audio.c \
22 audio/pcm.c \
23 audio/synthesizers.c \
24 audio/tables.c \
25 video/getpicture.c \
26 video/headers.c \
27 video/idct.c \
28 video/macroblocks.c \
29 video/mmxtest.c \
30 video/motion.c \
31 video/mpeg3video.c \
32 video/output.c \
33 video/reconstruct.c \
34 video/seek.c \
35 video/slice.c \
36 video/vlc.c
37 TARGET = mpeg3plugin
38 DESTDIR = ../../plugins/codecs
39INCLUDEPATH += $(QPEDIR)/include ..
40DEPENDPATH += ../$(QPEDIR)/include ..
41LIBS += -lqpe -lpthread -lm
42 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 @@
1/**********************************************************************
2** Copyright (C) 2001 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#include "libmpeg3plugin.h"
21
22/*
23bool LibMpeg3Plugin::audioReadSamples( short *output, int channel, long samples, int stream ) {
24 return file ? mpeg3_read_audio( file, 0, output, 0, channel, samples, stream ) == 1 : FALSE;
25}
26
27
28bool LibMpeg3Plugin::audioReReadSamples( short *output, int channel, long samples, int stream ) {
29 return file ? mpeg3_reread_audio( file, 0, output, 0, channel, samples, stream ) == 1 : FALSE;
30}
31
32
33bool LibMpeg3Plugin::audioReadMonoSamples( short *output, long samples, long& samplesRead, int stream ) {
34 samplesRead = samples;
35 return file ? mpeg3_read_audio( file, 0, output, 0, 0, samples, stream ) == 1 : FALSE;
36}
37
38
39bool LibMpeg3Plugin::audioReadStereoSamples( short *output, long samples, long& samplesRead, int stream ) {
40 bool err = FALSE;
41 if ( file ) {
42#if 1
43 err = mpeg3_read_audio ( file, 0, output, 1, 0, samples, stream ) == 1;
44 if ( err == FALSE ) {
45 err = mpeg3_reread_audio( file, 0, output + 1, 1, 1, samples, stream ) == 1;
46#else
47 short left[samples];
48 short right[samples];
49 err = mpeg3_read_audio ( file, 0, left, 0, samples, stream ) == 1;
50 if ( !err )
51 err = mpeg3_reread_audio( file, 0, right, 1, samples, stream ) == 1;
52 for ( int j = 0; j < samples; j++ ) {
53 output[j*2+0] = left[j];
54 output[j*2+1] = right[j];
55#endif
56 }
57 }
58 samplesRead = samples;
59 return err;
60}
61*/
62
63bool LibMpeg3Plugin::audioReadSamples( short *output, int channels, long samples, long& samplesRead, int stream ) {
64 samplesRead = samples;
65 switch ( channels ) {
66 case 1:
67 return file ? mpeg3_read_audio( file, 0, output, 0, 0, samples, stream ) == 1 : FALSE;
68 case 2:
69 if ( ( file ) && ( mpeg3_read_audio( file, 0, output, 1, 0, samples, stream ) != 1 ) &&
70 ( mpeg3_reread_audio( file, 0, output + 1, 1, 1, samples, stream ) != 1 ) )
71 return TRUE;
72 return FALSE;
73 }
74 return FALSE;
75}
76
77bool LibMpeg3Plugin::videoReadFrame( unsigned char **output_rows, int in_x, int in_y, int in_w, int in_h, ColorFormat color_model, int stream ) {
78 int format = MPEG3_RGB565;
79 switch ( color_model ) {
80 case RGB565:format = MPEG3_RGB565; break;
81 case BGR565: /*format = MPEG3_BGR565;*/ break;
82 case RGBA8888:format = MPEG3_RGBA8888; break;
83 case BGRA8888:format = MPEG3_BGRA8888; break;
84 }
85 return file ? mpeg3_read_frame( file, output_rows, in_x, in_y, in_w, in_h, in_w, in_h, format, stream ) == 1 : FALSE;
86}
87
88
89bool 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 ) {
90 int format = MPEG3_RGB565;
91 switch ( color_model ) {
92 case RGB565:format = MPEG3_RGB565; break;
93 case BGR565:/*format = MPEG3_BGR565;*/ break;
94 case RGBA8888:format = MPEG3_RGBA8888; break;
95 case BGRA8888:format = MPEG3_BGRA8888; break;
96 }
97 return file ? mpeg3_read_frame( file, output_rows, in_x, in_y, in_w, in_h, out_w, out_h, format, stream ) == 1 : FALSE;
98}
99
100
101bool 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 ) {
102 return file ? mpeg3_read_yuvframe( file, y_output, u_output, v_output, in_x, in_y, in_w, in_h, stream ) == 1 : FALSE;
103}
104
105
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 @@
1/**********************************************************************
2** Copyright (C) 2001 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef LIBMPEG3_PLUGIN_H
21#define LIBMPEG3_PLUGIN_H
22
23
24#include <qstring.h>
25#include <qapplication.h>
26#include "libmpeg3.h"
27#include "mpeg3protos.h"
28#include "mediaplayerplugininterface.h"
29
30
31class LibMpeg3Plugin : public MediaPlayerDecoder {
32
33public:
34 LibMpeg3Plugin() { file = NULL; }
35 ~LibMpeg3Plugin() { close(); }
36
37 const char *pluginName() { return "LibMpeg3Plugin"; }
38 const char *pluginComment() { return "This is the libmpeg3 library writen by ... which has been modified by trolltech to use fixed point maths"; }
39 double pluginVersion() { return 1.0; }
40
41 bool isFileSupported( const QString& fileName ) { return mpeg3_check_sig( (char *)fileName.latin1() ) == 1; }
42 bool open( const QString& fileName ) { file = mpeg3_open( (char *)fileName.latin1() ); return file != NULL; }
43 bool close() { if ( file ) { int r = mpeg3_close( file ); file = NULL; return r == 1; } return FALSE; }
44 bool isOpen() { return file != NULL; }
45 const QString &fileInfo() { return strInfo = QString( "" ); }
46
47 // If decoder doesn't support audio then return 0 here
48 int audioStreams() { return file ? mpeg3_total_astreams( file ) : 0; }
49 int audioChannels( int stream ) { return file ? mpeg3_audio_channels( file, stream ) : 0; }
50 int audioFrequency( int stream ) { return file ? mpeg3_sample_rate( file, stream ) : 0; }
51 int audioSamples( int stream ) { return file ? mpeg3_audio_samples( file, stream ) : 0; }
52 bool audioSetSample( long sample, int stream ) { return file ? mpeg3_set_sample( file, sample, stream) == 1 : FALSE; }
53 long audioGetSample( int stream ) { return file ? mpeg3_get_sample( file, stream ) : 0; }
54// bool audioReadMonoSamples( short *output, long samples, long& samplesRead, int stream );
55// bool audioReadStereoSamples( short *output, long samples, long& samplesRead, int stream );
56 bool audioReadSamples( short *output, int channels, long samples, long& samplesRead, int stream );
57// bool audioReadSamples( short *output, int channel, long samples, int stream );
58// bool audioReReadSamples( short *output, int channel, long samples, int stream );
59
60 // If decoder doesn't support video then return 0 here
61 int videoStreams() { return file ? mpeg3_total_vstreams( file ) : 0; }
62 int videoWidth( int stream ) { return file ? mpeg3_video_width( file, stream ) : 0; }
63 int videoHeight( int stream ) { return file ? mpeg3_video_height( file, stream ) : 0; }
64 double videoFrameRate( int stream ) { return file ? mpeg3_frame_rate( file, stream ) : 0.0; }
65 int videoFrames( int stream )
66{ return file ? mpeg3_video_frames( file, stream ) : 0; }
67/*
68{
69 if ( file ) {
70 int frames = mpeg3_video_frames( file, stream );
71 if ( frames == 1 ) {
72 int res = mpeg3_seek_percentage( file, 0.99 );
73 printf("res: %i\n", res );
74 mpeg3video_seek( file->vtrack[stream]->video );
75 frames = mpeg3_get_frame( file, stream );
76 mpeg3_seek_percentage( file, 0.0 );
77 }
78 return frames;
79 }
80 return 0;
81}
82*/
83 bool videoSetFrame( long frame, int stream ) { return file ? mpeg3_set_frame( file, frame, stream) == 1 : FALSE; }
84 long videoGetFrame( int stream ) { return file ? mpeg3_get_frame( file, stream ) : 0; }
85 bool videoReadFrame( unsigned char **output_rows, int in_x, int in_y, int in_w, int in_h, ColorFormat color_model, int stream );
86 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 );
87 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 );
88
89 // Profiling
90 double getTime() { return file ? mpeg3_get_time( file ) : 0.0; }
91
92 // Ignore if these aren't supported
93 bool setSMP( int cpus ) { return file ? mpeg3_set_cpus( file, cpus ) == 1 : FALSE; }
94 bool setMMX( bool useMMX ) { return file ? mpeg3_set_mmx( file, useMMX ) == 1 : FALSE; }
95
96 // Capabilities
97 bool supportsAudio() { return TRUE; }
98 bool supportsVideo() { return TRUE; }
99 bool supportsYUV() { return TRUE; }
100 bool supportsMMX() { return TRUE; }
101 bool supportsSMP() { return TRUE; }
102 bool supportsStereo() { return TRUE; }
103 bool supportsScaling() { return TRUE; }
104
105private:
106 mpeg3_t *file;
107 QString strInfo;
108
109};
110
111
112#endif
113
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#include "libmpeg3plugin.h"
21#include "libmpeg3pluginimpl.h"
22
23
24LibMpeg3PluginImpl::LibMpeg3PluginImpl()
25 : libmpeg3plugin(0), ref(0)
26{
27}
28
29
30LibMpeg3PluginImpl::~LibMpeg3PluginImpl()
31{
32 if ( libmpeg3plugin )
33 delete libmpeg3plugin;
34}
35
36
37MediaPlayerDecoder *LibMpeg3PluginImpl::decoder()
38{
39 if ( !libmpeg3plugin )
40 libmpeg3plugin = new LibMpeg3Plugin;
41 return libmpeg3plugin;
42}
43
44
45MediaPlayerEncoder *LibMpeg3PluginImpl::encoder()
46{
47 return NULL;
48}
49
50
51#ifndef QT_NO_COMPONENT
52
53
54QRESULT LibMpeg3PluginImpl::queryInterface( const QUuid &uuid, QUnknownInterface **iface )
55{
56 *iface = 0;
57 if ( ( uuid == IID_QUnknown ) || ( uuid == IID_MediaPlayerPlugin ) )
58 *iface = this, (*iface)->addRef();
59 return QS_OK;
60}
61
62
63Q_EXPORT_INTERFACE()
64{
65 Q_CREATE_INSTANCE( LibMpeg3PluginImpl )
66}
67
68
69#endif
70
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 @@
1/**********************************************************************
2** Copyright (C) 2001 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef LIBMPEG3_PLUGIN_IMPL_H
21#define LIBMPEG3_PLUGIN_IMPL_H
22
23
24#include "../mediaplayerplugininterface.h"
25
26
27class LibMpeg3Plugin;
28
29
30class LibMpeg3PluginImpl : public MediaPlayerPluginInterface
31{
32public:
33 LibMpeg3PluginImpl();
34 virtual ~LibMpeg3PluginImpl();
35
36#ifndef QT_NO_COMPONENT
37
38 QRESULT queryInterface( const QUuid&, QUnknownInterface** );
39 Q_REFCOUNT
40
41#endif
42
43 virtual MediaPlayerDecoder *decoder();
44 virtual MediaPlayerEncoder *encoder();
45
46private:
47 LibMpeg3Plugin *libmpeg3plugin;
48 ulong ref;
49};
50
51
52#endif
53
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 @@
1#!/bin/sh
2
3VERSION=1.2.1
4
5rm -r /tmp/libmpeg3-$VERSION
6mkdir -p /tmp/libmpeg3-$VERSION
7make clean
8cp -rd * /tmp/libmpeg3-$VERSION
9cd /tmp
10tar 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 @@
1#include "libmpeg3.h"
2#include "mpeg3protos.h"
3
4#include <stdlib.h>
5
6mpeg3_atrack_t* mpeg3_new_atrack(mpeg3_t *file, int stream_id, int format, mpeg3_demuxer_t *demuxer)
7{
8 mpeg3_atrack_t *new_atrack;
9
10 new_atrack = (mpeg3_atrack_t*)calloc(1, sizeof(mpeg3_atrack_t));
11 new_atrack->channels = 0;
12 new_atrack->sample_rate = 0;
13 new_atrack->total_samples = 0;
14 new_atrack->current_position = 0;
15 new_atrack->demuxer = mpeg3_new_demuxer(file, 1, 0, stream_id);
16 if(demuxer) mpeg3demux_copy_titles(new_atrack->demuxer, demuxer);
17 new_atrack->audio = mpeg3audio_new(file, new_atrack, format);
18
19 if(!new_atrack->audio)
20 {
21/* Failed */
22 mpeg3_delete_atrack(file, new_atrack);
23 new_atrack = 0;
24 }
25 return new_atrack;
26}
27
28int mpeg3_delete_atrack(mpeg3_t *file, mpeg3_atrack_t *atrack)
29{
30 if(atrack->audio)
31 mpeg3audio_delete(atrack->audio);
32 if(atrack->demuxer)
33 mpeg3_delete_demuxer(atrack->demuxer);
34 free(atrack);
35}
36
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef MPEG3ATRACK_H
21#define MPEG3ATRACK_H
22
23#include "mpeg3demux.h"
24#include "audio/mpeg3audio.h"
25
26struct mpeg3_atrack_rec
27{
28 int channels;
29 int sample_rate;
30 mpeg3_demuxer_t *demuxer;
31 mpeg3audio_t *audio;
32 long current_position;
33 long total_samples;
34};
35
36#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 @@
1/* Concatenate elementary streams */
2
3#include "libmpeg3.h"
4
5#include <stdio.h>
6#include <stdlib.h>
7#include <string.h>
8
9#define MPEG3_SEQUENCE_START_CODE 0x000001b3
10#define BUFFER_SIZE 1000000
11
12int main(int argc, char *argv[])
13{
14 char inpath[1024];
15 mpeg3_t *in;
16 int current_file, current_output_file = 0, i;
17 unsigned int bits;
18 unsigned char *buffer;
19 long output_size;
20 int result = 0;
21 long total_frames = 0;
22 int do_audio = 0, do_video = 0;
23 int stream = 0;
24
25 if(argc < 2)
26 {
27 fprintf(stderr, "Concatenate elementary streams or demultiplex a program stream.\n"
28 "Usage: mpeg3cat -[av0123456789] <infile> [infile...] > <outfile>\n\n"
29 "Example: Concatenate 2 video files: mpeg3cat xena1.m2v xena2.m2v > xena.m2v\n"
30 " Extract audio stream 0: mpeg3cat -a0 xena.vob > war_cry.ac3\n");
31 exit(1);
32 }
33
34 for(i = 1; i < argc; i++)
35 {
36 if(argv[i][0] == '-')
37 {
38 if(argv[i][1] != 'a' && argv[i][1] != 'v')
39 {
40 fprintf(stderr, "invalid option %s\n", argv[i]);
41 }
42 else
43 {
44 if(argv[i][1] == 'a') do_audio = 1;
45 else
46 if(argv[i][1] == 'v') do_video = 1;
47
48 if(argv[i][2] != 0)
49 {
50 stream = argv[i][2] - 48;
51 }
52 }
53 }
54 }
55
56 buffer = (unsigned char*)malloc(BUFFER_SIZE);
57
58 for(current_file = 1; current_file < argc; current_file++)
59 {
60 if(argv[current_file][0] == '-') continue;
61
62 strcpy(inpath, argv[current_file]);
63 if(!(in = mpeg3_open(inpath)))
64 {
65 fprintf(stderr, "Skipping %s\n", inpath);
66 continue;
67 }
68
69 if((mpeg3_has_audio(in) && in->is_audio_stream) ||
70 (do_audio && !in->is_audio_stream && !in->is_video_stream))
71 {
72 do_audio = 1;
73/* Add audio stream to end */
74 while(!mpeg3_read_audio_chunk(in, buffer,
75 &output_size,
76 BUFFER_SIZE,
77 stream))
78 {
79 result = !fwrite(buffer, output_size, 1, stdout);
80 if(result)
81 {
82 perror("fwrite audio chunk");
83 break;
84 }
85 }
86 }
87 else
88 if((mpeg3_has_video(in) && in->is_video_stream) ||
89 (do_video && !in->is_video_stream && !in->is_audio_stream))
90 {
91/* Add video stream to end */
92 int hour, minute, second, frame;
93 long gop_frame;
94 unsigned long code;
95 float carry;
96 int i, offset;
97
98 do_video = 1;
99 while(!mpeg3_read_video_chunk(in,
100 buffer,
101 &output_size,
102 BUFFER_SIZE,
103 stream) &&
104 output_size >= 4)
105 {
106 code = (unsigned long)buffer[output_size - 4] << 24;
107 code |= (unsigned long)buffer[output_size - 3] << 16;
108 code |= (unsigned long)buffer[output_size - 2] << 8;
109 code |= (unsigned long)buffer[output_size - 1];
110
111/* Got a frame at the end of this buffer. */
112 if(code == MPEG3_PICTURE_START_CODE)
113 {
114 total_frames++;
115 }
116 else
117 if(code == MPEG3_SEQUENCE_END_CODE)
118 {
119/* Got a sequence end code at the end of this buffer. */
120 output_size -= 4;
121 }
122
123 code = (unsigned long)buffer[0] << 24;
124 code |= (unsigned long)buffer[1] << 16;
125 code |= (unsigned long)buffer[2] << 8;
126 code |= buffer[3];
127
128 i = 0;
129 offset = 0;
130 if(code == MPEG3_SEQUENCE_START_CODE && current_output_file > 0)
131 {
132/* Skip the sequence start code */
133 i += 4;
134 while(i < output_size &&
135 code != MPEG3_GOP_START_CODE)
136 {
137 code <<= 8;
138 code |= buffer[i++];
139 }
140 i -= 4;
141 offset = i;
142 }
143
144/* Search for GOP header to fix */
145 code = (unsigned long)buffer[i++] << 24;
146 code |= (unsigned long)buffer[i++] << 16;
147 code |= (unsigned long)buffer[i++] << 8;
148 code |= buffer[i++];
149 while(i < output_size &&
150 code != MPEG3_GOP_START_CODE)
151 {
152 code <<= 8;
153 code |= buffer[i++];
154 }
155
156 if(code == MPEG3_GOP_START_CODE)
157 {
158/* Get the time code */
159 code = (unsigned long)buffer[i] << 24;
160 code |= (unsigned long)buffer[i + 1] << 16;
161 code |= (unsigned long)buffer[i + 2] << 8;
162 code |= (unsigned long)buffer[i + 3];
163
164 hour = code >> 26 & 0x1f;
165 minute = code >> 20 & 0x3f;
166 second = code >> 13 & 0x3f;
167 frame = code >> 7 & 0x3f;
168
169 gop_frame = (long)(hour * 3600 * mpeg3_frame_rate(in, stream) +
170 minute * 60 * mpeg3_frame_rate(in, stream) +
171 second * mpeg3_frame_rate(in, stream) +
172 frame);
173/* fprintf(stderr, "old: %02d:%02d:%02d:%02d ", hour, minute, second, frame); */
174/* Write a new time code */
175 hour = (long)((float)(total_frames - 1) / mpeg3_frame_rate(in, stream) / 3600);
176 carry = hour * 3600 * mpeg3_frame_rate(in, stream);
177 minute = (long)((float)(total_frames - 1 - carry) / mpeg3_frame_rate(in, stream) / 60);
178 carry += minute * 60 * mpeg3_frame_rate(in, stream);
179 second = (long)((float)(total_frames - 1 - carry) / mpeg3_frame_rate(in, stream));
180 carry += second * mpeg3_frame_rate(in, stream);
181 frame = (int)(total_frames - 1 - carry);
182
183 buffer[i] = ((code >> 24) & 0x80) | (hour << 2) | (minute >> 4);
184 buffer[i + 1] = ((code >> 16) & 0x08) | ((minute & 0xf) << 4) | (second >> 3);
185 buffer[i + 2] = ((second & 0x7) << 5) | (frame >> 1);
186 buffer[i + 3] = (code & 0x7f) | ((frame & 0x1) << 7);
187/* fprintf(stderr, "new: %02d:%02d:%02d:%02d\n", hour, minute, second, frame); */
188 }
189
190/* Write the frame */
191 result = !fwrite(buffer + offset, output_size - offset, 1, stdout);
192 if(result)
193 {
194 perror("fwrite video chunk");
195 break;
196 }
197 }
198 }
199 else
200 {
201 fprintf(stderr, "Unsupported stream type.\n");
202 mpeg3_close(in);
203 in = 0;
204 continue;
205 }
206
207 mpeg3_close(in);
208 in = 0;
209 current_output_file++;
210 }
211
212/* Terminate output */
213 if(current_output_file > 0 && do_video)
214 {
215/*fprintf(stderr, "\n"); */
216/* Write new end of sequence */
217 buffer[0] = MPEG3_SEQUENCE_END_CODE >> 24;
218 buffer[1] = (MPEG3_SEQUENCE_END_CODE >> 16) & 0xff;
219 buffer[2] = (MPEG3_SEQUENCE_END_CODE >> 8) & 0xff;
220 buffer[3] = MPEG3_SEQUENCE_END_CODE & 0xff;
221 result = !fwrite(buffer, 4, 1, stdout);
222 }
223
224 exit(0);
225}
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 @@
1#include "mpeg3css.h"
2#include "mpeg3private.h"
3
4extern "C" {
5
6int mpeg3_init_css(mpeg3_t *file, mpeg3_css_t *css)
7{
8 return 0;
9}
10
11int mpeg3_get_keys(mpeg3_css_t *css, char *path)
12{
13 return 1;
14}
15
16int mpeg3_decrypt_packet(mpeg3_css_t *css, unsigned char *sector)
17{
18 return 1;
19}
20
21mpeg3_css_t* mpeg3_new_css()
22{
23 return 0;
24}
25
26int mpeg3_delete_css(mpeg3_css_t *css)
27{
28 return 0;
29}
30
31};
32
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef MPEG3CSS_H
21#define MPEG3CSS_H
22
23/* Stubs for deCSS which can't be distributed legally */
24
25typedef struct
26{
27} mpeg3_css_t;
28
29#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 @@
1/* Stubs for deCSS which can't be distributed in source form */
2
3#include "mpeg3css.h"
4#include "mpeg3private.h"
5
6int mpeg3_init_css(mpeg3_t *file, mpeg3_css_t *css)
7{
8 return 0;
9}
10
11int mpeg3_get_keys(mpeg3_css_t *css, char *path)
12{
13 return 1;
14}
15
16int mpeg3_decrypt_packet(mpeg3_css_t *css, unsigned char *sector)
17{
18 return 1;
19}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef MPEG3CSS_H
21#define MPEG3CSS_H
22
23/* Stubs for deCSS which can't be distributed legally */
24
25typedef struct
26{
27} mpeg3_css_t;
28
29#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 @@
1#include "libmpeg3.h"
2#include "mpeg3io.h"
3#include "mpeg3protos.h"
4
5#include <math.h>
6#include <stdlib.h>
7#include <string.h>
8
9#define ABS(x) ((x) >= 0 ? (x) : -(x))
10
11/* Don't advance pointer */
12static inline unsigned char mpeg3packet_next_char(mpeg3_demuxer_t *demuxer)
13{
14 return demuxer->raw_data[demuxer->raw_offset];
15}
16
17unsigned char mpeg3packet_read_char(mpeg3_demuxer_t *demuxer)
18{
19 unsigned char result = demuxer->raw_data[demuxer->raw_offset++];
20 return result;
21}
22
23static inline unsigned int mpeg3packet_read_int16(mpeg3_demuxer_t *demuxer)
24{
25 unsigned int a, b, result;
26 a = demuxer->raw_data[demuxer->raw_offset++];
27 b = demuxer->raw_data[demuxer->raw_offset++];
28 result = (a << 8) | b;
29
30 return result;
31}
32
33static inline unsigned int mpeg3packet_next_int24(mpeg3_demuxer_t *demuxer)
34{
35 unsigned int a, b, c, result;
36 a = demuxer->raw_data[demuxer->raw_offset];
37 b = demuxer->raw_data[demuxer->raw_offset + 1];
38 c = demuxer->raw_data[demuxer->raw_offset + 2];
39 result = (a << 16) | (b << 8) | c;
40
41 return result;
42}
43
44static inline unsigned int mpeg3packet_read_int24(mpeg3_demuxer_t *demuxer)
45{
46 unsigned int a, b, c, result;
47 a = demuxer->raw_data[demuxer->raw_offset++];
48 b = demuxer->raw_data[demuxer->raw_offset++];
49 c = demuxer->raw_data[demuxer->raw_offset++];
50 result = (a << 16) | (b << 8) | c;
51
52 return result;
53}
54
55static inline unsigned int mpeg3packet_read_int32(mpeg3_demuxer_t *demuxer)
56{
57 unsigned int a, b, c, d, result;
58 a = demuxer->raw_data[demuxer->raw_offset++];
59 b = demuxer->raw_data[demuxer->raw_offset++];
60 c = demuxer->raw_data[demuxer->raw_offset++];
61 d = demuxer->raw_data[demuxer->raw_offset++];
62 result = (a << 24) | (b << 16) | (c << 8) | d;
63
64 return result;
65}
66
67static inline unsigned int mpeg3packet_skip(mpeg3_demuxer_t *demuxer, long length)
68{
69 demuxer->raw_offset += length;
70 return 0;
71}
72
73int mpeg3_get_adaptation_field(mpeg3_demuxer_t *demuxer)
74{
75 long length;
76 int pcr_flag;
77
78 demuxer->adaptation_fields++;
79/* get adaptation field length */
80 length = mpeg3packet_read_char(demuxer);
81/* get first byte */
82 pcr_flag = (mpeg3packet_read_char(demuxer) >> 4) & 1;
83
84 if(pcr_flag)
85 {
86 unsigned long clk_ref_base = mpeg3packet_read_int32(demuxer);
87 unsigned int clk_ref_ext = mpeg3packet_read_int16(demuxer);
88
89 if (clk_ref_base > 0x7fffffff)
90 { /* correct for invalid numbers */
91 clk_ref_base = 0; /* ie. longer than 32 bits when multiplied by 2 */
92 clk_ref_ext = 0; /* multiplied by 2 corresponds to shift left 1 (<<=1) */
93 }
94 else
95 {
96 clk_ref_base <<= 1; /* Create space for bit */
97 clk_ref_base |= (clk_ref_ext >> 15); /* Take bit */
98 clk_ref_ext &= 0x01ff; /* Only lower 9 bits */
99 }
100 demuxer->time = clk_ref_base + clk_ref_ext / 300;
101 if(length) mpeg3packet_skip(demuxer, length - 7);
102 }
103 else
104 mpeg3packet_skip(demuxer, length - 1);
105
106 return 0;
107}
108
109int mpeg3_get_program_association_table(mpeg3_demuxer_t *demuxer)
110{
111 demuxer->program_association_tables++;
112 demuxer->table_id = mpeg3packet_read_char(demuxer);
113 demuxer->section_length = mpeg3packet_read_int16(demuxer) & 0xfff;
114 demuxer->transport_stream_id = mpeg3packet_read_int16(demuxer);
115 mpeg3packet_skip(demuxer, demuxer->raw_size - demuxer->raw_offset);
116 return 0;
117}
118
119int mpeg3packet_get_data_buffer(mpeg3_demuxer_t *demuxer)
120{
121 while(demuxer->raw_offset < demuxer->raw_size && demuxer->data_size < demuxer->data_allocated)
122 {
123 demuxer->data_buffer[demuxer->data_size++] = demuxer->raw_data[demuxer->raw_offset++];
124 }
125 return 0;
126}
127
128int mpeg3_get_pes_packet_header(mpeg3_demuxer_t *demuxer, unsigned long *pts, unsigned long *dts)
129{
130 unsigned int pes_header_bytes = 0;
131 unsigned int pts_dts_flags;
132 int pes_header_data_length;
133
134/* drop first 8 bits */
135 mpeg3packet_read_char(demuxer);
136 pts_dts_flags = (mpeg3packet_read_char(demuxer) >> 6) & 0x3;
137 pes_header_data_length = mpeg3packet_read_char(demuxer);
138
139/* Get Presentation Time stamps and Decoding Time Stamps */
140 if(pts_dts_flags == 2)
141 {
142 *pts = (mpeg3packet_read_char(demuxer) >> 1) & 7; /* Only low 4 bits (7==1111) */
143 *pts <<= 15;
144 *pts |= (mpeg3packet_read_int16(demuxer) >> 1);
145 *pts <<= 15;
146 *pts |= (mpeg3packet_read_int16(demuxer) >> 1);
147 pes_header_bytes += 5;
148 }
149 else if(pts_dts_flags == 3)
150 {
151 *pts = (mpeg3packet_read_char(demuxer) >> 1) & 7; /* Only low 4 bits (7==1111) */
152 *pts <<= 15;
153 *pts |= (mpeg3packet_read_int16(demuxer) >> 1);
154 *pts <<= 15;
155 *pts |= (mpeg3packet_read_int16(demuxer) >> 1);
156 *dts = (mpeg3packet_read_char(demuxer) >> 1) & 7; /* Only low 4 bits (7==1111) */
157 *dts <<= 15;
158 *dts |= (mpeg3packet_read_int16(demuxer) >> 1);
159 *dts <<= 15;
160 *dts |= (mpeg3packet_read_int16(demuxer) >> 1);
161 pes_header_bytes += 10;
162 }
163/* extract other stuff here! */
164
165 mpeg3packet_skip(demuxer, pes_header_data_length - pes_header_bytes);
166 return 0;
167}
168
169int get_unknown_data(mpeg3_demuxer_t *demuxer)
170{
171 mpeg3packet_skip(demuxer, demuxer->raw_size - demuxer->raw_offset);
172 return 0;
173}
174
175int mpeg3_get_pes_packet_data(mpeg3_demuxer_t *demuxer, unsigned int stream_id)
176{
177 unsigned long pts = 0, dts = 0;
178
179 if((stream_id >> 4) == 12 || (stream_id >> 4) == 13)
180 {
181/* Just pick the first available stream if no ID is set */
182 if(demuxer->astream == -1)
183 demuxer->astream = (stream_id & 0x0f);
184
185 if((stream_id & 0x0f) == demuxer->astream && demuxer->do_audio)
186 {
187 mpeg3_get_pes_packet_header(demuxer, &pts, &dts);
188 demuxer->pes_audio_time = pts;
189 demuxer->audio_pid = demuxer->pid;
190 return mpeg3packet_get_data_buffer(demuxer);
191 }
192 }
193 else
194 if((stream_id >> 4)==14)
195 {
196/* Just pick the first available stream if no ID is set */
197 if(demuxer->vstream == -1)
198 demuxer->vstream = (stream_id & 0x0f);
199
200 if((stream_id & 0x0f) == demuxer->vstream && demuxer->do_video)
201 {
202 mpeg3_get_pes_packet_header(demuxer, &pts, &dts);
203 demuxer->pes_video_time = pts;
204 demuxer->video_pid = demuxer->pid;
205 return mpeg3packet_get_data_buffer(demuxer);
206 }
207 }
208 else
209 {
210 return get_unknown_data(demuxer);
211 }
212
213 mpeg3packet_skip(demuxer, demuxer->raw_size - demuxer->raw_offset);
214
215 return 0;
216}
217
218int mpeg3_get_pes_packet(mpeg3_demuxer_t *demuxer)
219{
220 unsigned int stream_id;
221
222 demuxer->pes_packets++;
223 stream_id = mpeg3packet_read_char(demuxer);
224/* Skip startcode */
225 mpeg3packet_read_int24(demuxer);
226/* Skip pes packet length */
227 mpeg3packet_read_int16(demuxer);
228
229 if(stream_id != MPEG3_PRIVATE_STREAM_2 && stream_id != MPEG3_PADDING_STREAM)
230 {
231 return mpeg3_get_pes_packet_data(demuxer, stream_id);
232 }
233 else
234 if(stream_id == MPEG3_PRIVATE_STREAM_2)
235 {
236/* Dump private data! */
237 fprintf(stderr, "stream_id == MPEG3_PRIVATE_STREAM_2\n");
238 mpeg3packet_skip(demuxer, demuxer->raw_size - demuxer->raw_offset);
239 return 0;
240 }
241 else
242 if(stream_id == MPEG3_PADDING_STREAM)
243 {
244 mpeg3packet_skip(demuxer, demuxer->raw_size - demuxer->raw_offset);
245 return 0;
246 }
247 else
248 {
249 fprintf(stderr, "unknown stream_id in pes packet");
250 return 1;
251 }
252 return 0;
253}
254
255int mpeg3_get_payload(mpeg3_demuxer_t *demuxer)
256{
257 if(demuxer->payload_unit_start_indicator)
258 {
259 if(demuxer->pid==0) mpeg3_get_program_association_table(demuxer);
260 else
261 if(mpeg3packet_next_int24(demuxer) == MPEG3_PACKET_START_CODE_PREFIX) mpeg3_get_pes_packet(demuxer);
262 else
263 mpeg3packet_skip(demuxer, demuxer->raw_size - demuxer->raw_offset);
264 }
265 else
266 {
267 if(demuxer->pid == demuxer->audio_pid && demuxer->do_audio)
268 {
269 mpeg3packet_get_data_buffer(demuxer);
270 }
271 else
272 if(demuxer->pid == demuxer->video_pid && demuxer->do_video)
273 {
274 mpeg3packet_get_data_buffer(demuxer);
275 }
276 else
277 mpeg3packet_skip(demuxer, demuxer->raw_size - demuxer->raw_offset);
278 }
279 return 0;
280}
281
282/* Read a transport packet */
283int mpeg3_read_transport(mpeg3_demuxer_t *demuxer)
284{
285 mpeg3_title_t *title = demuxer->titles[demuxer->current_title];
286 int result = mpeg3io_read_data(demuxer->raw_data, demuxer->packet_size, title->fs);
287 unsigned int bits;
288 int table_entry;
289
290 demuxer->raw_size = demuxer->packet_size;
291 demuxer->raw_offset = 0;
292 if(result)
293 {
294 perror("mpeg3_read_transport");
295 return 1;
296 }
297
298/* Sync byte */
299 if(mpeg3packet_read_char(demuxer) != MPEG3_SYNC_BYTE)
300 {
301 fprintf(stderr, "mpeg3packet_read_char(demuxer) != MPEG3_SYNC_BYTE\n");
302 return 1;
303 }
304
305 /* bits = mpeg3packet_read_int24(demuxer) & 0x0000ffff; */
306 /* demuxer->transport_error_indicator = bits >> 15; */
307 /* demuxer->payload_unit_start_indicator = (bits >> 14) & 1; */
308 /* demuxer->pid = bits & 0x00001fff; */
309 /* demuxer->transport_scrambling_control = (mpeg3packet_next_char(demuxer) >> 6) & 0x3; */
310 /* demuxer->adaptation_field_control = (mpeg3packet_next_char(demuxer) >> 4) & 0x3; */
311 /* demuxer->continuity_counter = (mpeg3packet_read_char(demuxer) & 0xf); */
312
313 bits = mpeg3packet_read_int24(demuxer) & 0x00ffffff;
314 demuxer->transport_error_indicator = (bits >> 23) & 0x1;
315 demuxer->payload_unit_start_indicator = (bits >> 22) & 0x1;
316 demuxer->pid = (bits >> 8) & 0x00001fff;
317 demuxer->transport_scrambling_control = (bits >> 6) & 0x3;
318 demuxer->adaptation_field_control = (bits >> 4) & 0x3;
319 demuxer->continuity_counter = bits & 0xf;
320
321 if(demuxer->transport_error_indicator)
322 {
323 fprintf(stderr, "demuxer->transport_error_indicator\n");
324 return 1;
325 }
326
327 if (demuxer->pid == 0x1fff)
328 {
329 demuxer->is_padding = 1; /* padding; just go to next */
330 return 0;
331 }
332 else
333 {
334 demuxer->is_padding = 0;
335 }
336
337/* Get pid */
338 for(table_entry = 0, result = 0; table_entry < demuxer->total_pids; table_entry++)
339 {
340 if(demuxer->pid == demuxer->pid_table[table_entry])
341 {
342 result = 1;
343 break;
344 }
345 }
346
347/* Not in pid table */
348 if(!result)
349 {
350 demuxer->pid_table[table_entry] = demuxer->pid;
351 demuxer->continuity_counters[table_entry] = demuxer->continuity_counter; /* init */
352 demuxer->total_pids++;
353 }
354 result = 0;
355
356/* Check counters */
357 if(demuxer->pid != MPEG3_PROGRAM_ASSOCIATION_TABLE &&
358 demuxer->pid != MPEG3_CONDITIONAL_ACCESS_TABLE &&
359 (demuxer->adaptation_field_control == 1 || demuxer->adaptation_field_control == 3))
360 {
361 if(demuxer->continuity_counters[table_entry] != demuxer->continuity_counter)
362 {
363 fprintf(stderr, "demuxer->continuity_counters[table_entry] != demuxer->continuity_counter\n");
364/* Reset it */
365 demuxer->continuity_counters[table_entry] = demuxer->continuity_counter;
366 }
367 if(++(demuxer->continuity_counters[table_entry]) > 15) demuxer->continuity_counters[table_entry] = 0;
368 }
369
370 if(demuxer->adaptation_field_control == 2 || demuxer->adaptation_field_control == 3)
371 result = mpeg3_get_adaptation_field(demuxer);
372
373 if(demuxer->adaptation_field_control == 1 || demuxer->adaptation_field_control == 3)
374 result = mpeg3_get_payload(demuxer);
375
376 return result;
377}
378
379int mpeg3_get_system_header(mpeg3_demuxer_t *demuxer)
380{
381 int length = mpeg3packet_read_int16(demuxer);
382 mpeg3packet_skip(demuxer, length);
383 return 0;
384}
385
386unsigned long mpeg3_get_timestamp(mpeg3_demuxer_t *demuxer)
387{
388 unsigned long timestamp;
389/* Only low 4 bits (7==1111) */
390 timestamp = (mpeg3packet_read_char(demuxer) >> 1) & 7;
391 timestamp <<= 15;
392 timestamp |= (mpeg3packet_read_int16(demuxer) >> 1);
393 timestamp <<= 15;
394 timestamp |= (mpeg3packet_read_int16(demuxer) >> 1);
395 return timestamp;
396}
397
398int mpeg3_get_pack_header(mpeg3_demuxer_t *demuxer, unsigned int *header)
399{
400 unsigned long i, j;
401 unsigned long clock_ref, clock_ref_ext;
402
403/* Get the time code */
404 if((mpeg3packet_next_char(demuxer) >> 4) == 2)
405 {
406/* MPEG-1 */
407 demuxer->time = (double)mpeg3_get_timestamp(demuxer) / 90000;
408/* Skip 3 bytes */
409 mpeg3packet_read_int24(demuxer);
410 }
411 else
412 if(mpeg3packet_next_char(demuxer) & 0x40)
413 {
414 i = mpeg3packet_read_int32(demuxer);
415 j = mpeg3packet_read_int16(demuxer);
416 if(i & 0x40000000 || (i >> 28) == 2)
417 {
418 clock_ref = ((i & 0x31000000) << 3);
419 clock_ref |= ((i & 0x03fff800) << 4);
420 clock_ref |= ((i & 0x000003ff) << 5);
421 clock_ref |= ((j & 0xf800) >> 11);
422 clock_ref_ext = (j >> 1) & 0x1ff;
423
424 demuxer->time = (double)(clock_ref + clock_ref_ext / 300) / 90000;
425/* Skip 3 bytes */
426 mpeg3packet_read_int24(demuxer);
427 i = mpeg3packet_read_char(demuxer) & 0x7;
428
429/* stuffing */
430 mpeg3packet_skip(demuxer, i);
431 }
432 }
433 else
434 {
435 mpeg3packet_skip(demuxer, 2);
436 }
437
438 *header = mpeg3packet_read_int32(demuxer);
439 if(*header == MPEG3_SYSTEM_START_CODE)
440 {
441 mpeg3_get_system_header(demuxer);
442 *header = mpeg3packet_read_int32(demuxer);
443 }
444 return 0;
445}
446
447/* Program packet reading core */
448int mpeg3_get_ps_pes_packet(mpeg3_demuxer_t *demuxer, unsigned int *header)
449{
450 unsigned long pts = 0, dts = 0;
451 int stream_id;
452 int pes_packet_length;
453 int pes_packet_start;
454 int i;
455 mpeg3_t *file = demuxer->file;
456
457 stream_id = *header & 0xff;
458 pes_packet_length = mpeg3packet_read_int16(demuxer);
459 pes_packet_start = demuxer->raw_offset;
460
461 if(stream_id != MPEG3_PRIVATE_STREAM_2 &&
462 stream_id != MPEG3_PADDING_STREAM)
463 {
464 if((mpeg3packet_next_char(demuxer) >> 6) == 0x02)
465 {
466/* Get MPEG-2 packet */
467 int pes_header_bytes = 0;
468 int scrambling = (mpeg3packet_read_char(demuxer) >> 4) & 0x3;
469 int pts_dts_flags = (mpeg3packet_read_char(demuxer) >> 6) & 0x3;
470 int pes_header_data_length = mpeg3packet_read_char(demuxer);
471
472 if(scrambling && (demuxer->do_audio || demuxer->do_video))
473 {
474/* Decrypt it */
475 if(mpeg3_decrypt_packet(demuxer->titles[demuxer->current_title]->fs->css,
476 demuxer->raw_data))
477 {
478 fprintf(stderr, "mpeg3_get_ps_pes_packet: Decryption not available\n");
479 return 1;
480 }
481 }
482
483/* Get Presentation and Decoding Time Stamps */
484 if(pts_dts_flags == 2)
485 {
486 pts = (mpeg3packet_read_char(demuxer) >> 1) & 7; /* Only low 4 bits (7==1111) */
487 pts <<= 15;
488 pts |= (mpeg3packet_read_int16(demuxer) >> 1);
489 pts <<= 15;
490 pts |= (mpeg3packet_read_int16(demuxer) >> 1);
491 pes_header_bytes += 5;
492 }
493 else
494 if(pts_dts_flags == 3)
495 {
496 pts = (mpeg3packet_read_char(demuxer) >> 1) & 7; /* Only low 4 bits (7==1111) */
497 pts <<= 15;
498 pts |= (mpeg3packet_read_int16(demuxer) >> 1);
499 pts <<= 15;
500 pts |= (mpeg3packet_read_int16(demuxer) >> 1);
501 dts = (mpeg3packet_read_char(demuxer) >> 1) & 7; /* Only low 4 bits (7==1111) */
502 dts <<= 15;
503 dts |= (mpeg3packet_read_int16(demuxer) >> 1);
504 dts <<= 15;
505 dts |= (mpeg3packet_read_int16(demuxer) >> 1);
506 pes_header_bytes += 10;
507 }
508
509/* Skip unknown */
510 mpeg3packet_skip(demuxer, pes_header_data_length - pes_header_bytes);
511 }
512 else
513 {
514 int pts_dts_flags;
515/* Get MPEG-1 packet */
516 while(mpeg3packet_next_char(demuxer) == 0xff)
517 {
518 mpeg3packet_read_char(demuxer);
519 }
520
521/* Skip STD buffer scale */
522 if((mpeg3packet_next_char(demuxer) & 0x40) == 0x40)
523 {
524 mpeg3packet_skip(demuxer, 2);
525 }
526
527/* Decide which timestamps are available */
528 pts_dts_flags = mpeg3packet_next_char(demuxer);
529
530 if(pts_dts_flags >= 0x30)
531 {
532/* Get the presentation and decoding time stamp */
533 pts = mpeg3_get_timestamp(demuxer);
534 dts = mpeg3_get_timestamp(demuxer);
535 }
536 else
537 if(pts_dts_flags >= 0x20)
538 {
539/* Get just the presentation time stamp */
540 pts = mpeg3_get_timestamp(demuxer);
541 }
542 else
543 if(pts_dts_flags == 0x0f)
544 {
545/* End of timestamps */
546 mpeg3packet_read_char(demuxer);
547 }
548 else
549 {
550 return 1; /* Error */
551 }
552 }
553
554/* Now extract the payload. */
555 if((stream_id >> 4) == 0xc || (stream_id >> 4) == 0xd)
556 {
557/* Audio data */
558/* Take first stream ID if -1 */
559 pes_packet_length -= demuxer->raw_offset - pes_packet_start;
560 if(!demuxer->do_audio && !demuxer->do_video)
561 demuxer->astream_table[stream_id & 0x0f] = AUDIO_MPEG;
562 else
563 if(demuxer->astream == -1)
564 demuxer->astream = stream_id & 0x0f;
565
566 if((stream_id & 0x0f) == demuxer->astream && demuxer->do_audio)
567 {
568 if(pts) demuxer->pes_audio_time = pts;
569
570 memcpy(&demuxer->data_buffer[demuxer->data_size],
571 &demuxer->raw_data[demuxer->raw_offset],
572 pes_packet_length);
573 demuxer->data_size += pes_packet_length;
574 demuxer->raw_offset += pes_packet_length;
575 }
576 else
577 {
578 mpeg3packet_skip(demuxer, pes_packet_length);
579 }
580 }
581 else
582 if((stream_id >> 4) == 0xe)
583 {
584/* Video data */
585/* Take first stream ID if -1 */
586 if(!demuxer->do_audio && !demuxer->do_video)
587 demuxer->vstream_table[stream_id & 0x0f] = 1;
588 else
589 if(demuxer->vstream == -1)
590 demuxer->vstream = stream_id & 0x0f;
591
592 pes_packet_length -= demuxer->raw_offset - pes_packet_start;
593 if((stream_id & 0x0f) == demuxer->vstream && demuxer->do_video)
594 {
595 if(pts) demuxer->pes_video_time = pts;
596
597 memcpy(&demuxer->data_buffer[demuxer->data_size],
598 &demuxer->raw_data[demuxer->raw_offset],
599 pes_packet_length);
600 demuxer->data_size += pes_packet_length;
601 demuxer->raw_offset += pes_packet_length;
602 }
603 else
604 {
605 mpeg3packet_skip(demuxer, pes_packet_length);
606 }
607 }
608 else
609 if(stream_id == 0xbd && demuxer->raw_data[demuxer->raw_offset] != 0xff)
610 {
611/* DVD audio data */
612/* Get the audio format */
613 int format;
614 if((demuxer->raw_data[demuxer->raw_offset] & 0xf0) == 0xa0)
615 format = AUDIO_PCM;
616 else
617 format = AUDIO_AC3;
618
619 stream_id = demuxer->raw_data[demuxer->raw_offset] - 0x80;
620
621/* Take first stream ID if not building TOC. */
622 if(!demuxer->do_audio && !demuxer->do_video)
623 demuxer->astream_table[stream_id] = format;
624 else
625 if(demuxer->astream == -1)
626 demuxer->astream = stream_id;
627
628 if(stream_id == demuxer->astream && demuxer->do_audio)
629 {
630 demuxer->aformat = format;
631 if(pts) demuxer->pes_audio_time = pts;
632 mpeg3packet_read_int32(demuxer);
633 pes_packet_length -= demuxer->raw_offset - pes_packet_start;
634
635 memcpy(&demuxer->data_buffer[demuxer->data_size],
636 &demuxer->raw_data[demuxer->raw_offset],
637 pes_packet_length);
638 demuxer->data_size += pes_packet_length;
639 demuxer->raw_offset += pes_packet_length;
640 }
641 else
642 {
643 pes_packet_length -= demuxer->raw_offset - pes_packet_start;
644 mpeg3packet_skip(demuxer, pes_packet_length);
645 }
646 }
647 else
648 if(stream_id == 0xbc || 1)
649 {
650 pes_packet_length -= demuxer->raw_offset - pes_packet_start;
651 mpeg3packet_skip(demuxer, pes_packet_length);
652 }
653 }
654 else
655 if(stream_id == MPEG3_PRIVATE_STREAM_2 || stream_id == MPEG3_PADDING_STREAM)
656 {
657 pes_packet_length -= demuxer->raw_offset - pes_packet_start;
658 mpeg3packet_skip(demuxer, pes_packet_length);
659 }
660
661 while(demuxer->raw_offset + 4 < demuxer->raw_size)
662 {
663 *header = mpeg3packet_read_int32(demuxer);
664 if((*header >> 8) != MPEG3_PACKET_START_CODE_PREFIX)
665 demuxer->raw_offset -= 3;
666 else
667 break;
668 }
669
670 return 0;
671}
672
673int mpeg3_read_program(mpeg3_demuxer_t *demuxer)
674{
675 int result = 0, count = 0;
676 mpeg3_t *file = demuxer->file;
677 mpeg3_title_t *title = demuxer->titles[demuxer->current_title];
678 unsigned int header;
679 demuxer->raw_size = demuxer->packet_size;
680 demuxer->raw_offset = 0;
681 demuxer->data_size = 0;
682
683/* Search backward for it. */
684 header = mpeg3io_read_int32(title->fs);
685 result = mpeg3io_eof(title->fs);
686
687 if(!result) result = mpeg3io_seek_relative(title->fs, -4);
688
689// Search backwards for header
690 while(header != MPEG3_PACK_START_CODE && !result && count < demuxer->packet_size)
691 {
692 result = mpeg3io_seek_relative(title->fs, -1);
693 if(!result)
694 {
695 header >>= 8;
696 header |= mpeg3io_read_char(title->fs) << 24;
697 result = mpeg3io_seek_relative(title->fs, -1);
698 }
699 count++;
700 }
701
702 if(result)
703 {
704// couldn't find MPEG3_PACK_START_CODE
705 return 1;
706 }
707
708 result = mpeg3io_read_data(demuxer->raw_data, demuxer->packet_size, title->fs);
709
710 if(result)
711 {
712 perror("mpeg3_read_program");
713 return 1;
714 }
715
716 header = mpeg3packet_read_int32(demuxer);
717 while(demuxer->raw_offset + 4 < demuxer->raw_size && !result)
718 {
719 if(header == MPEG3_PACK_START_CODE)
720 {
721 result = mpeg3_get_pack_header(demuxer, &header);
722 }
723 else
724 if((header >> 8) == MPEG3_PACKET_START_CODE_PREFIX)
725 {
726 result = mpeg3_get_ps_pes_packet(demuxer, &header);
727 }
728 }
729 return result;
730}
731
732double mpeg3_lookup_time_offset(mpeg3_demuxer_t *demuxer, long byte)
733{
734 int i;
735 mpeg3_title_t *title = demuxer->titles[demuxer->current_title];
736
737 if(!title->timecode_table_size) return 0;
738
739 for(i = title->timecode_table_size - 1;
740 i >= 0 && title->timecode_table[i].start_byte > byte;
741 i--)
742 ;
743 if(i < 0) i = 0;
744 return title->timecode_table[i].absolute_start_time - title->timecode_table[i].start_time;
745}
746
747int mpeg3_advance_timecode(mpeg3_demuxer_t *demuxer, int reverse)
748{
749 mpeg3_title_t *title = demuxer->titles[demuxer->current_title];
750 int result = 0;
751 int do_seek = 0;
752
753/* Skip timecode advancing when constructing timecode table */
754 if(!title->timecode_table ||
755 !title->timecode_table_size ||
756 demuxer->generating_timecode) return 0;
757
758 if(!reverse)
759 {
760/* Get inside the current timecode */
761 if(mpeg3io_tell(title->fs) < title->timecode_table[demuxer->current_timecode].start_byte)
762 {
763 mpeg3io_seek(title->fs, title->timecode_table[demuxer->current_timecode].start_byte);
764 }
765
766/* Get the next timecode */
767 while(!result &&
768 (mpeg3io_tell(title->fs) >= title->timecode_table[demuxer->current_timecode].end_byte ||
769 demuxer->current_program != title->timecode_table[demuxer->current_timecode].program))
770 {
771
772/*
773 * printf("mpeg3_advance_timecode %d %d %d %d\n", mpeg3io_tell(title->fs), title->timecode_table[demuxer->current_timecode].end_byte,
774 * demuxer->current_program, title->timecode_table[demuxer->current_timecode].program);
775 */
776
777 demuxer->current_timecode++;
778 if(demuxer->current_timecode >= title->timecode_table_size)
779 {
780 demuxer->current_timecode = 0;
781 if(demuxer->current_title + 1 < demuxer->total_titles)
782 {
783 mpeg3demux_open_title(demuxer, demuxer->current_title + 1);
784 do_seek = 1;
785 }
786 else
787 {
788 mpeg3io_seek(title->fs, mpeg3io_total_bytes(title->fs));
789 result = 1;
790 }
791 }
792 title = demuxer->titles[demuxer->current_title];
793 }
794
795 if(!result && do_seek)
796 {
797 mpeg3io_seek(title->fs, title->timecode_table[demuxer->current_timecode].start_byte);
798 }
799 }
800 else
801 {
802/* Get the previous timecode */
803 while(!result &&
804 (mpeg3io_tell(title->fs) < title->timecode_table[demuxer->current_timecode].start_byte ||
805 demuxer->current_program != title->timecode_table[demuxer->current_timecode].program))
806 {
807/*
808 * 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,
809 * demuxer->current_program, title->timecode_table[demuxer->current_timecode].program);
810 */
811 demuxer->current_timecode--;
812 if(demuxer->current_timecode < 0)
813 {
814 if(demuxer->current_title > 0)
815 {
816 mpeg3demux_open_title(demuxer, demuxer->current_title - 1);
817 title = demuxer->titles[demuxer->current_title];
818 demuxer->current_timecode = title->timecode_table_size - 1;
819 do_seek = 1;
820 }
821 else
822 {
823 mpeg3io_seek(title->fs, 0);
824 demuxer->current_timecode = 0;
825 result = 1;
826 }
827 }
828 }
829
830 if(!result && do_seek)
831 mpeg3io_seek(title->fs, title->timecode_table[demuxer->current_timecode].start_byte);
832 }
833
834 return result;
835}
836
837/* Read packet in the forward direction */
838int mpeg3_read_next_packet(mpeg3_demuxer_t *demuxer)
839{
840 int result = 0;
841 long current_position;
842 mpeg3_t *file = demuxer->file;
843 mpeg3_title_t *title = demuxer->titles[demuxer->current_title];
844 demuxer->data_size = 0;
845 demuxer->data_position = 0;
846
847/* Flip the file descriptor back to the end of the packet for forward */
848/* reading. */
849 if(demuxer->reverse)
850 {
851 result = mpeg3io_seek_relative(title->fs, demuxer->packet_size);
852 demuxer->reverse = 0;
853 }
854
855/* Read packets until the output buffer is full */
856 if(!result)
857 {
858 do
859 {
860 result = mpeg3_advance_timecode(demuxer, 0);
861
862 if(!result)
863 {
864 demuxer->time_offset = mpeg3_lookup_time_offset(demuxer, mpeg3io_tell(title->fs));
865
866 if(file->is_transport_stream)
867 {
868 result = mpeg3_read_transport(demuxer);
869 }
870 else
871 if(file->is_program_stream)
872 {
873 result = mpeg3_read_program(demuxer);
874 }
875 else
876 {
877/* Read elementary stream. */
878 result = mpeg3io_read_data(demuxer->data_buffer, demuxer->packet_size, title->fs);
879 if(!result) demuxer->data_size = demuxer->packet_size;
880 }
881 }
882 }while(!result && demuxer->data_size == 0 && (demuxer->do_audio || demuxer->do_video));
883 }
884
885 return result;
886}
887
888/* Read the packet right before the packet we're currently on. */
889int mpeg3_read_prev_packet(mpeg3_demuxer_t *demuxer)
890{
891 int result = 0;
892 mpeg3_t *file = demuxer->file;
893 long current_position;
894 mpeg3_title_t *title = demuxer->titles[demuxer->current_title];
895
896 demuxer->data_size = 0;
897 demuxer->data_position = 0;
898
899 do
900 {
901/* Rewind to the start of the packet to be read. */
902 result = mpeg3io_seek_relative(title->fs, -demuxer->packet_size);
903
904 if(!result) result = mpeg3_advance_timecode(demuxer, 1);
905 if(!result) demuxer->time_offset = mpeg3_lookup_time_offset(demuxer, mpeg3io_tell(title->fs));
906
907 if(file->is_transport_stream && !result)
908 {
909 result = mpeg3_read_transport(demuxer);
910 if(!mpeg3io_bof(title->fs))
911 /* if(!result) */result = mpeg3io_seek_relative(title->fs, -demuxer->packet_size);
912 }
913 else
914 if(file->is_program_stream && !result)
915 {
916
917 result = mpeg3_read_program(demuxer);
918 if(!mpeg3io_bof(title->fs))
919 /* if(!result) */result = mpeg3io_seek_relative(title->fs, -demuxer->packet_size);
920 }
921 else
922 if(!result)
923 {
924/* Elementary stream */
925/* Read the packet forwards and seek back to the start */
926 result = mpeg3io_read_data(demuxer->data_buffer, demuxer->packet_size, title->fs);
927 if(!result)
928 {
929 demuxer->data_size = demuxer->packet_size;
930 result = mpeg3io_seek_relative(title->fs, -demuxer->packet_size);
931 }
932 }
933 }while(!result && demuxer->data_size == 0 && (demuxer->do_audio || demuxer->do_video));
934
935/* Remember that the file descriptor is at the beginning of the packet just read. */
936 demuxer->reverse = 1;
937 demuxer->error_flag = result;
938 return result;
939}
940
941
942/* Used for audio */
943int mpeg3demux_read_data(mpeg3_demuxer_t *demuxer,
944 unsigned char *output,
945 long size)
946{
947 long i;
948 int result = 0;
949 mpeg3_t *file = demuxer->file;
950 demuxer->error_flag = 0;
951
952 if(demuxer->data_position >= 0)
953 {
954/* Read forwards */
955 for(i = 0; i < size && !result; )
956 {
957 int fragment_size = size - i;
958 if(fragment_size > demuxer->data_size - demuxer->data_position)
959 fragment_size = demuxer->data_size - demuxer->data_position;
960 memcpy(output + i, demuxer->data_buffer + demuxer->data_position, fragment_size);
961 demuxer->data_position += fragment_size;
962 i += fragment_size;
963
964 if(i < size)
965 {
966 result = mpeg3_read_next_packet(demuxer);
967 }
968 }
969 }
970 else
971 {
972/* Read backwards a full packet. */
973/* Only good for reading less than the size of a full packet, but */
974/* this routine should only be used for searching for previous markers. */
975 long current_position = demuxer->data_position;
976 result = mpeg3_read_prev_packet(demuxer);
977 if(!result) demuxer->data_position = demuxer->data_size + current_position;
978 memcpy(output, demuxer->data_buffer + demuxer->data_position, size);
979 demuxer->data_position += size;
980 }
981
982 demuxer->error_flag = result;
983 return result;
984}
985
986unsigned int mpeg3demux_read_char_packet(mpeg3_demuxer_t *demuxer)
987{
988 demuxer->error_flag = 0;
989 if(demuxer->data_position >= demuxer->data_size)
990 demuxer->error_flag = mpeg3_read_next_packet(demuxer);
991 demuxer->next_char = demuxer->data_buffer[demuxer->data_position++];
992 return demuxer->next_char;
993}
994
995unsigned int mpeg3demux_read_prev_char_packet(mpeg3_demuxer_t *demuxer)
996{
997 demuxer->error_flag = 0;
998 demuxer->data_position--;
999 if(demuxer->data_position < 0)
1000 {
1001 demuxer->error_flag = mpeg3_read_prev_packet(demuxer);
1002 if(!demuxer->error_flag) demuxer->data_position = demuxer->data_size - 1;
1003 }
1004 demuxer->next_char = demuxer->data_buffer[demuxer->data_position];
1005 return demuxer->next_char;
1006}
1007
1008mpeg3demux_timecode_t* mpeg3_append_timecode(mpeg3_demuxer_t *demuxer,
1009 mpeg3_title_t *title,
1010 long prev_byte,
1011 double prev_time,
1012 long next_byte,
1013 double next_time,
1014 int dont_store)
1015{
1016 mpeg3demux_timecode_t *new_table;
1017 mpeg3demux_timecode_t *new_timecode, *old_timecode;
1018 long i;
1019
1020 if(!title->timecode_table ||
1021 title->timecode_table_allocation <= title->timecode_table_size)
1022 {
1023 if(title->timecode_table_allocation == 0)
1024 title->timecode_table_allocation = 1;
1025 else
1026 title->timecode_table_allocation *= 2;
1027
1028 new_table = (mpeg3demux_timecode_t*)calloc(1, sizeof(mpeg3demux_timecode_t) * title->timecode_table_allocation);
1029 if(title->timecode_table)
1030 {
1031 for(i = 0; i < title->timecode_table_size; i++)
1032 {
1033 new_table[i] = title->timecode_table[i];
1034 }
1035
1036 free(title->timecode_table);
1037 }
1038 title->timecode_table = new_table;
1039 }
1040
1041 if(!dont_store)
1042 {
1043 new_timecode = &title->timecode_table[title->timecode_table_size];
1044 new_timecode->start_byte = next_byte;
1045 new_timecode->start_time = next_time;
1046 new_timecode->absolute_start_time = 0;
1047
1048 if(title->timecode_table_size > 0)
1049 {
1050 old_timecode = &title->timecode_table[title->timecode_table_size - 1];
1051 old_timecode->end_byte = prev_byte;
1052 old_timecode->end_time = prev_time;
1053 new_timecode->absolute_start_time =
1054 prev_time -
1055 old_timecode->start_time +
1056 old_timecode->absolute_start_time;
1057 new_timecode->absolute_end_time = next_time;
1058 }
1059 }
1060
1061 title->timecode_table_size++;
1062 return new_timecode;
1063}
1064
1065mpeg3demux_timecode_t* mpeg3demux_next_timecode(mpeg3_demuxer_t *demuxer,
1066 int *current_title,
1067 int *current_timecode,
1068 int current_program)
1069{
1070 int done = 0;
1071 while(!done)
1072 {
1073/* Increase timecode number */
1074 if(*current_timecode < demuxer->titles[*current_title]->timecode_table_size - 1)
1075 {
1076 (*current_timecode)++;
1077 if(demuxer->titles[*current_title]->timecode_table[*current_timecode].program == current_program)
1078 return &(demuxer->titles[*current_title]->timecode_table[*current_timecode]);
1079 }
1080 else
1081/* Increase title number */
1082 if(*current_title < demuxer->total_titles - 1)
1083 {
1084 (*current_title)++;
1085 (*current_timecode) = 0;
1086 if(demuxer->titles[*current_title]->timecode_table[*current_timecode].program == current_program)
1087 return &(demuxer->titles[*current_title]->timecode_table[*current_timecode]);
1088 }
1089 else
1090/* End of disk */
1091 done = 1;
1092 }
1093 return 0;
1094}
1095
1096mpeg3demux_timecode_t* mpeg3demux_prev_timecode(mpeg3_demuxer_t *demuxer,
1097 int *current_title,
1098 int *current_timecode,
1099 int current_program)
1100{
1101 int done = 0;
1102 while(!done)
1103 {
1104/* Increase timecode number */
1105 if(*current_timecode > 0)
1106 {
1107 (*current_timecode)--;
1108 if(demuxer->titles[*current_title]->timecode_table[*current_timecode].program == current_program)
1109 return &(demuxer->titles[*current_title]->timecode_table[*current_timecode]);
1110 }
1111 else
1112/* Increase title number */
1113 if(*current_title > 0)
1114 {
1115 (*current_title)--;
1116 (*current_timecode) = demuxer->titles[*current_title]->timecode_table_size - 1;
1117 if(demuxer->titles[*current_title]->timecode_table[*current_timecode].program == current_program)
1118 return &(demuxer->titles[*current_title]->timecode_table[*current_timecode]);
1119 }
1120 else
1121/* End of disk */
1122 done = 1;
1123
1124 }
1125 return 0;
1126}
1127
1128int mpeg3demux_open_title(mpeg3_demuxer_t *demuxer, int title_number)
1129{
1130 mpeg3_title_t *title;
1131
1132 if(title_number < demuxer->total_titles)
1133 {
1134 if(demuxer->current_title >= 0)
1135 {
1136 mpeg3io_close_file(demuxer->titles[demuxer->current_title]->fs);
1137 demuxer->current_title = -1;
1138 }
1139
1140 title = demuxer->titles[title_number];
1141 if(mpeg3io_open_file(title->fs))
1142 {
1143 demuxer->error_flag = 1;
1144 perror("mpeg3demux_open_title");
1145 }
1146 else
1147 {
1148 demuxer->current_title = title_number;
1149 }
1150 }
1151
1152 demuxer->current_timecode = 0;
1153
1154 return demuxer->error_flag;
1155}
1156
1157/* Assign program numbers to interleaved programs */
1158int mpeg3demux_assign_programs(mpeg3_demuxer_t *demuxer)
1159{
1160 int current_program = 0;
1161 int current_title = 0, previous_title;
1162 int current_timecode = 0, previous_timecode;
1163 double current_time, current_length;
1164 int done = 0;
1165 int interleaved = 0;
1166 mpeg3demux_timecode_t *timecode1, *timecode2;
1167 double program_times[MPEG3_MAX_STREAMS];
1168 int total_programs = 1;
1169 int i, j;
1170 int program_exists, last_program_assigned = 0;
1171 int total_timecodes;
1172 mpeg3_title_t **titles = demuxer->titles;
1173
1174 for(i = 0, total_timecodes = 0; i < demuxer->total_titles; i++)
1175 total_timecodes += demuxer->titles[i]->timecode_table_size;
1176
1177 //if(total_timecodes < 3) return 0;
1178
1179/*
1180 * // Assign programs based on length of contiguous timecode
1181 * timecode1 = demuxer->titles[current_title]->timecode_table;
1182 * while(!done)
1183 * {
1184 * if(!timecode1) done = 1;
1185 * else
1186 * if(timecode1->end_time - timecode1->start_time < MPEG3_PROGRAM_THRESHOLD)
1187 * {
1188 * // Got interleaved section
1189 * interleaved = 1;
1190 * program_times[0] = timecode1->end_time;
1191 *
1192 * while(interleaved && !done)
1193 * {
1194 * timecode2 = mpeg3demux_next_timecode(demuxer,
1195 * &current_title,
1196 * &current_timecode,
1197 * 0);
1198 *
1199 * if(!timecode2) done = 1;
1200 * else
1201 * {
1202 * // Another segment of interleaved data
1203 * if(timecode2->end_time - timecode2->start_time < MPEG3_PROGRAM_THRESHOLD)
1204 * {
1205 * // Search program times for where the previous instance of the program left off
1206 * for(program_exists = 0, i = 0;
1207 * i < total_programs && !program_exists;
1208 * i++)
1209 * {
1210 * // Got a previous instance of the program
1211 * if(program_times[i] + 0.5 > timecode2->start_time &&
1212 * program_times[i] - 0.5 < timecode2->start_time)
1213 * {
1214 * program_times[i] = timecode2->end_time;
1215 * timecode2->program = i;
1216 * program_exists = 1;
1217 *
1218 * // Programs must always start at 0 for an interleaved section
1219 * if(i < last_program_assigned && i != 0)
1220 * {
1221 * // Shift programs in the interleaved section down until they start at 0
1222 * for(j = 0; j < total_programs - 1; j++)
1223 * program_times[j] = program_times[j + 1];
1224 *
1225 * for(previous_title = current_title, previous_timecode = current_timecode;
1226 * titles[previous_title]->timecode_table[previous_timecode].program > 0 &&
1227 * (previous_title >= 0 || previous_timecode >= 0); )
1228 * {
1229 * titles[previous_title]->timecode_table[previous_timecode].program--;
1230 * previous_timecode--;
1231 * if(previous_timecode < 0 && previous_title > 0)
1232 * {
1233 * previous_title--;
1234 * previous_timecode = titles[previous_title]->timecode_table_size - 1;
1235 * }
1236 * }
1237 * }
1238 * }
1239 * }
1240 *
1241 * // Didn't get one
1242 * if(!program_exists)
1243 * {
1244 * program_times[total_programs] = timecode2->end_time;
1245 * timecode2->program = total_programs++;
1246 * }
1247 * last_program_assigned = timecode2->program;
1248 * }
1249 * // No more interleaved section
1250 * else
1251 * {
1252 * interleaved = 0;
1253 * // Restart program table from the beginning
1254 * total_programs = 1;
1255 * last_program_assigned = 0;
1256 * timecode1 = mpeg3demux_next_timecode(demuxer,
1257 * &current_title,
1258 * &current_timecode,
1259 * 0);
1260 * }
1261 * }
1262 * }
1263 * }
1264 * else
1265 * // Get next timecode
1266 * timecode1 = mpeg3demux_next_timecode(demuxer,
1267 * &current_title,
1268 * &current_timecode,
1269 * 0);
1270 * }
1271 *
1272 * demuxer->total_programs = total_programs;
1273 */
1274
1275/* Assign absolute timecodes in each program. */
1276 for(current_program = 0;
1277 current_program < total_programs;
1278 current_program++)
1279 {
1280 current_time = 0;
1281 current_title = 0;
1282 current_timecode = -1;
1283 while(timecode1 = mpeg3demux_next_timecode(demuxer,
1284 &current_title,
1285 &current_timecode,
1286 current_program))
1287 {
1288 timecode1->absolute_start_time = current_time;
1289 current_time += timecode1->end_time - timecode1->start_time;
1290 timecode1->absolute_end_time = current_time;
1291 }
1292 }
1293//for(i = 0; i < demuxer->total_titles; i++) mpeg3_dump_title(demuxer->titles[i]);
1294 demuxer->current_program = 0;
1295 return 0;
1296}
1297
1298/* ==================================================================== */
1299/* Entry points */
1300/* ==================================================================== */
1301
1302mpeg3_demuxer_t* mpeg3_new_demuxer(mpeg3_t *file, int do_audio, int do_video, int stream_id)
1303{
1304 mpeg3_demuxer_t *demuxer = (mpeg3_demuxer_t*)calloc(1, sizeof(mpeg3_demuxer_t));
1305 int i;
1306
1307/* The demuxer will change the default packet size for its own use. */
1308 demuxer->file = file;
1309 demuxer->packet_size = file->packet_size;
1310 demuxer->do_audio = do_audio;
1311 demuxer->do_video = do_video;
1312
1313/* Allocate buffer + padding */
1314 demuxer->raw_data = (unsigned char*)calloc(1, MPEG3_MAX_PACKSIZE);
1315 demuxer->data_buffer = (unsigned char*)calloc(1, MPEG3_MAX_PACKSIZE);
1316 demuxer->data_allocated = MPEG3_MAX_PACKSIZE;
1317/* System specific variables */
1318 demuxer->audio_pid = stream_id;
1319 demuxer->video_pid = stream_id;
1320 demuxer->astream = stream_id;
1321 demuxer->vstream = stream_id;
1322 demuxer->current_title = -1;
1323 return demuxer;
1324}
1325
1326int mpeg3_delete_demuxer(mpeg3_demuxer_t *demuxer)
1327{
1328 int i;
1329
1330 if(demuxer->current_title >= 0)
1331 {
1332 mpeg3io_close_file(demuxer->titles[demuxer->current_title]->fs);
1333 }
1334
1335 for(i = 0; i < demuxer->total_titles; i++)
1336 {
1337 mpeg3_delete_title(demuxer->titles[i]);
1338 }
1339
1340 if(demuxer->data_buffer) free(demuxer->data_buffer);
1341 free(demuxer->raw_data);
1342 free(demuxer);
1343}
1344
1345/* Create a title. */
1346/* Build a table of timecodes contained in the program stream. */
1347/* If toc is 0 just read the first and last timecode. */
1348int mpeg3demux_create_title(mpeg3_demuxer_t *demuxer, int timecode_search, FILE *toc)
1349{
1350 int result = 0, done = 0, counter_start, counter;
1351 mpeg3_t *file = demuxer->file;
1352 long next_byte, prev_byte;
1353 double next_time, prev_time, absolute_time;
1354 long i;
1355 mpeg3_title_t *title;
1356 unsigned long test_header = 0;
1357 mpeg3demux_timecode_t *timecode = 0;
1358
1359 demuxer->error_flag = 0;
1360 demuxer->generating_timecode = 1;
1361
1362/* Create a single title */
1363 if(!demuxer->total_titles)
1364 {
1365 demuxer->titles[0] = mpeg3_new_title(file, file->fs->path);
1366 demuxer->total_titles = 1;
1367 mpeg3demux_open_title(demuxer, 0);
1368 }
1369 title = demuxer->titles[0];
1370 title->total_bytes = mpeg3io_total_bytes(title->fs);
1371
1372
1373/* Get the packet size from the file */
1374 if(file->is_program_stream)
1375 {
1376 mpeg3io_seek(title->fs, 4);
1377 for(i = 0; i < MPEG3_MAX_PACKSIZE &&
1378 test_header != MPEG3_PACK_START_CODE; i++)
1379 {
1380 test_header <<= 8;
1381 test_header |= mpeg3io_read_char(title->fs);
1382 }
1383 if(i < MPEG3_MAX_PACKSIZE) demuxer->packet_size = i;
1384 mpeg3io_seek(title->fs, 0);
1385 }
1386 else
1387 demuxer->packet_size = file->packet_size;
1388
1389/* Get timecodes for the title */
1390 if(file->is_transport_stream || file->is_program_stream)
1391 {
1392 mpeg3io_seek(title->fs, 0);
1393 while(!done && !result && !mpeg3io_eof(title->fs))
1394 {
1395 next_byte = mpeg3io_tell(title->fs);
1396 result = mpeg3_read_next_packet(demuxer);
1397
1398 if(!result)
1399 {
1400 next_time = demuxer->time;
1401//printf("%f %f\n", next_time, prev_time);
1402 if(next_time < prev_time ||
1403 next_time - prev_time > MPEG3_CONTIGUOUS_THRESHOLD ||
1404 !title->timecode_table_size)
1405 {
1406/* Discontinuous */
1407 timecode = mpeg3_append_timecode(demuxer,
1408 title,
1409 prev_byte,
1410 prev_time,
1411 next_byte,
1412 next_time,
1413 0);
1414/*
1415 * printf("timecode: %ld %ld %f %f\n",
1416 * timecode->start_byte,
1417 * timecode->end_byte,
1418 * timecode->start_time,
1419 * timecode->end_time);
1420 */
1421
1422 counter_start = (int)next_time;
1423 }
1424 prev_time = next_time;
1425 prev_byte = next_byte;
1426 counter = (int)next_time;
1427 }
1428
1429/* Just get the first bytes if not building a toc to get the stream ID's. */
1430 if(next_byte > 0x100000 &&
1431 (!timecode_search || !toc)) done = 1;
1432 }
1433
1434/* Get the last timecode */
1435 if(!toc || !timecode_search)
1436 {
1437 result = mpeg3io_seek(title->fs, title->total_bytes);
1438 if(!result) result = mpeg3_read_prev_packet(demuxer);
1439 }
1440
1441 if(title->timecode_table && timecode)
1442 {
1443 timecode->end_byte = title->total_bytes;
1444 // timecode->end_byte = mpeg3io_tell(title->fs)/* + demuxer->packet_size */;
1445 timecode->end_time = demuxer->time;
1446 timecode->absolute_end_time = timecode->end_time - timecode->start_time;
1447 }
1448 }
1449
1450 mpeg3io_seek(title->fs, 0);
1451 demuxer->generating_timecode = 0;
1452 return 0;
1453}
1454
1455int mpeg3demux_print_timecodes(mpeg3_title_t *title, FILE *output)
1456{
1457 mpeg3demux_timecode_t *timecode;
1458 int i;
1459
1460 if(title->timecode_table)
1461 {
1462 for(i = 0; i < title->timecode_table_size; i++)
1463 {
1464 timecode = &title->timecode_table[i];
1465
1466 fprintf(output, "REGION: %ld %ld %f %f\n",
1467 timecode->start_byte,
1468 timecode->end_byte,
1469 timecode->start_time,
1470 timecode->end_time);
1471 }
1472 }
1473 return 0;
1474}
1475
1476/* Read the title information from a toc */
1477int mpeg3demux_read_titles(mpeg3_demuxer_t *demuxer)
1478{
1479 char string1[MPEG3_STRLEN], string2[MPEG3_STRLEN];
1480 long start_byte, end_byte;
1481 float start_time, end_time;
1482 mpeg3_title_t *title = 0;
1483 mpeg3_t *file = demuxer->file;
1484
1485// Eventually use IFO file to generate titles
1486 while(!feof(file->fs->fd))
1487 {
1488 fscanf(file->fs->fd, "%s %s %ld %f %f %f",
1489 string1,
1490 string2,
1491 &end_byte,
1492 &start_time,
1493 &end_time);
1494
1495 if(!strncasecmp(string1, "PATH:", 5))
1496 {
1497 title = demuxer->titles[demuxer->total_titles++] = mpeg3_new_title(file, string2);
1498
1499 if(demuxer->current_title < 0)
1500 mpeg3demux_open_title(demuxer, 0);
1501 }
1502 else
1503 if(title)
1504 {
1505 start_byte = atol(string2);
1506 if(!strcasecmp(string1, "REGION:"))
1507 {
1508 mpeg3_append_timecode(demuxer,
1509 title,
1510 0,
1511 0,
1512 0,
1513 0,
1514 1);
1515 title->timecode_table[title->timecode_table_size - 1].start_byte = start_byte;
1516 title->timecode_table[title->timecode_table_size - 1].end_byte = end_byte;
1517 title->timecode_table[title->timecode_table_size - 1].start_time = start_time;
1518 title->timecode_table[title->timecode_table_size - 1].end_time = end_time;
1519 }
1520 else
1521 if(!strcasecmp(string1, "ASTREAM:"))
1522 demuxer->astream_table[start_byte] = end_byte;
1523 else
1524 if(!strcasecmp(string1, "VSTREAM:"))
1525 demuxer->vstream_table[start_byte] = end_byte;
1526 else
1527 if(!strcasecmp(string1, "SIZE:"))
1528 title->total_bytes = start_byte;
1529 else
1530 if(!strcasecmp(string1, "PACKETSIZE:"))
1531 demuxer->packet_size = start_byte;
1532 }
1533 }
1534
1535 mpeg3demux_assign_programs(demuxer);
1536 return 0;
1537}
1538
1539int mpeg3demux_copy_titles(mpeg3_demuxer_t *dst, mpeg3_demuxer_t *src)
1540{
1541 long i;
1542 mpeg3_t *file = dst->file;
1543 mpeg3_title_t *dst_title, *src_title;
1544
1545 dst->packet_size = src->packet_size;
1546 dst->total_titles = src->total_titles;
1547 dst->total_programs = src->total_programs;
1548 for(i = 0; i < MPEG3_MAX_STREAMS; i++)
1549 {
1550 dst->astream_table[i] = src->astream_table[i];
1551 dst->vstream_table[i] = src->vstream_table[i];
1552 }
1553 for(i = 0; i < src->total_titles; i++)
1554 {
1555 src_title = src->titles[i];
1556 dst_title = dst->titles[i] = mpeg3_new_title(file, src->titles[i]->fs->path);
1557 mpeg3_copy_title(dst_title, src_title);
1558 }
1559
1560 mpeg3demux_open_title(dst, src->current_title);
1561 return 0;
1562}
1563
1564int mpeg3demux_print_streams(mpeg3_demuxer_t *demuxer, FILE *toc)
1565{
1566 int i;
1567/* Print the stream information */
1568 for(i = 0; i < MPEG3_MAX_STREAMS; i++)
1569 {
1570 if(demuxer->astream_table[i])
1571 fprintf(toc, "ASTREAM: %d %d\n", i, demuxer->astream_table[i]);
1572
1573 if(demuxer->vstream_table[i])
1574 fprintf(toc, "VSTREAM: %d %d\n", i, demuxer->vstream_table[i]);
1575 }
1576 return 0;
1577}
1578
1579/* Need a timecode table to do this */
1580double mpeg3demux_length(mpeg3_demuxer_t *demuxer)
1581{
1582 mpeg3_title_t *title;
1583 int i, j;
1584 double length;
1585
1586 for(i = demuxer->total_titles - 1; i >= 0; i--)
1587 {
1588 title = demuxer->titles[i];
1589 for(j = title->timecode_table_size - 1; j >= 0; j--)
1590 {
1591 if(title->timecode_table[j].program == demuxer->current_program)
1592 {
1593 return title->timecode_table[j].end_time -
1594 title->timecode_table[j].start_time +
1595 title->timecode_table[j].absolute_start_time;
1596 }
1597 }
1598 }
1599
1600 return 1;
1601}
1602
1603int mpeg3demux_eof(mpeg3_demuxer_t *demuxer)
1604{
1605 if(demuxer->current_title >= 0)
1606 {
1607 if(mpeg3io_eof(demuxer->titles[demuxer->current_title]->fs) &&
1608 demuxer->current_title >= demuxer->total_titles - 1)
1609 return 1;
1610 }
1611
1612 return 0;
1613}
1614
1615int mpeg3demux_bof(mpeg3_demuxer_t *demuxer)
1616{
1617 if(demuxer->current_title >= 0)
1618 {
1619 if(mpeg3io_bof(demuxer->titles[demuxer->current_title]->fs) &&
1620 demuxer->current_title <= 0)
1621 return 1;
1622 }
1623 return 0;
1624}
1625
1626
1627/* For elemental streams seek to a byte */
1628int mpeg3demux_seek_byte(mpeg3_demuxer_t *demuxer, long byte)
1629{
1630 long current_position;
1631 mpeg3_t *file = demuxer->file;
1632 mpeg3_title_t *title = demuxer->titles[demuxer->current_title];
1633
1634 demuxer->data_position = 0;
1635 demuxer->data_size = 0;
1636
1637 demuxer->error_flag = mpeg3io_seek(title->fs, byte);
1638
1639 if(!demuxer->error_flag && (file->is_transport_stream || file->is_program_stream))
1640 {
1641/* Get on a packet boundary only for system streams. */
1642 current_position = mpeg3io_tell(title->fs);
1643 if(byte % demuxer->packet_size)
1644 {
1645 demuxer->error_flag |= mpeg3io_seek(title->fs, current_position - (current_position % demuxer->packet_size));
1646 }
1647 }
1648 return demuxer->error_flag;
1649}
1650
1651/* For programs streams and toc seek to a time */
1652int mpeg3demux_seek_time(mpeg3_demuxer_t *demuxer, double new_time)
1653{
1654 int i, j, done = 0, result = 0;
1655 double byte_offset, new_byte_offset;
1656 double guess = 0, minimum = 65535;
1657 mpeg3_title_t *title;
1658 mpeg3demux_timecode_t *timecode;
1659
1660 demuxer->error_flag = 0;
1661
1662 i = 0;
1663 j = 0;
1664 title = demuxer->titles[i];
1665 timecode = &title->timecode_table[j];
1666
1667/* Get the title and timecode of the new position */
1668 while(!demuxer->error_flag &&
1669 !(timecode->absolute_start_time <= new_time &&
1670 timecode->absolute_end_time > new_time &&
1671 timecode->program == demuxer->current_program))
1672 {
1673/* Next timecode */
1674 j++;
1675 if(j >= title->timecode_table_size)
1676 {
1677 i++;
1678 j = 0;
1679 if(i >= demuxer->total_titles)
1680 {
1681 demuxer->error_flag = 1;
1682 return 1;
1683 }
1684 else
1685 {
1686 mpeg3demux_open_title(demuxer, i);
1687 }
1688 }
1689
1690 title = demuxer->titles[i];
1691 timecode = &title->timecode_table[j];
1692 }
1693
1694/* Guess the new byte position */
1695 demuxer->current_timecode = j;
1696
1697 byte_offset = ((new_time - timecode->absolute_start_time) /
1698 (timecode->absolute_end_time - timecode->absolute_start_time) *
1699 (timecode->end_byte - timecode->start_byte) +
1700 timecode->start_byte);
1701//printf("mpeg3demux_seek_time %f %f\n", new_time, byte_offset);
1702
1703 while(!done && !result && byte_offset >= 0)
1704 {
1705 result = mpeg3demux_seek_byte(demuxer, (long)byte_offset);
1706//printf("seek_time 0 byte %.0f want %f result %d\n", byte_offset, new_time, result);
1707
1708 if(!result)
1709 {
1710 result = mpeg3_read_next_packet(demuxer);
1711// printf("seek_time 1 guess %f want %f\n", guess, new_time);
1712 guess = demuxer->time + demuxer->time_offset;
1713
1714 if(fabs(new_time - guess) >= fabs(minimum)) done = 1;
1715 else
1716 {
1717 minimum = guess - new_time;
1718 new_byte_offset = byte_offset + ((new_time - guess) /
1719 (timecode->end_time - timecode->start_time) *
1720 (timecode->end_byte - timecode->start_byte));
1721 if(labs((long)new_byte_offset - (long)byte_offset) < demuxer->packet_size) done = 1;
1722 byte_offset = new_byte_offset;
1723 }
1724 }
1725 }
1726
1727/* Get one packet before the packet just read */
1728 if(!result && byte_offset > demuxer->packet_size && minimum > 0)
1729 {
1730 mpeg3_read_prev_packet(demuxer);
1731 mpeg3_read_prev_packet(demuxer);
1732 }
1733//printf("seek_time %d %d %d\n", demuxer->current_title, demuxer->current_timecode, mpeg3demux_tell(demuxer));
1734 demuxer->error_flag = result;
1735 return result;
1736}
1737
1738int mpeg3demux_seek_percentage(mpeg3_demuxer_t *demuxer, double percentage)
1739{
1740 double total_bytes = 0;
1741 double absolute_position;
1742 long relative_position;
1743 int i, new_title;
1744 mpeg3_title_t *title;
1745
1746 demuxer->error_flag = 0;
1747
1748/* Get the absolute byte position; */
1749 for(i = 0; i < demuxer->total_titles; i++)
1750 total_bytes += demuxer->titles[i]->total_bytes;
1751
1752 absolute_position = percentage * total_bytes;
1753
1754/* Get the title the byte is inside */
1755 for(new_title = 0, total_bytes = 0; new_title < demuxer->total_titles; new_title++)
1756 {
1757 total_bytes += demuxer->titles[new_title]->total_bytes;
1758 if(absolute_position < total_bytes) break;
1759 }
1760
1761 if(new_title >= demuxer->total_titles)
1762 {
1763 new_title = demuxer->total_titles - 1;
1764 }
1765
1766/* Got a title */
1767 title = demuxer->titles[new_title];
1768 total_bytes -= title->total_bytes;
1769 relative_position = (long)(absolute_position - total_bytes);
1770
1771/* Get the timecode the byte is inside */
1772 for(demuxer->current_timecode = 0;
1773 demuxer->current_timecode < title->timecode_table_size;
1774 demuxer->current_timecode++)
1775 {
1776 if(title->timecode_table[demuxer->current_timecode].start_byte <= relative_position &&
1777 title->timecode_table[demuxer->current_timecode].end_byte > relative_position)
1778 {
1779 break;
1780 }
1781 }
1782
1783 if(demuxer->current_timecode >= title->timecode_table_size)
1784 demuxer->current_timecode = title->timecode_table_size - 1;
1785
1786/* Get the nearest timecode in the same program */
1787 while(demuxer->current_timecode < title->timecode_table_size - 1 &&
1788 title->timecode_table[demuxer->current_timecode].program != demuxer->current_program)
1789 {
1790 demuxer->current_timecode++;
1791 }
1792
1793/* Open the new title and seek to the correct byte */
1794 if(new_title != demuxer->current_title)
1795 {
1796 demuxer->error_flag = mpeg3demux_open_title(demuxer, new_title);
1797 }
1798
1799 if(!demuxer->error_flag)
1800 demuxer->error_flag = mpeg3io_seek(title->fs, relative_position);
1801
1802 return demuxer->error_flag;
1803}
1804
1805double mpeg3demux_tell_percentage(mpeg3_demuxer_t *demuxer)
1806{
1807 double total_bytes = 0;
1808 double position = 0;
1809 int i;
1810
1811 demuxer->error_flag = 0;
1812 position = mpeg3io_tell(demuxer->titles[demuxer->current_title]->fs);
1813 for(i = 0; i < demuxer->total_titles; i++)
1814 {
1815 if(i == demuxer->current_title)
1816 {
1817 position += total_bytes;
1818 }
1819 total_bytes += demuxer->titles[i]->total_bytes;
1820 }
1821 return position / total_bytes;
1822}
1823
1824double mpeg3demux_get_time(mpeg3_demuxer_t *demuxer)
1825{
1826 return demuxer->time;
1827}
1828
1829long mpeg3demux_tell(mpeg3_demuxer_t *demuxer)
1830{
1831 return mpeg3io_tell(demuxer->titles[demuxer->current_title]->fs);
1832}
1833
1834long mpeg3demuxer_total_bytes(mpeg3_demuxer_t *demuxer)
1835{
1836 mpeg3_title_t *title = demuxer->titles[demuxer->current_title];
1837 return title->total_bytes;
1838}
1839
1840mpeg3_demuxer_t* mpeg3_get_demuxer(mpeg3_t *file)
1841{
1842 if(file->is_program_stream || file->is_transport_stream)
1843 {
1844 if(file->has_audio) return file->atrack[0]->demuxer;
1845 else
1846 if(file->has_video) return file->vtrack[0]->demuxer;
1847 }
1848 return 0;
1849}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef MPEG3DEMUX_H
21#define MPEG3DEMUX_H
22
23#include "mpeg3title.h"
24#include <stdio.h>
25
26typedef struct
27{
28 struct mpeg3_rec* file;
29/* Data consisting of the multiplexed packet */
30 unsigned char *raw_data;
31 long raw_offset;
32 int raw_size;
33 long packet_size;
34/* Only one is on depending on which track owns the demultiplexer. */
35 int do_audio;
36 int do_video;
37/* Data consisting of the elementary stream */
38 unsigned char *data_buffer;
39 long data_size;
40 long data_position;
41 long data_allocated;
42/* Remember when the file descriptor is at the beginning of the packet just read. */
43 int reverse;
44/* Set to 1 when eof or attempt to read before beginning */
45 int error_flag;
46/* Temp variables for returning */
47 unsigned char next_char;
48/* Correction factor for time discontinuity */
49 double time_offset;
50 int generating_timecode;
51
52/* Titles */
53 mpeg3_title_t *titles[MPEG3_MAX_STREAMS];
54 int total_titles;
55 int current_title;
56
57/* Tables of every stream ID encountered */
58 int astream_table[MPEG3_MAX_STREAMS]; /* macro of audio format if audio */
59 int vstream_table[MPEG3_MAX_STREAMS]; /* 1 if video */
60
61/* Programs */
62 int total_programs;
63 int current_program;
64
65/* Timecode in the current title */
66 int current_timecode;
67
68/* Byte position in the current title */
69 long current_byte;
70
71 int transport_error_indicator;
72 int payload_unit_start_indicator;
73 int pid;
74 int transport_scrambling_control;
75 int adaptation_field_control;
76 int continuity_counter;
77 int is_padding;
78 int pid_table[MPEG3_PIDMAX];
79 int continuity_counters[MPEG3_PIDMAX];
80 int total_pids;
81 int adaptation_fields;
82 double time; /* Time in seconds */
83 int audio_pid;
84 int video_pid;
85 int astream; /* Video stream ID being decoded. -1 = select first ID in stream */
86 int vstream; /* Audio stream ID being decoded. -1 = select first ID in stream */
87 int aformat; /* format of the audio derived from multiplexing codes */
88 long program_association_tables;
89 int table_id;
90 int section_length;
91 int transport_stream_id;
92 long pes_packets;
93 double pes_audio_time; /* Presentation Time stamps */
94 double pes_video_time; /* Presentation Time stamps */
95} mpeg3_demuxer_t;
96
97/* ========================================================================= */
98/* Entry points */
99/* ========================================================================= */
100
101#define mpeg3demux_error(demuxer) (((mpeg3_demuxer_t *)(demuxer))->error_flag)
102
103#define mpeg3demux_time_offset(demuxer) (((mpeg3_demuxer_t *)(demuxer))->time_offset)
104
105#define mpeg3demux_current_time(demuxer) (((mpeg3_demuxer_t *)(demuxer))->time + ((mpeg3_demuxer_t *)(demuxer))->time_offset)
106
107#define mpeg3demux_read_char(demuxer) \
108 ((((mpeg3_demuxer_t *)(demuxer))->data_position < ((mpeg3_demuxer_t *)(demuxer))->data_size) ? \
109 ((mpeg3_demuxer_t *)(demuxer))->data_buffer[((mpeg3_demuxer_t *)(demuxer))->data_position++] : \
110 mpeg3demux_read_char_packet(demuxer))
111
112#define mpeg3demux_read_prev_char(demuxer) \
113 ((((mpeg3_demuxer_t *)(demuxer))->data_position != 0) ? \
114 ((mpeg3_demuxer_t *)(demuxer))->data_buffer[((mpeg3_demuxer_t *)(demuxer))->data_position--] : \
115 mpeg3demux_read_prev_char_packet(demuxer))
116
117
118#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 @@
1#include "mpeg3private.h"
2#include "mpeg3protos.h"
3
4#ifndef _WIN32
5#include <mntent.h>
6#else
7
8#endif
9#include <sys/stat.h>
10#include <stdlib.h>
11#include <string.h>
12
13mpeg3_fs_t* mpeg3_new_fs(char *path)
14{
15 mpeg3_fs_t *fs = (mpeg3_fs_t*)calloc(1, sizeof(mpeg3_fs_t));
16 fs->css = mpeg3_new_css();
17 strcpy(fs->path, path);
18 return fs;
19}
20
21int mpeg3_delete_fs(mpeg3_fs_t *fs)
22{
23 mpeg3_delete_css(fs->css);
24 free(fs);
25 return 0;
26}
27
28int mpeg3_copy_fs(mpeg3_fs_t *dst, mpeg3_fs_t *src)
29{
30 strcpy(dst->path, src->path);
31 dst->current_byte = 0;
32 return 0;
33}
34
35long mpeg3io_get_total_bytes(mpeg3_fs_t *fs)
36{
37/*
38 * struct stat st;
39 * if(stat(fs->path, &st) < 0) return 0;
40 * return (long)st.st_size;
41 */
42
43 fseek(fs->fd, 0, SEEK_END);
44 fs->total_bytes = ftell(fs->fd);
45 fseek(fs->fd, 0, SEEK_SET);
46 return fs->total_bytes;
47}
48
49int mpeg3io_open_file(mpeg3_fs_t *fs)
50{
51/* Need to perform authentication before reading a single byte. */
52 mpeg3_get_keys(fs->css, fs->path);
53
54 if(!(fs->fd = fopen(fs->path, "rb")))
55 {
56 perror("mpeg3io_open_file");
57 return 1;
58 }
59
60 fs->total_bytes = mpeg3io_get_total_bytes(fs);
61
62 if(!fs->total_bytes)
63 {
64 fclose(fs->fd);
65 return 1;
66 }
67 fs->current_byte = 0;
68 return 0;
69}
70
71int mpeg3io_close_file(mpeg3_fs_t *fs)
72{
73 if(fs->fd) fclose(fs->fd);
74 fs->fd = 0;
75 return 0;
76}
77
78int mpeg3io_read_data(unsigned char *buffer, long bytes, mpeg3_fs_t *fs)
79{
80 int result = 0;
81//printf("read %d bytes\n",bytes);
82 result = !fread(buffer, 1, bytes, fs->fd);
83 fs->current_byte += bytes;
84 return (result && bytes);
85}
86
87int mpeg3io_device(char *path, char *device)
88{
89 struct stat file_st, device_st;
90 struct mntent *mnt;
91 FILE *fp;
92
93 if(stat(path, &file_st) < 0)
94 {
95 perror("mpeg3io_device");
96 return 1;
97 }
98
99#ifndef _WIN32
100 fp = setmntent(MOUNTED, "r");
101 while(fp && (mnt = getmntent(fp)))
102 {
103 if(stat(mnt->mnt_fsname, &device_st) < 0) continue;
104 if(device_st.st_rdev == file_st.st_dev)
105 {
106 strncpy(device, mnt->mnt_fsname, MPEG3_STRLEN);
107 break;
108 }
109 }
110 endmntent(fp);
111#endif
112
113 return 0;
114}
115
116int mpeg3io_seek(mpeg3_fs_t *fs, long byte)
117{
118 fs->current_byte = byte;
119 return fseek(fs->fd, byte, SEEK_SET);
120}
121
122int mpeg3io_seek_relative(mpeg3_fs_t *fs, long bytes)
123{
124 fs->current_byte += bytes;
125 return fseek(fs->fd, fs->current_byte, SEEK_SET);
126}
127
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef MPEG3IO_H
21#define MPEG3IO_H
22
23
24#include <stdio.h>
25#include "mpeg3css.h"
26#include "mpeg3private.inc"
27
28/* Filesystem structure */
29
30typedef struct
31{
32 FILE *fd;
33 mpeg3_css_t *css; /* Encryption object */
34 char path[MPEG3_STRLEN];
35/* Hypothetical position of file pointer */
36 long current_byte;
37 long total_bytes;
38} mpeg3_fs_t;
39
40#define mpeg3io_tell(fs) (((mpeg3_fs_t *)(fs))->current_byte)
41
42// End of file
43#define mpeg3io_eof(fs) (((mpeg3_fs_t *)(fs))->current_byte >= ((mpeg3_fs_t *)(fs))->total_bytes)
44
45// Beginning of file
46 #define mpeg3io_bof(fs)(((mpeg3_fs_t *)(fs))->current_byte < 0)
47
48
49#define mpeg3io_total_bytes(fs) (((mpeg3_fs_t *)(fs))->total_bytes)
50
51extern inline unsigned int mpeg3io_read_int32(mpeg3_fs_t *fs)
52{
53 int a, b, c, d;
54 unsigned int result;
55/* Do not fread. This breaks byte ordering. */
56 a = (unsigned char)fgetc(fs->fd);
57 b = (unsigned char)fgetc(fs->fd);
58 c = (unsigned char)fgetc(fs->fd);
59 d = (unsigned char)fgetc(fs->fd);
60 result = ((int)a << 24) |
61 ((int)b << 16) |
62 ((int)c << 8) |
63 ((int)d);
64 fs->current_byte += 4;
65 return result;
66}
67
68extern inline unsigned int mpeg3io_read_char(mpeg3_fs_t *fs)
69{
70 fs->current_byte++;
71 return fgetc(fs->fd);
72}
73
74#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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef MPEG3PRIVATE_H
21#define MPEG3PRIVATE_H
22
23#include "mpeg3atrack.h"
24#include "mpeg3css.h"
25#include "mpeg3io.h"
26#include "mpeg3private.inc"
27#include "mpeg3title.h"
28#include "mpeg3vtrack.h"
29
30struct mpeg3_rec
31{
32 mpeg3_fs_t *fs; /* Store entry path here */
33 mpeg3_demuxer_t *demuxer; /* Master tables */
34
35/* Media specific */
36 int has_audio;
37 int has_video;
38 int total_astreams;
39 int total_vstreams;
40 mpeg3_atrack_t *atrack[MPEG3_MAX_STREAMS];
41 mpeg3_vtrack_t *vtrack[MPEG3_MAX_STREAMS];
42
43/* Only one of these is set to 1 to specify what kind of stream we have. */
44 int is_transport_stream;
45 int is_program_stream;
46 int is_audio_stream; /* Elemental stream */
47 int is_video_stream; /* Elemental stream */
48 long packet_size;
49/* Type and stream for getting current percentage */
50 int last_type_read; /* 1 - audio 2 - video */
51 int last_stream_read;
52
53 int program; /* Number of program to play */
54 int cpus;
55 int have_mmx;
56};
57
58typedef struct mpeg3_rec mpeg3_t;
59
60
61
62#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 @@
1#ifndef LIBMPEG3_INC
2#define LIBMPEG3_INC
3
4#ifdef _WIN32
5
6// Disable some compiler warnings that happen a lot but don't matter
7#pragma warning( disable : 4003 ) // not enough parameters for macro
8#pragma warning( disable : 4305 ) // truncation frm double to float
9#pragma warning( disable : 4715 ) // not all control paths return a value
10#pragma warning( disable : 4716 ) // must return a value
11
12#ifdef LIBMPEG_EXPORTS
13 #define LIBMPEG_EXPORT __declspec( dllexport )
14#else
15 #define LIBMPEG_EXPORT __declspec( dllimport )
16#endif
17
18#ifdef ERROR
19#undef ERROR
20#include <windows.h>
21#undef ERROR
22#define ERROR (-1)
23#else
24#include <windows.h>
25#undef ERROR
26#endif
27
28 #define inline __inline
29 #define M_PI 3.14159265358979323846
30 #define M_SQRT2 1.41421356237309504880
31
32 #define pthread_mutexattr_t int
33#define pthread_mutexattr_init(a) // Nothing
34 #define pthread_mutex_t CRITICAL_SECTION
35 #define pthread_mutex_init(a,b) InitializeCriticalSection(a)
36 #define pthread_mutex_lock(a) EnterCriticalSection(a)
37 #define pthread_mutex_unlock(a) LeaveCriticalSection(a)
38#define pthread_mutex_destroy(a) //DeleteCriticalSection(a)
39
40 #define pthread_attr_t int
41 #define pthread_attr_init(a) // Nothing
42 #define pthread_t unsigned long
43 #define pthread_create(a,b,c,d) *(a) = _beginthread(c,0,d)
44 //#define pthread_join(a,b) _endthread(b)
45 //#define pthread_join(a,b) _cwait(NULL,b,NULL)
46#define pthread_join(a,b)
47
48 #define strncasecmp(a,b,c) _strnicmp(a,b,c)
49 #define strcasecmp(a,b) _stricmp(a,b)
50 #define bzero(a,b) memset(a,0,b)
51
52#else
53
54 #define LONGLONG long long
55 #define ULONGLONG unsigned long long
56
57#endif
58
59#ifndef LIBMPEG_EXPORT
60#define LIBMPEG_EXPORT
61#endif
62
63#define MPEG3_FLOAT32 mpeg3_real_t
64#define MPEG3_INT16 short int
65#define MPEG3_INT32 int
66#define MPEG3_INT64 long
67
68#define MPEG3_TOC_PREFIX 0x544f4356
69#define MPEG3_TOC_PREFIXLOWER 0x746f6376
70#define MPEG3_ID3_PREFIX 0x494433
71#define MPEG3_RIFF_CODE 0x52494646
72#define MPEG3_PROC_CPUINFO "/proc/cpuinfo"
73#define MPEG3_TS_PACKET_SIZE 188
74#define MPEG3_DVD_PACKET_SIZE 0x800
75#define MPEG3_SYNC_BYTE 0x47
76#define MPEG3_PACK_START_CODE 0x000001ba
77#define MPEG3_SEQUENCE_START_CODE 0x000001b3
78#define MPEG3_SEQUENCE_END_CODE 0x000001b7
79#define MPEG3_SYSTEM_START_CODE 0x000001bb
80#define MPEG3_STRLEN 1024
81#define MPEG3_PIDMAX 20 /* Maximum number of PIDs in one stream */
82#define MPEG3_PROGRAM_ASSOCIATION_TABLE 0x00
83#define MPEG3_CONDITIONAL_ACCESS_TABLE 0x01
84#define MPEG3_PACKET_START_CODE_PREFIX 0x000001
85#define MPEG3_PRIVATE_STREAM_2 0xbf
86#define MPEG3_PADDING_STREAM 0xbe
87#define MPEG3_GOP_START_CODE 0x000001b8
88#define MPEG3_PICTURE_START_CODE 0x00000100
89#define MPEG3_EXT_START_CODE 0x000001b5
90#define MPEG3_USER_START_CODE 0x000001b2
91#define MPEG3_SLICE_MIN_START 0x00000101
92#define MPEG3_SLICE_MAX_START 0x000001af
93#define MPEG3_AC3_START_CODE 0x0b77
94#define MPEG3_PCM_START_CODE 0x0180
95#define MPEG3_MAX_CPUS 256
96#define MPEG3_MAX_STREAMS 256
97#define MPEG3_MAX_PACKSIZE 262144
98#define MPEG3_CONTIGUOUS_THRESHOLD 10 /* Positive difference before declaring timecodes discontinuous */
99#define MPEG3_PROGRAM_THRESHOLD 5 /* Minimum number of seconds before interleaving programs */
100#define MPEG3_SEEK_THRESHOLD 16 /* Number of frames difference before absolute seeking */
101
102/* Values for audio format */
103#define AUDIO_UNKNOWN 0
104#define AUDIO_MPEG 1
105#define AUDIO_AC3 2
106#define AUDIO_PCM 3
107#define AUDIO_AAC 4
108#define AUDIO_JESUS 5
109
110#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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef MPEG3PROTOS_H
21#define MPEG3PROTOS_H
22
23#if defined(__cplusplus)
24extern "C" {
25#endif
26
27/* CSS */
28
29mpeg3_css_t* mpeg3_new_css();
30
31/* DEMUX */
32
33mpeg3_demuxer_t* mpeg3_new_demuxer(mpeg3_t *file, int do_audio, int do_video, int stream_id);
34int mpeg3_delete_demuxer(mpeg3_demuxer_t *demuxer);
35int mpeg3demux_read_data(mpeg3_demuxer_t *demuxer, unsigned char *output, long size);
36unsigned int mpeg3demux_read_int32(mpeg3_demuxer_t *demuxer);
37unsigned int mpeg3demux_read_int24(mpeg3_demuxer_t *demuxer);
38unsigned int mpeg3demux_read_int16(mpeg3_demuxer_t *demuxer);
39double mpeg3demux_length(mpeg3_demuxer_t *demuxer);
40mpeg3_demuxer_t* mpeg3_get_demuxer(mpeg3_t *file);
41long mpeg3demux_tell(mpeg3_demuxer_t *demuxer);
42double mpeg3demux_tell_percentage(mpeg3_demuxer_t *demuxer);
43double mpeg3demux_get_time(mpeg3_demuxer_t *demuxer);
44int mpeg3demux_eof(mpeg3_demuxer_t *demuxer);
45int mpeg3demux_bof(mpeg3_demuxer_t *demuxer);
46int mpeg3demux_copy_titles(mpeg3_demuxer_t *dst, mpeg3_demuxer_t *src);
47int mpeg3demux_create_title(mpeg3_demuxer_t *demuxer, int timecode_search, FILE *toc);
48long mpeg3demuxer_total_bytes(mpeg3_demuxer_t *demuxer);
49int mpeg3demux_seek_byte(mpeg3_demuxer_t *demuxer, long byte);
50int mpeg3demux_seek_time(mpeg3_demuxer_t *demuxer, double new_time);
51int mpeg3demux_seek_percentage(mpeg3_demuxer_t *demuxer, double percentage);
52int mpeg3demux_print_streams(mpeg3_demuxer_t *demuxer, FILE *toc);
53int mpeg3demux_print_timecodes(mpeg3_title_t *title, FILE *output);
54int mpeg3demux_read_titles(mpeg3_demuxer_t *demuxer);
55int mpeg3demux_open_title(mpeg3_demuxer_t *demuxer, int title_number);
56
57/* TITLE */
58
59mpeg3_title_t* mpeg3_new_title(mpeg3_t *file, char *path);
60int mpeg3_delete_title(mpeg3_title_t *title);
61int mpeg3_copy_title(mpeg3_title_t *dst, mpeg3_title_t *src);
62
63
64/* ATRACK */
65
66mpeg3_atrack_t* mpeg3_new_atrack(mpeg3_t *file, int stream_id, int is_ac3, mpeg3_demuxer_t *demuxer);
67int mpeg3_delete_atrack(mpeg3_t *file, mpeg3_atrack_t *atrack);
68
69/* VTRACK */
70
71mpeg3_vtrack_t* mpeg3_new_vtrack(mpeg3_t *file, int stream_id, mpeg3_demuxer_t *demuxer);
72int mpeg3_delete_vtrack(mpeg3_t *file, mpeg3_vtrack_t *vtrack);
73
74/* AUDIO */
75mpeg3audio_t* mpeg3audio_new(mpeg3_t *file, mpeg3_atrack_t *track, int is_ac3);
76int mpeg3audio_delete(mpeg3audio_t *audio);
77int mpeg3audio_seek_sample(mpeg3audio_t *audio, long sample);
78int mpeg3audio_seek_percentage(mpeg3audio_t *audio, double percentage);
79int mpeg3audio_decode_audio(mpeg3audio_t *audio,
80 mpeg3_real_t *output_f,
81 short *output_i, int sampleSpacing,
82 int channel,
83 long start_position,
84 long len);
85int mpeg3audio_read_raw(mpeg3audio_t *audio, unsigned char *output, long *size, long max_size);
86int mpeg3audio_read_ac3_header(mpeg3audio_t *audio);
87int mpeg3audio_read_pcm_header(mpeg3audio_t *audio);
88int mpeg3audio_synth_mono(mpeg3audio_t *audio, mpeg3_real_t *bandPtr, mpeg3_real_t *samples, int *pnt);
89int mpeg3audio_synth_stereo(mpeg3audio_t *audio, mpeg3_real_t *bandPtr, int channel, mpeg3_real_t *out, int *pnt);
90int mpeg3audio_replace_buffer(mpeg3audio_t *audio, long new_allocation);
91int mpeg3audio_ac3_exponent_unpack(mpeg3audio_t *audio,
92 mpeg3_ac3bsi_t *bsi,
93 mpeg3_ac3audblk_t *audblk);
94int mpeg3audio_ac3_bit_allocate(mpeg3audio_t *audio,
95 unsigned int fscod,
96 mpeg3_ac3bsi_t *bsi,
97 mpeg3_ac3audblk_t *audblk);
98int mpeg3audio_ac3_coeff_unpack(mpeg3audio_t *audio,
99 mpeg3_ac3bsi_t *bsi,
100 mpeg3_ac3audblk_t *audblk,
101 mpeg3ac3_stream_samples_t samples);
102int mpeg3audio_ac3_imdct(mpeg3audio_t *audio,
103 mpeg3_ac3bsi_t *bsi,
104 mpeg3_ac3audblk_t *audblk,
105 mpeg3ac3_stream_samples_t samples);
106int mpeg3audio_replace_buffer(mpeg3audio_t *audio, long new_allocation);
107int mpeg3audio_dct36(mpeg3_real_t *inbuf, mpeg3_real_t *o1, mpeg3_real_t *o2, mpeg3_real_t *wintab, mpeg3_real_t *tsbuf);
108int mpeg3audio_dct12(mpeg3_real_t *in,mpeg3_real_t *rawout1,mpeg3_real_t *rawout2,register mpeg3_real_t *wi,register mpeg3_real_t *ts);
109int mpeg3audio_read_header(mpeg3audio_t *audio);
110int mpeg3audio_do_ac3(mpeg3audio_t *audio);
111int mpeg3audio_dolayer2(mpeg3audio_t *audio);
112int mpeg3audio_dolayer3(mpeg3audio_t *audio);
113int mpeg3audio_do_pcm(mpeg3audio_t *audio);
114int mpeg3audio_dct64(mpeg3_real_t *a, mpeg3_real_t *b, mpeg3_real_t *c);
115int mpeg3audio_reset_synths(mpeg3audio_t *audio);
116int mpeg3audio_prev_header(mpeg3audio_t *audio);
117int mpeg3audio_read_layer3_frame(mpeg3audio_t *audio);
118int mpeg3audio_new_decode_tables(mpeg3audio_t *audio);
119int mpeg3audio_imdct_init(mpeg3audio_t *audio);
120
121
122/* VIDEO */
123mpeg3video_t* mpeg3video_new(mpeg3_t *file, mpeg3_vtrack_t *track);
124int mpeg3video_delete(mpeg3video_t *video);
125int mpeg3video_read_frame(mpeg3video_t *video,
126 long frame_number,
127 unsigned char **output_rows,
128 int in_x,
129 int in_y,
130 int in_w,
131 int in_h,
132 int out_w,
133 int out_h,
134 int color_model);
135int mpeg3video_set_cpus(mpeg3video_t *video, int cpus);
136int mpeg3video_set_mmx(mpeg3video_t *video, int use_mmx);
137int mpeg3video_seek(mpeg3video_t *video);
138int mpeg3video_seek_frame(mpeg3video_t *video, long frame);
139int mpeg3video_seek_percentage(mpeg3video_t *video, double percentage);
140int mpeg3video_previous_frame(mpeg3video_t *video);
141int mpeg3video_drop_frames(mpeg3video_t *video, long frames);
142int mpeg3video_read_yuvframe(mpeg3video_t *video,
143 long frame_number,
144 char *y_output,
145 char *u_output,
146 char *v_output,
147 int in_x,
148 int in_y,
149 int in_w,
150 int in_h);
151int mpeg3video_read_raw(mpeg3video_t *video, unsigned char *output, long *size, long max_size);
152int mpeg3video_display_second_field(mpeg3video_t *video);
153int mpeg3video_init_output();
154int mpeg3video_get_header(mpeg3video_t *video, int dont_repeat);
155int mpeg3video_getpicture(mpeg3video_t *video, int framenum);
156int mpeg3video_match_refframes(mpeg3video_t *video);
157int mpeg3video_next_code(mpeg3_bits_t* stream, unsigned int code);
158int mpeg3video_prev_code(mpeg3_bits_t* stream, unsigned int code);
159int mpeg3video_getgophdr(mpeg3video_t *video);
160int mpeg3video_present_frame(mpeg3video_t *video);
161int mpeg3video_read_frame_backend(mpeg3video_t *video, int skip_bframes);
162int mpeg3video_getslicehdr(mpeg3_slice_t *slice, mpeg3video_t *video);
163int mpeg3video_get_macroblock_address(mpeg3_slice_t *slice);
164int mpeg3video_macroblock_modes(mpeg3_slice_t *slice,
165 mpeg3video_t *video,
166 int *pmb_type,
167 int *pstwtype,
168 int *pstwclass,
169 int *pmotion_type,
170 int *pmv_count,
171 int *pmv_format,
172 int *pdmv,
173 int *pmvscale,
174 int *pdct_type);
175int mpeg3video_motion_vectors(mpeg3_slice_t *slice,
176 mpeg3video_t *video,
177 int PMV[2][2][2],
178 int dmvector[2],
179 int mv_field_sel[2][2],
180 int s,
181 int mv_count,
182 int mv_format,
183 int h_r_size,
184 int v_r_size,
185 int dmv,
186 int mvscale);
187void mpeg3video_motion_vector(mpeg3_slice_t *slice,
188 mpeg3video_t *video,
189 int *PMV,
190 int *dmvector,
191 int h_r_size,
192 int v_r_size,
193 int dmv,
194 int mvscale,
195 int full_pel_vector);
196int mpeg3video_get_cbp(mpeg3_slice_t *slice);
197int mpeg3video_clearblock(mpeg3_slice_t *slice, int comp, int size);
198int mpeg3video_getmpg2intrablock(mpeg3_slice_t *slice,
199 mpeg3video_t *video,
200 int comp,
201 int dc_dct_pred[]);
202int mpeg3video_getintrablock(mpeg3_slice_t *slice,
203 mpeg3video_t *video,
204 int comp,
205 int dc_dct_pred[]);
206int mpeg3video_getmpg2interblock(mpeg3_slice_t *slice,
207 mpeg3video_t *video,
208 int comp);
209int mpeg3video_getinterblock(mpeg3_slice_t *slice,
210 mpeg3video_t *video,
211 int comp);
212int mpeg3video_reconstruct(mpeg3video_t *video,
213 int bx,
214 int by,
215 int mb_type,
216 int motion_type,
217 int PMV[2][2][2],
218 int mv_field_sel[2][2],
219 int dmvector[2],
220 int stwtype);
221void mpeg3video_calc_dmv(mpeg3video_t *video,
222 int DMV[][2],
223 int *dmvector,
224 int mvx,
225 int mvy);
226
227
228/* FILESYSTEM */
229
230mpeg3_fs_t* mpeg3_new_fs(char *path);
231int mpeg3_delete_fs(mpeg3_fs_t *fs);
232int mpeg3io_open_file(mpeg3_fs_t *fs);
233int mpeg3io_close_file(mpeg3_fs_t *fs);
234int mpeg3io_read_data(unsigned char *buffer, long bytes, mpeg3_fs_t *fs);
235
236/* BITSTREAM */
237mpeg3_bits_t* mpeg3bits_new_stream(mpeg3_t *file, mpeg3_demuxer_t *demuxer);
238unsigned int mpeg3bits_getbits(mpeg3_bits_t* stream, int n);
239int mpeg3bits_read_buffer(mpeg3_bits_t* stream, unsigned char *buffer, int bytes);
240int mpeg3bits_use_ptr(mpeg3_bits_t* stream, unsigned char *buffer);
241int mpeg3bits_use_demuxer(mpeg3_bits_t* stream);
242int mpeg3bits_refill(mpeg3_bits_t* stream);
243int mpeg3bits_getbitoffset(mpeg3_bits_t *stream);
244void mpeg3bits_start_reverse(mpeg3_bits_t* stream);
245void mpeg3bits_start_forward(mpeg3_bits_t* stream);
246int mpeg3bits_delete_stream(mpeg3_bits_t* stream);
247int mpeg3bits_byte_align(mpeg3_bits_t *stream);
248int mpeg3bits_seek_start(mpeg3_bits_t* stream);
249int mpeg3bits_seek_time(mpeg3_bits_t* stream, double time_position);
250int mpeg3bits_seek_byte(mpeg3_bits_t* stream, long position);
251int mpeg3bits_seek_percentage(mpeg3_bits_t* stream, double percentage);
252unsigned int mpeg3bits_next_startcode(mpeg3_bits_t* stream);
253int mpeg3bits_seek_end(mpeg3_bits_t* stream);
254
255/* MISC */
256int mpeg3_read_toc(mpeg3_t *file);
257int mpeg3_generate_toc(FILE *output, char *path, int timecode_search, int print_streams);
258int mpeg3_mmx_test();
259int mpeg3io_seek(mpeg3_fs_t *fs, long byte);
260int mpeg3io_seek_relative(mpeg3_fs_t *fs, long bytes);
261int mpeg3io_device(char *path, char *device);
262int mpeg3_decrypt_packet(mpeg3_css_t *css, unsigned char *sector);
263int mpeg3_delete_css(mpeg3_css_t *css);
264int mpeg3_get_keys(mpeg3_css_t *css, char *path);
265int mpeg3_copy_fs(mpeg3_fs_t *dst, mpeg3_fs_t *src);
266int mpeg3_min(int x, int y);
267int mpeg3_max(int x, int y);
268int mpeg3_new_slice_buffer(mpeg3_slice_buffer_t *slice_buffer);
269int mpeg3_expand_slice_buffer(mpeg3_slice_buffer_t *slice_buffer);
270int mpeg3_delete_slice_decoder(mpeg3_slice_t *slice);
271int mpeg3_new_slice_decoder(mpeg3video_t *video, mpeg3_slice_t *slice);
272int mpeg3_delete_slice_buffer(mpeg3_slice_buffer_t *slice_buffer);
273
274#if defined(__cplusplus)
275}
276#endif
277
278#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 @@
1#include "mpeg3private.h"
2#include "mpeg3protos.h"
3#include "mpeg3title.h"
4
5
6#include <stdlib.h>
7
8
9mpeg3_title_t* mpeg3_new_title(mpeg3_t *file, char *path)
10{
11 mpeg3_title_t *title = (mpeg3_title_t*)calloc(1, sizeof(mpeg3_title_t));
12 title->fs = mpeg3_new_fs(path);
13 title->file = file;
14 return title;
15}
16
17int mpeg3_delete_title(mpeg3_title_t *title)
18{
19 mpeg3_delete_fs(title->fs);
20 if(title->timecode_table_size)
21 {
22 free(title->timecode_table);
23 }
24 free(title);
25 return 0;
26}
27
28
29int mpeg3_copy_title(mpeg3_title_t *dst, mpeg3_title_t *src)
30{
31 int i;
32
33 mpeg3_copy_fs(dst->fs, src->fs);
34 dst->total_bytes = src->total_bytes;
35
36 if(src->timecode_table_size)
37 {
38 dst->timecode_table_allocation = src->timecode_table_allocation;
39 dst->timecode_table_size = src->timecode_table_size;
40 dst->timecode_table = (mpeg3demux_timecode_t*)calloc(1, sizeof(mpeg3demux_timecode_t) * dst->timecode_table_allocation);
41
42 for(i = 0; i < dst->timecode_table_size; i++)
43 {
44 dst->timecode_table[i] = src->timecode_table[i];
45 }
46 }
47}
48
49int mpeg3_dump_title(mpeg3_title_t *title)
50{
51 int i;
52
53 for(i = 0; i < title->timecode_table_size; i++)
54 {
55 printf("%f: %d - %d %f %f %d\n",
56 title->timecode_table[i].absolute_start_time,
57 title->timecode_table[i].start_byte,
58 title->timecode_table[i].end_byte,
59 title->timecode_table[i].start_time,
60 title->timecode_table[i].end_time,
61 title->timecode_table[i].program);
62 }
63}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef MPEG3TITLE_H
21#define MPEG3TITLE_H
22
23#include "mpeg3io.h"
24
25typedef struct
26{
27 long start_byte;
28 double start_time;
29 double absolute_start_time;
30 double absolute_end_time;
31 long end_byte;
32 double end_time;
33 int program;
34} mpeg3demux_timecode_t;
35
36typedef struct
37{
38 struct mpeg3_rec *file;
39 mpeg3_fs_t *fs;
40 long total_bytes; /* Total bytes in file. Critical for seeking and length. */
41/* Timecode table */
42 mpeg3demux_timecode_t *timecode_table;
43 long timecode_table_size; /* Number of entries */
44 long timecode_table_allocation; /* Number of available slots */
45} mpeg3_title_t;
46
47#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 @@
1#include "libmpeg3.h"
2#include "mpeg3protos.h"
3
4#include <stdio.h>
5#include <stdlib.h>
6#include <string.h>
7#include <sys/stat.h>
8#include <stdlib.h>
9
10int main(int argc, char *argv[])
11{
12 int i;
13 /*FILE *output; */
14 char new_path[1024], *ext;
15 struct stat st;
16 long size;
17 int timecode_search = 0;
18
19 if(argc < 2)
20 {
21 fprintf(stderr, "Create a table of contents for a DVD.\n"
22 "Usage: mpeg3toc [-t] <filename>...\n"
23 "-t Perform timecode search.\n"
24 "\n"
25 "The filenames should be absolute paths unless you plan\n"
26 "to always run your movie player from the same directory\n"
27 "as the filename. Alternatively you can edit the toc by\n"
28 "hand.\n"
29 "The timecode search allows XMovie to play the Matrix.\n"
30 "Example: mpeg3toc /cd2/video_ts/vts_01_*.vob > titanic.toc\n");
31 exit(1);
32 }
33
34 for(i = 1; i < argc; i++)
35 {
36 if(!strcmp(argv[i], "-t"))
37 {
38 timecode_search = 1;
39 }
40 else
41 {
42/* Get just name */
43 ext = strrchr(argv[i], '/');
44 if(ext)
45 {
46 ext++;
47 strcpy(new_path, ext);
48 }
49 else
50 strcpy(new_path, argv[i]);
51
52
53/* Replace suffix */
54 ext = strrchr(new_path, '.');
55 if(ext)
56 {
57 sprintf(ext, ".toc");
58 }
59 else
60 strcat(new_path, ".toc");
61
62 /* fprintf(stderr, "Creating %s\n", new_path); */
63
64 stat(argv[i], &st);
65 size = (long)st.st_size;
66
67 if(!size)
68 {
69 fprintf(stderr, "%s is 0 length. Skipping\n", new_path);
70 }
71 else
72 {
73/* Just want the first title's streams */
74 if(mpeg3_generate_toc(stdout, argv[i], timecode_search, i == argc - 1))
75 {
76 fprintf(stderr, "Skipping %s\n", argv[i]);
77 }
78 }
79 }
80 }
81}
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 @@
1#include "libmpeg3.h"
2#include "mpeg3protos.h"
3
4#include <stdlib.h>
5
6mpeg3_vtrack_t* mpeg3_new_vtrack(mpeg3_t *file, int stream_id, mpeg3_demuxer_t *demuxer)
7{
8 int result = 0;
9 mpeg3_vtrack_t *new_vtrack;
10 new_vtrack = (mpeg3_vtrack_t*)calloc(1, sizeof(mpeg3_vtrack_t));
11 new_vtrack->demuxer = mpeg3_new_demuxer(file, 0, 1, stream_id);
12 if(demuxer) mpeg3demux_copy_titles(new_vtrack->demuxer, demuxer);
13 new_vtrack->current_position = 0;
14
15/* Get information about the track here. */
16 new_vtrack->video = mpeg3video_new(file, new_vtrack);
17 if(!new_vtrack->video)
18 {
19/* Failed */
20 mpeg3_delete_vtrack(file, new_vtrack);
21 new_vtrack = 0;
22 }
23 return new_vtrack;
24}
25
26int mpeg3_delete_vtrack(mpeg3_t *file, mpeg3_vtrack_t *vtrack)
27{
28 if(vtrack->video)
29 mpeg3video_delete(vtrack->video);
30 if(vtrack->demuxer)
31 mpeg3_delete_demuxer(vtrack->demuxer);
32 free(vtrack);
33}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef MPEG3_VTRACK_H
21#define MPEG3_VTRACK_H
22
23#include "mpeg3demux.h"
24#include "video/mpeg3video.h"
25
26struct mpeg3_vtrack_rec
27{
28 int width;
29 int height;
30 float frame_rate;
31 mpeg3_demuxer_t *demuxer;
32 mpeg3video_t *video;
33 long current_position; /* Number of next frame to be played */
34 long total_frames; /* Total frames in the file */
35};
36
37typedef struct mpeg3_vtrack_rec mpeg3_vtrack_t;
38
39#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 @@
1TOCVERSION 2
2PATH: /cdrom/video_ts/vts_01_1.vob
3ASTREAM: 0 2
4VSTREAM: 0 1
5ASTREAM: 1 2
6ASTREAM: 2 2
7SIZE: 1073709056
8PACKETSIZE: 2048
9REGION: 0 35557376 0.000000 51.643256
10REGION: 35559424 307005440 0.000000 440.561122
11REGION: 307007488 556705792 0.000000 423.698289
12REGION: 556707840 792827904 0.000000 423.877622
13REGION: 792829952 967956480 0.000000 292.754122
14REGION: 967958528 1073709056 0.000000 191.720711
15TOCVERSION 2
16PATH: /cdrom/video_ts/vts_01_2.vob
17ASTREAM: 0 2
18VSTREAM: 0 1
19ASTREAM: 1 2
20ASTREAM: 2 2
21SIZE: 1073709056
22PACKETSIZE: 2048
23REGION: 0 268423168 191.722344 632.760000
24REGION: 268425216 539189248 0.000000 448.729167
25REGION: 539191296 823230464 0.000000 374.061122
26REGION: 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 @@
1TOCVERSION 2
2PATH: /cdrom/video_ts/vts_01_1.vob
3SIZE: 1073709056
4PACKETSIZE: 2048
5REGION: 0 33830912 0.000000 51.643256
6REGION: 33832960 321945600 0.000000 440.561122
7REGION: 321947648 566126592 0.000000 423.698289
8REGION: 566128640 804149248 0.000000 423.877622
9REGION: 804151296 979050496 0.000000 292.754122
10REGION: 979052544 1073709056 0.000000 170.331700
11TOCVERSION 2
12PATH: /cdrom/video_ts/vts_01_2.vob
13SIZE: 1073709056
14PACKETSIZE: 2048
15REGION: 0 274845696 170.333322 632.760000
16REGION: 274847744 539138048 0.000000 448.729167
17REGION: 539140096 818880512 0.000000 374.061122
18REGION: 818882560 1073709056 0.000000 431.104722
19TOCVERSION 2
20PATH: /cdrom/video_ts/vts_01_3.vob
21SIZE: 1073709056
22PACKETSIZE: 2048
23REGION: 0 3602432 431.122100 437.362056
24REGION: 3604480 316528640 0.000000 508.150422
25REGION: 316530688 562409472 0.000000 446.758722
26REGION: 562411520 728014848 0.000000 317.737689
27REGION: 728016896 943480832 0.000000 401.809556
28REGION: 943482880 1073709056 0.000000 177.871922
29TOCVERSION 2
30PATH: /cdrom/video_ts/vts_01_4.vob
31SIZE: 1073709056
32PACKETSIZE: 2048
33REGION: 0 224798720 177.873544 496.357422
34REGION: 224800768 469219328 0.000000 431.833522
35REGION: 469221376 718004224 0.000000 426.048756
36REGION: 718006272 978356224 0.000000 411.668422
37REGION: 978358272 1073709056 0.000000 154.534211
38TOCVERSION 2
39PATH: /cdrom/video_ts/vts_01_5.vob
40ASTREAM: 0 2
41VSTREAM: 0 1
42ASTREAM: 1 2
43ASTREAM: 2 2
44SIZE: 78041088
45PACKETSIZE: 2048
46REGION: 0 78028800 154.545878 312.853122
47REGION: 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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef TIMECODE_H
21#define TIMECODE_H
22
23typedef struct
24{
25 long hour;
26 long minute;
27 long second;
28 long frame;
29} mpeg3_timecode_t;
30
31#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 @@
1include ../global_config
2export CFLAGS
3export CFLAGS_lessopt
4
5OBJS = \
6 getpicture.o \
7 headers.o \
8 idct.o \
9 macroblocks.o \
10 mmxtest.o \
11 motion.o \
12 mpeg3video.o \
13 output.o \
14 reconstruct.o \
15 seek.o \
16 slice.o \
17 vlc.o
18
19
20all: $(OBJS) $(MMXOBJS2)
21
22.c.o:
23 $(CC) -c `./c_flags` -o $@ $<
24
25.s.o:
26 $(NASM) -f elf $*.s
27
28.S.o:
29 $(CC) -S `./c_flags` $*.S
30
31clean:
32 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 @@
1#include "../libmpeg3.h"
2#include "../mpeg3protos.h"
3#include "mpeg3video.h"
4#include "vlc.h"
5
6#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
9
10int mpeg3video_get_cbp(mpeg3_slice_t *slice)
11{
12 int code;
13 mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
14
15 if((code = mpeg3slice_showbits9(slice_buffer)) >= 128)
16 {
17 code >>= 4;
18 mpeg3slice_flushbits(slice_buffer, mpeg3_CBPtab0[code].len);
19 return mpeg3_CBPtab0[code].val;
20 }
21
22 if(code >= 8)
23 {
24 code >>= 1;
25 mpeg3slice_flushbits(slice_buffer, mpeg3_CBPtab1[code].len);
26 return mpeg3_CBPtab1[code].val;
27 }
28
29 if(code < 1)
30 {
31 /* fprintf(stderr,"mpeg3video_get_cbp: invalid coded_block_pattern code\n"); */
32 slice->fault = 1;
33 return 0;
34 }
35
36 mpeg3slice_flushbits(slice_buffer, mpeg3_CBPtab2[code].len);
37 return mpeg3_CBPtab2[code].val;
38}
39
40
41/* set block to zero */
42int mpeg3video_clearblock(mpeg3_slice_t *slice, int comp, int size)
43{
44 slice->sparse[comp] = 1;
45
46/* Compiler error */
47/*
48 * for(i = 0; i < size; i++)
49 * {
50 * bzero(slice->block[comp] + sizeof(short) * 64 * i, sizeof(short) * 64);
51 * }
52 */
53
54 if(size == 6)
55 {
56 bzero(slice->block[comp], sizeof(short) * 64 * 6);
57 }
58 else
59 {
60printf("mpeg3video_clearblock size = %d\n", size);
61 memset(slice->block[comp], 0, sizeof(short) * 64 * size);
62 }
63 return 0;
64}
65
66static inline int mpeg3video_getdclum(mpeg3_slice_buffer_t *slice_buffer)
67{
68 int code, size, val;
69/* decode length */
70 code = mpeg3slice_showbits5(slice_buffer);
71
72 if(code < 31)
73 {
74 size = mpeg3_DClumtab0[code].val;
75 mpeg3slice_flushbits(slice_buffer, mpeg3_DClumtab0[code].len);
76 }
77 else
78 {
79 code = mpeg3slice_showbits9(slice_buffer) - 0x1f0;
80 size = mpeg3_DClumtab1[code].val;
81 mpeg3slice_flushbits(slice_buffer, mpeg3_DClumtab1[code].len);
82 }
83
84 if(size == 0) val = 0;
85 else
86 {
87 val = mpeg3slice_getbits(slice_buffer, size);
88 if((val & (1 << (size - 1))) == 0) val -= (1 << size) - 1;
89 }
90
91 return val;
92}
93
94
95int mpeg3video_getdcchrom(mpeg3_slice_buffer_t *slice_buffer)
96{
97 int code, size, val;
98
99/* decode length */
100 code = mpeg3slice_showbits5(slice_buffer);
101
102 if(code < 31)
103 {
104 size = mpeg3_DCchromtab0[code].val;
105 mpeg3slice_flushbits(slice_buffer, mpeg3_DCchromtab0[code].len);
106 }
107 else
108 {
109 code = mpeg3slice_showbits(slice_buffer, 10) - 0x3e0;
110 size = mpeg3_DCchromtab1[code].val;
111 mpeg3slice_flushbits(slice_buffer, mpeg3_DCchromtab1[code].len);
112 }
113
114 if(size == 0) val = 0;
115 else
116 {
117 val = mpeg3slice_getbits(slice_buffer, size);
118 if((val & (1 << (size - 1))) == 0) val -= (1 << size) - 1;
119 }
120
121 return val;
122}
123
124
125/* decode one intra coded MPEG-1 block */
126
127int mpeg3video_getintrablock(mpeg3_slice_t *slice,
128 mpeg3video_t *video,
129 int comp,
130 int dc_dct_pred[])
131{
132 int val, i, j, sign;
133 unsigned int code;
134 mpeg3_DCTtab_t *tab = 0;
135 short *bp = slice->block[comp];
136 mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
137
138/* decode DC coefficients */
139 if(comp < 4)
140 bp[0] = (dc_dct_pred[0] += mpeg3video_getdclum(slice_buffer)) << 3;
141 else
142 if(comp == 4)
143 bp[0] = (dc_dct_pred[1] += mpeg3video_getdcchrom(slice_buffer)) << 3;
144 else
145 bp[0] = (dc_dct_pred[2] += mpeg3video_getdcchrom(slice_buffer)) << 3;
146
147#ifdef HAVE_MMX
148 if(video->have_mmx)
149 bp[0] <<= 4;
150#endif
151
152 if(slice->fault) return 1;
153
154/* decode AC coefficients */
155 for(i = 1; ; i++)
156 {
157 code = mpeg3slice_showbits16(slice_buffer);
158 if(code >= 16384)
159 tab = &mpeg3_DCTtabnext[(code >> 12) - 4];
160 else
161 if(code >= 1024) tab = &mpeg3_DCTtab0[(code >> 8) - 4];
162 else
163 if(code >= 512) tab = &mpeg3_DCTtab1[(code >> 6) - 8];
164 else
165 if(code >= 256) tab = &mpeg3_DCTtab2[(code >> 4) - 16];
166 else
167 if(code >= 128) tab = &mpeg3_DCTtab3[(code >> 3) - 16];
168 else
169 if(code >= 64) tab = &mpeg3_DCTtab4[(code >> 2) - 16];
170 else
171 if(code >= 32) tab = &mpeg3_DCTtab5[(code >> 1) - 16];
172 else
173 if(code >= 16) tab = &mpeg3_DCTtab6[code - 16];
174 else
175 {
176 /* fprintf(stderr, "mpeg3video_getintrablock: invalid Huffman code\n"); */
177 slice->fault = 1;
178 return 1;
179 }
180
181 mpeg3slice_flushbits(slice_buffer, tab->len);
182
183 if(tab->run == 64) break; /* end_of_block */
184
185 if(tab->run == 65)
186 {
187/* escape */
188 i += mpeg3slice_getbits(slice_buffer, 6);
189
190 if((val = mpeg3slice_getbits(slice_buffer, 8)) == 0)
191 val = mpeg3slice_getbits(slice_buffer, 8);
192 else
193 if(val == 128)
194 val = mpeg3slice_getbits(slice_buffer, 8) - 256;
195 else
196 if(val > 128)
197 val -= 256;
198
199 if((sign = (val < 0)) != 0) val= -val;
200 }
201 else
202 {
203 i += tab->run;
204 val = tab->level;
205 sign = mpeg3slice_getbit(slice_buffer);
206 }
207
208 if(i < 64)
209 j = video->mpeg3_zigzag_scan_table[i];
210 else
211 {
212 slice->fault = 1;
213 return 1;
214 }
215
216
217#ifdef HAVE_MMX
218 if(video->have_mmx)
219 {
220 val = (val * slice->quant_scale * video->intra_quantizer_matrix[j]) << 1;
221 val = (val - 16) | 16;
222 }
223 else
224#endif
225 {
226 val = (val * slice->quant_scale * video->intra_quantizer_matrix[j]) >> 3;
227 val = (val - 1) | 1;
228 }
229
230 bp[j] = sign ? -val : val;
231 }
232
233 if(j != 0)
234 {
235/* not a sparse matrix ! */
236 slice->sparse[comp] = 0;
237 }
238 return 0;
239}
240
241
242/* decode one non-intra coded MPEG-1 block */
243
244int mpeg3video_getinterblock(mpeg3_slice_t *slice,
245 mpeg3video_t *video,
246 int comp)
247{
248 int val, i, j, sign;
249 unsigned int code;
250 mpeg3_DCTtab_t *tab;
251 short *bp = slice->block[comp];
252 mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
253
254/* decode AC coefficients */
255 for(i = 0; ; i++)
256 {
257 code = mpeg3slice_showbits16(slice_buffer);
258 if(code >= 16384)
259 {
260 if(i == 0)
261 tab = &mpeg3_DCTtabfirst[(code >> 12) - 4];
262 else
263 tab = &mpeg3_DCTtabnext[(code >> 12) - 4];
264 }
265 else
266 if(code >= 1024) tab = &mpeg3_DCTtab0[(code >> 8) - 4];
267 else
268 if(code >= 512) tab = &mpeg3_DCTtab1[(code >> 6) - 8];
269 else
270 if(code >= 256) tab = &mpeg3_DCTtab2[(code >> 4) - 16];
271 else
272 if(code >= 128) tab = &mpeg3_DCTtab3[(code >> 3) - 16];
273 else
274 if(code >= 64) tab = &mpeg3_DCTtab4[(code >> 2) - 16];
275 else
276 if(code >= 32) tab = &mpeg3_DCTtab5[(code >> 1) - 16];
277 else
278 if(code >= 16) tab = &mpeg3_DCTtab6[code - 16];
279 else
280 {
281// invalid Huffman code
282 slice->fault = 1;
283 return 1;
284 }
285
286 mpeg3slice_flushbits(slice_buffer, tab->len);
287
288/* end of block */
289 if(tab->run == 64)
290 break;
291
292 if(tab->run == 65)
293 {
294/* escape */
295 i += mpeg3slice_getbits(slice_buffer, 6);
296 if((val = mpeg3slice_getbits(slice_buffer, 8)) == 0)
297 val = mpeg3slice_getbits(slice_buffer, 8);
298 else
299 if(val == 128)
300 val = mpeg3slice_getbits(slice_buffer, 8) - 256;
301 else
302 if(val > 128)
303 val -= 256;
304
305 if((sign = (val < 0)) != 0) val = -val;
306 }
307 else
308 {
309 i += tab->run;
310 val = tab->level;
311 sign = mpeg3slice_getbit(slice_buffer);
312 }
313
314 j = video->mpeg3_zigzag_scan_table[i];
315
316#ifdef HAVE_MMX
317 if(video->have_mmx)
318 {
319 val = (((val << 1)+1) * slice->quant_scale * video->non_intra_quantizer_matrix[j]);
320 val = (val - 16) | 16;
321 }
322 else
323#endif
324 {
325 val = (((val << 1)+1) * slice->quant_scale * video->non_intra_quantizer_matrix[j]) >> 4;
326 val = (val - 1) | 1;
327 }
328
329 bp[j] = sign ? -val : val;
330 }
331
332 if(j != 0)
333 {
334/* not a sparse matrix ! */
335 slice->sparse[comp] = 0;
336 }
337 return 0;
338}
339
340
341/* decode one intra coded MPEG-2 block */
342int mpeg3video_getmpg2intrablock(mpeg3_slice_t *slice,
343 mpeg3video_t *video,
344 int comp,
345 int dc_dct_pred[])
346{
347 int val, i, j, sign, nc;
348 unsigned int code;
349 mpeg3_DCTtab_t *tab;
350 short *bp;
351 int *qmat;
352 mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
353
354/* with data partitioning, data always goes to base layer */
355 bp = slice->block[comp];
356
357 qmat = (comp < 4 || video->chroma_format == CHROMA420)
358 ? video->intra_quantizer_matrix
359 : video->chroma_intra_quantizer_matrix;
360
361/* decode DC coefficients */
362 if(comp < 4)
363 val = (dc_dct_pred[0] += mpeg3video_getdclum(slice_buffer));
364 else
365 if((comp & 1) == 0)
366 val = (dc_dct_pred[1] += mpeg3video_getdcchrom(slice_buffer));
367 else
368 val = (dc_dct_pred[2] += mpeg3video_getdcchrom(slice_buffer));
369
370 if(slice->fault) return 1;
371#ifdef HAVE_MMX
372 if(video->have_mmx)
373 bp[0] = val << (7 - video->dc_prec);
374 else
375#endif
376 bp[0] = val << (3 - video->dc_prec);
377
378 nc = 0;
379
380/* decode AC coefficients */
381 for(i = 1; ; i++)
382 {
383 code = mpeg3slice_showbits16(slice_buffer);
384
385 if(code >= 16384 && !video->intravlc)
386 tab = &mpeg3_DCTtabnext[(code >> 12) - 4];
387 else
388 if(code >= 1024)
389 {
390 if(video->intravlc)
391 tab = &mpeg3_DCTtab0a[(code >> 8) - 4];
392 else
393 tab = &mpeg3_DCTtab0[(code >> 8) - 4];
394 }
395 else
396 if(code >= 512)
397 {
398 if(video->intravlc)
399 tab = &mpeg3_DCTtab1a[(code >> 6) - 8];
400 else
401 tab = &mpeg3_DCTtab1[(code >> 6) - 8];
402 }
403 else
404 if(code >= 256) tab = &mpeg3_DCTtab2[(code >> 4) - 16];
405 else
406 if(code >= 128) tab = &mpeg3_DCTtab3[(code >> 3) - 16];
407 else
408 if(code >= 64) tab = &mpeg3_DCTtab4[(code >> 2) - 16];
409 else
410 if(code >= 32) tab = &mpeg3_DCTtab5[(code >> 1) - 16];
411 else
412 if(code >= 16) tab = &mpeg3_DCTtab6[code - 16];
413 else
414 {
415 /* fprintf(stderr,"mpeg3video_getmpg2intrablock: invalid Huffman code\n"); */
416 slice->fault = 1;
417 return 1;
418 }
419
420 mpeg3slice_flushbits(slice_buffer, tab->len);
421
422/* end_of_block */
423 if(tab->run == 64)
424 break;
425
426 if(tab->run == 65)
427 {
428/* escape */
429 i += mpeg3slice_getbits(slice_buffer, 6);
430
431 val = mpeg3slice_getbits(slice_buffer, 12);
432 if((val & 2047) == 0)
433 {
434// invalid signed_level (escape)
435 slice->fault = 1;
436 return 1;
437 }
438 if((sign = (val >= 2048)) != 0) val = 4096 - val;
439 }
440 else
441 {
442 i += tab->run;
443 val = tab->level;
444 sign = mpeg3slice_getbit(slice_buffer);
445 }
446
447 j = (video->altscan ? video->mpeg3_alternate_scan_table : video->mpeg3_zigzag_scan_table)[i];
448
449#ifdef HAVE_MMX
450 if(video->have_mmx)
451 val = (val * slice->quant_scale * qmat[j]);
452 else
453#endif
454 val = (val * slice->quant_scale * qmat[j]) >> 4;
455
456 bp[j] = sign ? -val : val;
457 nc++;
458 }
459
460 if(j != 0)
461 {
462/* not a sparse matrix ! */
463 slice->sparse[comp] = 0;
464 }
465 return 1;
466}
467
468
469/* decode one non-intra coded MPEG-2 block */
470
471int mpeg3video_getmpg2interblock(mpeg3_slice_t *slice,
472 mpeg3video_t *video,
473 int comp)
474{
475 int val, i, j, sign, nc;
476 unsigned int code;
477 mpeg3_DCTtab_t *tab;
478 short *bp;
479 int *qmat;
480 mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
481
482/* with data partitioning, data always goes to base layer */
483 bp = slice->block[comp];
484
485 qmat = (comp < 4 || video->chroma_format == CHROMA420)
486 ? video->non_intra_quantizer_matrix
487 : video->chroma_non_intra_quantizer_matrix;
488
489 nc = 0;
490
491/* decode AC coefficients */
492 for(i = 0; ; i++)
493 {
494 code = mpeg3slice_showbits16(slice_buffer);
495 if(code >= 16384)
496 {
497 if(i == 0) tab = &mpeg3_DCTtabfirst[(code >> 12) - 4];
498 else tab = &mpeg3_DCTtabnext[(code >> 12) - 4];
499 }
500 else
501 if(code >= 1024) tab = &mpeg3_DCTtab0[(code >> 8) - 4];
502 else
503 if(code >= 512) tab = &mpeg3_DCTtab1[(code >> 6) - 8];
504 else
505 if(code >= 256) tab = &mpeg3_DCTtab2[(code >> 4) - 16];
506 else
507 if(code >= 128) tab = &mpeg3_DCTtab3[(code >> 3) - 16];
508 else
509 if(code >= 64) tab = &mpeg3_DCTtab4[(code >> 2) - 16];
510 else
511 if(code >= 32) tab = &mpeg3_DCTtab5[(code >> 1) - 16];
512 else
513 if(code >= 16) tab = &mpeg3_DCTtab6[code - 16];
514 else
515 {
516// invalid Huffman code
517 slice->fault = 1;
518 return 1;
519 }
520
521 mpeg3slice_flushbits(slice_buffer, tab->len);
522
523/* end_of_block */
524 if(tab->run == 64)
525 break;
526
527 if(tab->run == 65)
528 {
529/* escape */
530 i += mpeg3slice_getbits(slice_buffer, 6);
531 val = mpeg3slice_getbits(slice_buffer, 12);
532 if((val & 2047) == 0)
533 {
534 /* fprintf(stderr, "mpeg3video_getmpg2interblock: invalid signed_level (escape)\n"); */
535 slice->fault = 1;
536 return 1;
537 }
538 if((sign = (val >= 2048)) != 0) val = 4096 - val;
539 }
540 else
541 {
542 i += tab->run;
543 val = tab->level;
544 sign = mpeg3slice_getbit(slice_buffer);
545 }
546
547 j = (video->altscan ? video->mpeg3_alternate_scan_table : video->mpeg3_zigzag_scan_table)[i];
548
549#ifdef HAVE_MMX
550 if(video->have_mmx)
551 val = (((val << 1)+1) * slice->quant_scale * qmat[j]) >> 1;
552 else
553#endif
554 val = (((val << 1)+1) * slice->quant_scale * qmat[j]) >> 5;
555
556 bp[j] = sign ? (-val) : val ;
557 nc++;
558 }
559
560 if(j != 0)
561 {
562 slice->sparse[comp] = 0;
563 }
564 return 0;
565}
566
567
568/* decode all macroblocks of the current picture */
569int mpeg3video_get_macroblocks(mpeg3video_t *video, int framenum)
570{
571 unsigned int code;
572 mpeg3_slice_buffer_t *slice_buffer; /* Buffer being loaded */
573 int i;
574 int current_buffer;
575 mpeg3_bits_t *vstream = video->vstream;
576
577/* Load every slice into a buffer array */
578 video->total_slice_buffers = 0;
579 current_buffer = 0;
580 while(!mpeg3bits_eof(vstream) &&
581 mpeg3bits_showbits32_noptr(vstream) >= MPEG3_SLICE_MIN_START &&
582 mpeg3bits_showbits32_noptr(vstream) <= MPEG3_SLICE_MAX_START)
583 {
584/* Initialize the buffer */
585 if(current_buffer >= video->slice_buffers_initialized)
586 mpeg3_new_slice_buffer(&(video->slice_buffers[video->slice_buffers_initialized++]));
587 slice_buffer = &(video->slice_buffers[current_buffer]);
588 slice_buffer->buffer_size = 0;
589 slice_buffer->current_position = 0;
590 slice_buffer->bits_size = 0;
591 slice_buffer->done = 0;
592
593/* Read the slice into the buffer including the slice start code */
594 do
595 {
596/* Expand buffer */
597 if(slice_buffer->buffer_allocation <= slice_buffer->buffer_size)
598 mpeg3_expand_slice_buffer(slice_buffer);
599
600/* Load 1 char into buffer */
601 slice_buffer->data[slice_buffer->buffer_size++] = mpeg3bits_getbyte_noptr(vstream);
602 }while(!mpeg3bits_eof(vstream) &&
603 mpeg3bits_showbits24_noptr(vstream) != MPEG3_PACKET_START_CODE_PREFIX);
604
605/* Pad the buffer to get the last macroblock */
606 if(slice_buffer->buffer_allocation <= slice_buffer->buffer_size + 4)
607 mpeg3_expand_slice_buffer(slice_buffer);
608
609 slice_buffer->data[slice_buffer->buffer_size++] = 0;
610 slice_buffer->data[slice_buffer->buffer_size++] = 0;
611 slice_buffer->data[slice_buffer->buffer_size++] = 1;
612 slice_buffer->data[slice_buffer->buffer_size++] = 0;
613 slice_buffer->bits_size = 0;
614
615 pthread_mutex_lock(&(slice_buffer->completion_lock)); fflush(stdout);
616 current_buffer++;
617 video->total_slice_buffers++;
618 }
619
620/* Run the slice decoders */
621 if(video->total_slice_buffers > 0)
622 {
623 for(i = 0; i < video->total_slice_decoders; i++)
624 {
625 if(i == 0 && video->total_slice_decoders > 1)
626 {
627 video->slice_decoders[i].current_buffer = 0;
628 video->slice_decoders[i].buffer_step = 1;
629 video->slice_decoders[i].last_buffer = (video->total_slice_buffers - 1);
630 }
631 else
632 if(i == 1)
633 {
634 video->slice_decoders[i].current_buffer = video->total_slice_buffers - 1;
635 video->slice_decoders[i].buffer_step = -1;
636 video->slice_decoders[i].last_buffer = 0;
637 }
638 else
639 {
640 video->slice_decoders[i].current_buffer = i;
641 video->slice_decoders[i].buffer_step = 1;
642 video->slice_decoders[i].last_buffer = video->total_slice_buffers - 1;
643 }
644 pthread_mutex_unlock(&(video->slice_decoders[i].input_lock));
645 }
646 }
647
648/* Wait for the slice decoders to finish */
649 if(video->total_slice_buffers > 0)
650 {
651 for(i = 0; i < video->total_slice_buffers; i++)
652 {
653 pthread_mutex_lock(&(video->slice_buffers[i].completion_lock));
654 pthread_mutex_unlock(&(video->slice_buffers[i].completion_lock));
655 }
656 }
657 return 0;
658}
659
660int mpeg3video_allocate_decoders(mpeg3video_t *video, int decoder_count)
661{
662 int i;
663 mpeg3_t *file = video->file;
664/* Get the slice decoders */
665 if(video->total_slice_decoders != file->cpus)
666 {
667 for(i = 0; i < video->total_slice_decoders; i++)
668 {
669 mpeg3_delete_slice_decoder(&video->slice_decoders[i]);
670 }
671
672 for(i = 0; i < file->cpus && i < MPEG3_MAX_CPUS; i++)
673 {
674 mpeg3_new_slice_decoder(video, &(video->slice_decoders[i]));
675 video->slice_decoders[i].thread_number = i;
676 }
677
678 video->total_slice_decoders = file->cpus;
679 }
680 return 0;
681}
682
683/* decode one frame or field picture */
684
685int mpeg3video_getpicture(mpeg3video_t *video, int framenum)
686{
687 int i, result = 0;
688 mpeg3_t *file = video->file;
689
690 if(video->pict_struct == FRAME_PICTURE && video->secondfield)
691 {
692/* recover from illegal number of field pictures */
693 video->secondfield = 0;
694 }
695
696 if(!video->mpeg2)
697 {
698 video->current_repeat = video->repeat_count = 0;
699 }
700
701 mpeg3video_allocate_decoders(video, file->cpus);
702
703 for(i = 0; i < 3; i++)
704 {
705 if(video->pict_type == B_TYPE)
706 {
707 video->newframe[i] = video->auxframe[i];
708 }
709 else
710 {
711 if(!video->secondfield && !video->current_repeat)
712 {
713/* Swap refframes for I frames */
714 unsigned char* tmp = video->oldrefframe[i];
715 video->oldrefframe[i] = video->refframe[i];
716 video->refframe[i] = tmp;
717 }
718
719 video->newframe[i] = video->refframe[i];
720 }
721
722 if(video->pict_struct == BOTTOM_FIELD)
723 {
724/* Only used if fields are in different pictures */
725 video->newframe[i] += (i == 0) ? video->coded_picture_width : video->chrom_width;
726 }
727 }
728
729/* The problem is when a B frame lands on the first repeat and is skipped, */
730/* the second repeat goes for the same bitmap as the skipped repeat, */
731/* so it picks up a frame from 3 frames back. */
732/* The first repeat must consititutively read a B frame if its B frame is going to be */
733/* used in a later repeat. */
734 if(!video->current_repeat)
735 if(!(video->skip_bframes && video->pict_type == B_TYPE) ||
736 (video->repeat_count >= 100 + 100 * video->skip_bframes))
737 result = mpeg3video_get_macroblocks(video, framenum);
738
739/* Set the frame to display */
740 video->output_src = 0;
741 if(framenum > -1 && !result)
742 {
743 if(video->pict_struct == FRAME_PICTURE || video->secondfield)
744 {
745 if(video->pict_type == B_TYPE)
746 {
747 video->output_src = video->auxframe;
748 }
749 else
750 {
751 video->output_src = video->oldrefframe;
752 }
753 }
754 else
755 {
756 mpeg3video_display_second_field(video);
757 }
758 }
759
760 if(video->mpeg2)
761 {
762 video->current_repeat += 100;
763 }
764
765 if(video->pict_struct != FRAME_PICTURE) video->secondfield = !video->secondfield;
766 return result;
767}
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 @@
1#include "../mpeg3demux.h"
2#include "../libmpeg3.h"
3#include "../mpeg3protos.h"
4#include "mpeg3video.h"
5
6#include <stdio.h>
7#include <stdlib.h>
8
9int mpeg3video_getseqhdr(mpeg3video_t *video)
10{
11 int i;
12 mpeg3_t *file = video->file;
13
14 int aspect_ratio, picture_rate, vbv_buffer_size;
15 int constrained_parameters_flag;
16 int load_intra_quantizer_matrix, load_non_intra_quantizer_matrix;
17
18 video->horizontal_size = mpeg3bits_getbits(video->vstream, 12);
19 video->vertical_size = mpeg3bits_getbits(video->vstream, 12);
20 aspect_ratio = mpeg3bits_getbits(video->vstream, 4);
21 video->framerate_code = mpeg3bits_getbits(video->vstream, 4);
22 video->bitrate = mpeg3bits_getbits(video->vstream, 18);
23 mpeg3bits_getbit_noptr(video->vstream); /* marker bit (=1) */
24 vbv_buffer_size = mpeg3bits_getbits(video->vstream, 10);
25 constrained_parameters_flag = mpeg3bits_getbit_noptr(video->vstream);
26 video->frame_rate = mpeg3_frame_rate_table[video->framerate_code];
27
28 load_intra_quantizer_matrix = mpeg3bits_getbit_noptr(video->vstream);
29 if(load_intra_quantizer_matrix)
30 {
31 for(i = 0; i < 64; i++)
32 video->intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]] = mpeg3bits_getbyte_noptr(video->vstream);
33 }
34 else
35 {
36 for(i = 0; i < 64; i++)
37 video->intra_quantizer_matrix[i] = mpeg3_default_intra_quantizer_matrix[i];
38 }
39
40 load_non_intra_quantizer_matrix = mpeg3bits_getbit_noptr(video->vstream);
41 if(load_non_intra_quantizer_matrix)
42 {
43 for(i = 0; i < 64; i++)
44 video->non_intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]] = mpeg3bits_getbyte_noptr(video->vstream);
45 }
46 else
47 {
48 for(i = 0; i < 64; i++)
49 video->non_intra_quantizer_matrix[i] = 16;
50 }
51
52/* copy luminance to chrominance matrices */
53 for(i = 0; i < 64; i++)
54 {
55 video->chroma_intra_quantizer_matrix[i] = video->intra_quantizer_matrix[i];
56 video->chroma_non_intra_quantizer_matrix[i] = video->non_intra_quantizer_matrix[i];
57 }
58
59 return 0;
60}
61
62
63/* decode sequence extension */
64
65int mpeg3video_sequence_extension(mpeg3video_t *video)
66{
67 int prof_lev;
68 int horizontal_size_extension, vertical_size_extension;
69 int bit_rate_extension, vbv_buffer_size_extension, low_delay;
70 int frame_rate_extension_n, frame_rate_extension_d;
71 int pos = 0;
72
73 video->mpeg2 = 1;
74 video->scalable_mode = SC_NONE; /* unless overwritten by seq. scal. ext. */
75 prof_lev = mpeg3bits_getbyte_noptr(video->vstream);
76 video->prog_seq = mpeg3bits_getbit_noptr(video->vstream);
77 video->chroma_format = mpeg3bits_getbits(video->vstream, 2);
78 horizontal_size_extension = mpeg3bits_getbits(video->vstream, 2);
79 vertical_size_extension = mpeg3bits_getbits(video->vstream, 2);
80 bit_rate_extension = mpeg3bits_getbits(video->vstream, 12);
81 mpeg3bits_getbit_noptr(video->vstream);
82 vbv_buffer_size_extension = mpeg3bits_getbyte_noptr(video->vstream);
83 low_delay = mpeg3bits_getbit_noptr(video->vstream);
84 frame_rate_extension_n = mpeg3bits_getbits(video->vstream, 2);
85 frame_rate_extension_d = mpeg3bits_getbits(video->vstream, 5);
86 video->horizontal_size = (horizontal_size_extension << 12) | (video->horizontal_size & 0x0fff);
87 video->vertical_size = (vertical_size_extension << 12) | (video->vertical_size & 0x0fff);
88}
89
90
91/* decode sequence display extension */
92
93int mpeg3video_sequence_display_extension(mpeg3video_t *video)
94{
95 int colour_primaries = 0, transfer_characteristics = 0;
96 int display_horizontal_size, display_vertical_size;
97 int pos = 0;
98 int video_format = mpeg3bits_getbits(video->vstream, 3);
99 int colour_description = mpeg3bits_getbit_noptr(video->vstream);
100
101 if(colour_description)
102 {
103 colour_primaries = mpeg3bits_getbyte_noptr(video->vstream);
104 transfer_characteristics = mpeg3bits_getbyte_noptr(video->vstream);
105 video->matrix_coefficients = mpeg3bits_getbyte_noptr(video->vstream);
106 }
107
108 display_horizontal_size = mpeg3bits_getbits(video->vstream, 14);
109 mpeg3bits_getbit_noptr(video->vstream);
110 display_vertical_size = mpeg3bits_getbits(video->vstream, 14);
111}
112
113
114/* decode quant matrix entension */
115
116int mpeg3video_quant_matrix_extension(mpeg3video_t *video)
117{
118 int i;
119 int load_intra_quantiser_matrix, load_non_intra_quantiser_matrix;
120 int load_chroma_intra_quantiser_matrix;
121 int load_chroma_non_intra_quantiser_matrix;
122 int pos = 0;
123
124 if((load_intra_quantiser_matrix = mpeg3bits_getbit_noptr(video->vstream)) != 0)
125 {
126 for(i = 0; i < 64; i++)
127 {
128 video->chroma_intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]]
129 = video->intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]]
130 = mpeg3bits_getbyte_noptr(video->vstream);
131 }
132 }
133
134 if((load_non_intra_quantiser_matrix = mpeg3bits_getbit_noptr(video->vstream)) != 0)
135 {
136 for (i = 0; i < 64; i++)
137 {
138 video->chroma_non_intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]]
139 = video->non_intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]]
140 = mpeg3bits_getbyte_noptr(video->vstream);
141 }
142 }
143
144 if((load_chroma_intra_quantiser_matrix = mpeg3bits_getbit_noptr(video->vstream)) != 0)
145 {
146 for(i = 0; i < 64; i++)
147 video->chroma_intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]] = mpeg3bits_getbyte_noptr(video->vstream);
148 }
149
150 if((load_chroma_non_intra_quantiser_matrix = mpeg3bits_getbit_noptr(video->vstream)) != 0)
151 {
152 for(i = 0; i < 64; i++)
153 video->chroma_non_intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]] = mpeg3bits_getbyte_noptr(video->vstream);
154 }
155}
156
157
158/* decode sequence scalable extension */
159
160int mpeg3video_sequence_scalable_extension(mpeg3video_t *video)
161{
162 int layer_id;
163
164 video->scalable_mode = mpeg3bits_getbits(video->vstream, 2) + 1; /* add 1 to make SC_DP != SC_NONE */
165 layer_id = mpeg3bits_getbits(video->vstream, 4);
166
167 if(video->scalable_mode == SC_SPAT)
168 {
169 video->llw = mpeg3bits_getbits(video->vstream, 14); /* lower_layer_prediction_horizontal_size */
170 mpeg3bits_getbit_noptr(video->vstream);
171 video->llh = mpeg3bits_getbits(video->vstream, 14); /* lower_layer_prediction_vertical_size */
172 video->hm = mpeg3bits_getbits(video->vstream, 5);
173 video->hn = mpeg3bits_getbits(video->vstream, 5);
174 video->vm = mpeg3bits_getbits(video->vstream, 5);
175 video->vn = mpeg3bits_getbits(video->vstream, 5);
176 }
177
178 if(video->scalable_mode == SC_TEMP)
179 fprintf(stderr, "mpeg3video_sequence_scalable_extension: temporal scalability not implemented\n");
180}
181
182
183/* decode picture display extension */
184
185int mpeg3video_picture_display_extension(mpeg3video_t *video)
186{
187 int n, i;
188 short frame_centre_horizontal_offset[3];
189 short frame_centre_vertical_offset[3];
190
191 if(video->prog_seq || video->pict_struct != FRAME_PICTURE)
192 n = 1;
193 else
194 n = video->repeatfirst ? 3 : 2;
195
196 for(i = 0; i < n; i++)
197 {
198 frame_centre_horizontal_offset[i] = (short)mpeg3bits_getbits(video->vstream, 16);
199 mpeg3bits_getbit_noptr(video->vstream);
200 frame_centre_vertical_offset[i] = (short)mpeg3bits_getbits(video->vstream, 16);
201 mpeg3bits_getbit_noptr(video->vstream);
202 }
203}
204
205
206/* decode picture coding extension */
207
208int mpeg3video_picture_coding_extension(mpeg3video_t *video)
209{
210 int chroma_420_type, composite_display_flag;
211 int v_axis = 0, field_sequence = 0, sub_carrier = 0, burst_amplitude = 0, sub_carrier_phase = 0;
212
213 video->h_forw_r_size = mpeg3bits_getbits(video->vstream, 4) - 1;
214 video->v_forw_r_size = mpeg3bits_getbits(video->vstream, 4) - 1;
215 video->h_back_r_size = mpeg3bits_getbits(video->vstream, 4) - 1;
216 video->v_back_r_size = mpeg3bits_getbits(video->vstream, 4) - 1;
217 video->dc_prec = mpeg3bits_getbits(video->vstream, 2);
218 video->pict_struct = mpeg3bits_getbits(video->vstream, 2);
219 video->topfirst = mpeg3bits_getbit_noptr(video->vstream);
220 video->frame_pred_dct = mpeg3bits_getbit_noptr(video->vstream);
221 video->conceal_mv = mpeg3bits_getbit_noptr(video->vstream);
222 video->qscale_type = mpeg3bits_getbit_noptr(video->vstream);
223 video->intravlc = mpeg3bits_getbit_noptr(video->vstream);
224 video->altscan = mpeg3bits_getbit_noptr(video->vstream);
225 video->repeatfirst = mpeg3bits_getbit_noptr(video->vstream);
226 chroma_420_type = mpeg3bits_getbit_noptr(video->vstream);
227 video->prog_frame = mpeg3bits_getbit_noptr(video->vstream);
228
229 if(video->repeat_count > 100)
230 video->repeat_count = 0;
231 video->repeat_count += 100;
232
233 video->current_repeat = 0;
234
235 if(video->prog_seq)
236 {
237 if(video->repeatfirst)
238 {
239 if(video->topfirst)
240 video->repeat_count += 200;
241 else
242 video->repeat_count += 100;
243 }
244 }
245 else
246 if(video->prog_frame)
247 {
248 if(video->repeatfirst)
249 {
250 video->repeat_count += 50;
251 }
252 }
253
254/*printf("mpeg3video_picture_coding_extension %d\n", video->repeat_count); */
255 composite_display_flag = mpeg3bits_getbit_noptr(video->vstream);
256
257 if(composite_display_flag)
258 {
259 v_axis = mpeg3bits_getbit_noptr(video->vstream);
260 field_sequence = mpeg3bits_getbits(video->vstream, 3);
261 sub_carrier = mpeg3bits_getbit_noptr(video->vstream);
262 burst_amplitude = mpeg3bits_getbits(video->vstream, 7);
263 sub_carrier_phase = mpeg3bits_getbyte_noptr(video->vstream);
264 }
265}
266
267
268/* decode picture spatial scalable extension */
269
270int mpeg3video_picture_spatial_scalable_extension(mpeg3video_t *video)
271{
272 video->pict_scal = 1; /* use spatial scalability in this picture */
273
274 video->lltempref = mpeg3bits_getbits(video->vstream, 10);
275 mpeg3bits_getbit_noptr(video->vstream);
276 video->llx0 = mpeg3bits_getbits(video->vstream, 15);
277 if(video->llx0 >= 16384) video->llx0 -= 32768;
278 mpeg3bits_getbit_noptr(video->vstream);
279 video->lly0 = mpeg3bits_getbits(video->vstream, 15);
280 if(video->lly0 >= 16384) video->lly0 -= 32768;
281 video->stwc_table_index = mpeg3bits_getbits(video->vstream, 2);
282 video->llprog_frame = mpeg3bits_getbit_noptr(video->vstream);
283 video->llfieldsel = mpeg3bits_getbit_noptr(video->vstream);
284}
285
286
287/* decode picture temporal scalable extension
288 *
289 * not implemented
290 *
291 */
292
293int mpeg3video_picture_temporal_scalable_extension(mpeg3video_t *video)
294{
295 fprintf(stderr, "mpeg3video_picture_temporal_scalable_extension: temporal scalability not supported\n");
296}
297
298
299/* decode extension and user data */
300
301int mpeg3video_ext_user_data(mpeg3video_t *video)
302{
303 int code = mpeg3bits_next_startcode(video->vstream);
304
305
306 while(code == MPEG3_EXT_START_CODE || code == MPEG3_USER_START_CODE &&
307 !mpeg3bits_eof(video->vstream))
308 {
309 mpeg3bits_refill(video->vstream);
310
311 if(code == MPEG3_EXT_START_CODE)
312 {
313 int ext_id = mpeg3bits_getbits(video->vstream, 4);
314 switch(ext_id)
315 {
316 case SEQ_ID:
317 mpeg3video_sequence_extension(video);
318 break;
319 case DISP_ID:
320 mpeg3video_sequence_display_extension(video);
321 break;
322 case QUANT_ID:
323 mpeg3video_quant_matrix_extension(video);
324 break;
325 case SEQSCAL_ID:
326 mpeg3video_sequence_scalable_extension(video);
327 break;
328 case PANSCAN_ID:
329 mpeg3video_picture_display_extension(video);
330 break;
331 case CODING_ID:
332 mpeg3video_picture_coding_extension(video);
333 break;
334 case SPATSCAL_ID:
335 mpeg3video_picture_spatial_scalable_extension(video);
336 break;
337 case TEMPSCAL_ID:
338 mpeg3video_picture_temporal_scalable_extension(video);
339 break;
340 default:
341 fprintf(stderr,"mpeg3video_ext_user_data: reserved extension start code ID %d\n", ext_id);
342 break;
343 }
344 }
345 code = mpeg3bits_next_startcode(video->vstream);
346 }
347}
348
349
350/* decode group of pictures header */
351
352int mpeg3video_getgophdr(mpeg3video_t *video)
353{
354 int drop_flag, closed_gop, broken_link;
355
356 drop_flag = mpeg3bits_getbit_noptr(video->vstream);
357 video->gop_timecode.hour = mpeg3bits_getbits(video->vstream, 5);
358 video->gop_timecode.minute = mpeg3bits_getbits(video->vstream, 6);
359 mpeg3bits_getbit_noptr(video->vstream);
360 video->gop_timecode.second = mpeg3bits_getbits(video->vstream, 6);
361 video->gop_timecode.frame = mpeg3bits_getbits(video->vstream, 6);
362 closed_gop = mpeg3bits_getbit_noptr(video->vstream);
363 broken_link = mpeg3bits_getbit_noptr(video->vstream);
364
365/*
366 * 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,
367 * drop_flag, closed_gop, broken_link);
368 */
369 return mpeg3bits_error(video->vstream);
370}
371
372/* decode picture header */
373
374int mpeg3video_getpicturehdr(mpeg3video_t *video)
375{
376 int temp_ref, vbv_delay;
377
378 video->pict_scal = 0; /* unless overwritten by pict. spat. scal. ext. */
379
380 temp_ref = mpeg3bits_getbits(video->vstream, 10);
381 video->pict_type = mpeg3bits_getbits(video->vstream, 3);
382 vbv_delay = mpeg3bits_getbits(video->vstream, 16);
383
384 if(video->pict_type == P_TYPE || video->pict_type == B_TYPE)
385 {
386 video->full_forw = mpeg3bits_getbit_noptr(video->vstream);
387 video->forw_r_size = mpeg3bits_getbits(video->vstream, 3) - 1;
388 }
389
390 if(video->pict_type == B_TYPE)
391 {
392 video->full_back = mpeg3bits_getbit_noptr(video->vstream);
393 video->back_r_size = mpeg3bits_getbits(video->vstream, 3) - 1;
394 }
395
396/* get extra bit picture */
397 while(mpeg3bits_getbit_noptr(video->vstream) &&
398 !mpeg3bits_eof(video->vstream)) mpeg3bits_getbyte_noptr(video->vstream);
399 return 0;
400}
401
402
403int mpeg3video_get_header(mpeg3video_t *video, int dont_repeat)
404{
405 unsigned int code;
406
407/* a sequence header should be found before returning from `getheader' the */
408/* first time (this is to set horizontal/vertical size properly) */
409
410/* Repeat the frame until it's less than 1 count from repeat_count */
411 if(video->repeat_count - video->current_repeat >= 100 && !dont_repeat)
412 {
413 return 0;
414 }
415
416 if(dont_repeat)
417 {
418 video->repeat_count = 0;
419 video->current_repeat = 0;
420 }
421 else
422 video->repeat_count -= video->current_repeat;
423
424 while(1)
425 {
426/* look for startcode */
427 code = mpeg3bits_next_startcode(video->vstream);
428 if(mpeg3bits_eof(video->vstream)) return 1;
429 if(code != MPEG3_SEQUENCE_END_CODE) mpeg3bits_refill(video->vstream);
430
431 switch(code)
432 {
433 case MPEG3_SEQUENCE_START_CODE:
434 video->found_seqhdr = 1;
435 mpeg3video_getseqhdr(video);
436 mpeg3video_ext_user_data(video);
437 break;
438
439 case MPEG3_GOP_START_CODE:
440 mpeg3video_getgophdr(video);
441 mpeg3video_ext_user_data(video);
442 break;
443
444 case MPEG3_PICTURE_START_CODE:
445 mpeg3video_getpicturehdr(video);
446 mpeg3video_ext_user_data(video);
447 if(video->found_seqhdr) return 0; /* Exit here */
448 break;
449
450 case MPEG3_SEQUENCE_END_CODE:
451// Continue until the end
452 mpeg3bits_refill(video->vstream);
453 break;
454
455 default:
456 break;
457 }
458 }
459 return 1; /* Shouldn't be reached. */
460}
461
462int mpeg3video_ext_bit_info(mpeg3_slice_buffer_t *slice_buffer)
463{
464 while(mpeg3slice_getbit(slice_buffer)) mpeg3slice_getbyte(slice_buffer);
465 return 0;
466}
467
468/* decode slice header */
469int mpeg3video_getslicehdr(mpeg3_slice_t *slice, mpeg3video_t *video)
470{
471 int slice_vertical_position_extension, intra_slice;
472 int qs;
473
474 slice_vertical_position_extension = (video->mpeg2 && video->vertical_size > 2800) ?
475 mpeg3slice_getbits(slice->slice_buffer, 3) : 0;
476
477 if(video->scalable_mode == SC_DP) slice->pri_brk = mpeg3slice_getbits(slice->slice_buffer, 7);
478
479 qs = mpeg3slice_getbits(slice->slice_buffer, 5);
480 slice->quant_scale = video->mpeg2 ? (video->qscale_type ? mpeg3_non_linear_mquant_table[qs] : (qs << 1)) : qs;
481
482 if(mpeg3slice_getbit(slice->slice_buffer))
483 {
484 intra_slice = mpeg3slice_getbit(slice->slice_buffer);
485 mpeg3slice_getbits(slice->slice_buffer, 7);
486 mpeg3video_ext_bit_info(slice->slice_buffer);
487 }
488 else
489 intra_slice = 0;
490
491 return slice_vertical_position_extension;
492}
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 @@
1#include "idct.h"
2#include <stdlib.h>
3
4/**********************************************************/
5/* inverse two dimensional DCT, Chen-Wang algorithm */
6/* (cf. IEEE ASSP-32, pp. 803-816, Aug. 1984) */
7/* 32-bit integer arithmetic (8 bit coefficients) */
8/* 11 mults, 29 adds per DCT */
9/* sE, 18.8.91 */
10/**********************************************************/
11/* coefficients extended to 12 bit for IEEE1180-1990 */
12/* compliance sE, 2.1.94 */
13/**********************************************************/
14
15/* this code assumes >> to be a two's-complement arithmetic */
16/* right shift: (-2)>>1 == -1 , (-3)>>1 == -2 */
17
18#define W1 2841 /* 2048*sqrt(2)*cos(1*pi/16) */
19#define W2 2676 /* 2048*sqrt(2)*cos(2*pi/16) */
20#define W3 2408 /* 2048*sqrt(2)*cos(3*pi/16) */
21#define W5 1609 /* 2048*sqrt(2)*cos(5*pi/16) */
22#define W6 1108 /* 2048*sqrt(2)*cos(6*pi/16) */
23#define W7 565 /* 2048*sqrt(2)*cos(7*pi/16) */
24
25/* row (horizontal) IDCT
26 *
27 * 7 pi 1
28 * dst[k] = sum c[l] * src[l] * cos( -- * ( k + - ) * l )
29 * l=0 8 2
30 *
31 * where: c[0] = 128
32 * c[1..7] = 128*sqrt(2)
33 */
34
35int mpeg3video_idctrow(short *blk)
36{
37 int x0, x1, x2, x3, x4, x5, x6, x7, x8;
38
39 /* shortcut */
40 if (!((x1 = blk[4]<<11) | (x2 = blk[6]) | (x3 = blk[2]) |
41 (x4 = blk[1]) | (x5 = blk[7]) | (x6 = blk[5]) | (x7 = blk[3])))
42 {
43 blk[0]=blk[1]=blk[2]=blk[3]=blk[4]=blk[5]=blk[6]=blk[7]=blk[0]<<3;
44 return 0;
45 }
46
47 x0 = (blk[0]<<11) + 128; /* for proper rounding in the fourth stage */
48
49 /* first stage */
50 x8 = W7*(x4+x5);
51 x4 = x8 + (W1-W7)*x4;
52 x5 = x8 - (W1+W7)*x5;
53 x8 = W3*(x6+x7);
54 x6 = x8 - (W3-W5)*x6;
55 x7 = x8 - (W3+W5)*x7;
56
57 /* second stage */
58 x8 = x0 + x1;
59 x0 -= x1;
60 x1 = W6*(x3+x2);
61 x2 = x1 - (W2+W6)*x2;
62 x3 = x1 + (W2-W6)*x3;
63 x1 = x4 + x6;
64 x4 -= x6;
65 x6 = x5 + x7;
66 x5 -= x7;
67
68 /* third stage */
69 x7 = x8 + x3;
70 x8 -= x3;
71 x3 = x0 + x2;
72 x0 -= x2;
73 x2 = (181*(x4+x5)+128)>>8;
74 x4 = (181*(x4-x5)+128)>>8;
75
76 /* fourth stage */
77 blk[0] = (x7+x1)>>8;
78 blk[1] = (x3+x2)>>8;
79 blk[2] = (x0+x4)>>8;
80 blk[3] = (x8+x6)>>8;
81 blk[4] = (x8-x6)>>8;
82 blk[5] = (x0-x4)>>8;
83 blk[6] = (x3-x2)>>8;
84 blk[7] = (x7-x1)>>8;
85
86 return 1;
87}
88
89/* column (vertical) IDCT
90 *
91 * 7 pi 1
92 * dst[8*k] = sum c[l] * src[8*l] * cos( -- * ( k + - ) * l )
93 * l=0 8 2
94 *
95 * where: c[0] = 1/1024
96 * c[1..7] = (1/1024)*sqrt(2)
97 */
98
99int mpeg3video_idctcol(short *blk)
100{
101 int x0, x1, x2, x3, x4, x5, x6, x7, x8;
102
103 /* shortcut */
104 if (!((x1 = (blk[8 * 4]<<8)) | (x2 = blk[8 * 6]) | (x3 = blk[8 * 2]) |
105 (x4 = blk[8*1]) | (x5 = blk[8 * 7]) | (x6 = blk[8 * 5]) | (x7 = blk[8 * 3]))){
106 blk[8*0]=blk[8*1]=blk[8 * 2]=blk[8 * 3]=blk[8 * 4]=blk[8 * 5]=blk[8 * 6]=blk[8 * 7]=
107 (blk[8*0]+32)>>6;
108 return 0;
109 }
110
111 x0 = (blk[8*0]<<8) + 8192;
112
113 /* first stage */
114 x8 = W7*(x4+x5) + 4;
115 x4 = (x8+(W1-W7)*x4)>>3;
116 x5 = (x8-(W1+W7)*x5)>>3;
117 x8 = W3*(x6+x7) + 4;
118 x6 = (x8-(W3-W5)*x6)>>3;
119 x7 = (x8-(W3+W5)*x7)>>3;
120
121 /* second stage */
122 x8 = x0 + x1;
123 x0 -= x1;
124 x1 = W6*(x3+x2) + 4;
125 x2 = (x1-(W2+W6)*x2)>>3;
126 x3 = (x1+(W2-W6)*x3)>>3;
127 x1 = x4 + x6;
128 x4 -= x6;
129 x6 = x5 + x7;
130 x5 -= x7;
131
132 /* third stage */
133 x7 = x8 + x3;
134 x8 -= x3;
135 x3 = x0 + x2;
136 x0 -= x2;
137 x2 = (181 * (x4 + x5) + 128) >> 8;
138 x4 = (181 * (x4 - x5) + 128) >> 8;
139
140 /* fourth stage */
141 blk[8 * 0] = (x7 + x1) >> 14;
142 blk[8 * 1] = (x3 + x2) >> 14;
143 blk[8 * 2] = (x0 + x4) >> 14;
144 blk[8 * 3] = (x8 + x6) >> 14;
145 blk[8 * 4] = (x8 - x6) >> 14;
146 blk[8 * 5] = (x0 - x4) >> 14;
147 blk[8 * 6] = (x3 - x2) >> 14;
148 blk[8 * 7] = (x7 - x1) >> 14;
149
150 return 1;
151}
152
153
154/* two dimensional inverse discrete cosine transform */
155void mpeg3video_idct_conversion(short* block)
156{
157 int i;
158 for(i = 0; i < 8; i++) mpeg3video_idctrow(block + 8 * i);
159 for(i = 0; i < 8; i++) mpeg3video_idctcol(block + i);
160}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef IDCT_H
21#define IDCT_H
22
23
24#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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef LAYERDATA_H
21#define LAYERDATA_H
22
23typedef struct
24{
25/* sequence header */
26 int intra_quantizer_matrix[64], non_intra_quantizer_matrix[64];
27 int chroma_intra_quantizer_matrix[64], chroma_non_intra_quantizer_matrix[64];
28 int mpeg2;
29 int qscale_type, altscan; /* picture coding extension */
30 int pict_scal; /* picture spatial scalable extension */
31 int scalable_mode; /* sequence scalable extension */
32} mpeg3_layerdata_t;
33
34
35#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 @@
1#include "../libmpeg3.h"
2#include "../mpeg3protos.h"
3#include "mpeg3video.h"
4#include "slice.h"
5#include "vlc.h"
6
7#include <stdio.h>
8
9int mpeg3video_get_macroblock_address(mpeg3_slice_t *slice)
10{
11 int code, val = 0;
12 mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
13
14 while((code = mpeg3slice_showbits(slice_buffer, 11)) < 24)
15 {
16/* Is not macroblock_stuffing */
17 if(code != 15)
18 {
19/* Is macroblock_escape */
20 if(code == 8)
21 {
22 val += 33;
23 }
24 else
25 {
26 /* fprintf(stderr, "mpeg3video_get_macroblock_address: invalid macroblock_address_increment code\n"); */
27 slice->fault = 1;
28 return 1;
29 }
30 }
31
32 mpeg3slice_flushbits(slice_buffer, 11);
33 }
34
35 if(code >= 1024)
36 {
37 mpeg3slice_flushbit(slice_buffer);
38 return val + 1;
39 }
40
41 if(code >= 128)
42 {
43 code >>= 6;
44 mpeg3slice_flushbits(slice_buffer, mpeg3_MBAtab1[code].len);
45 return val + mpeg3_MBAtab1[code].val;
46 }
47
48 code -= 24;
49 mpeg3slice_flushbits(slice_buffer, mpeg3_MBAtab2[code].len);
50
51 return val + mpeg3_MBAtab2[code].val;
52}
53
54/* macroblock_type for pictures with spatial scalability */
55
56static inline int mpeg3video_getsp_imb_type(mpeg3_slice_t *slice)
57{
58// ### This looks wrong.
59// slice_buffer is used without being initialised and slice is not used
60 //mpeg3_slice_buffer_t *slice_buffer = slice_buffer;
61// I think this would make more sense and might be what is intended
62 mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
63 unsigned int code = mpeg3slice_showbits(slice_buffer, 4);
64 if(!code)
65 {
66 /* fprintf(stderr,"mpeg3video_getsp_imb_type: invalid macroblock_type code\n"); */
67 slice->fault = 1;
68 return 0;
69 }
70
71 mpeg3slice_flushbits(slice_buffer, mpeg3_spIMBtab[code].len);
72 return mpeg3_spIMBtab[code].val;
73}
74
75static inline int mpeg3video_getsp_pmb_type(mpeg3_slice_t *slice)
76{
77 mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
78 int code = mpeg3slice_showbits(slice_buffer, 7);
79 if(code < 2)
80 {
81 /* fprintf(stderr,"mpeg3video_getsp_pmb_type: invalid macroblock_type code\n"); */
82 slice->fault = 1;
83 return 0;
84 }
85
86 if(code >= 16)
87 {
88 code >>= 3;
89 mpeg3slice_flushbits(slice_buffer, mpeg3_spPMBtab0[code].len);
90
91 return mpeg3_spPMBtab0[code].val;
92 }
93
94 mpeg3slice_flushbits(slice_buffer, mpeg3_spPMBtab1[code].len);
95 return mpeg3_spPMBtab1[code].val;
96}
97
98static inline int mpeg3video_getsp_bmb_type(mpeg3_slice_t *slice)
99{
100 mpeg3_VLCtab_t *p;
101 mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
102 int code = mpeg3slice_showbits9(slice_buffer);
103
104 if(code >= 64)
105 p = &mpeg3_spBMBtab0[(code >> 5) - 2];
106 else
107 if(code >= 16)
108 p = &mpeg3_spBMBtab1[(code >> 2) - 4];
109 else
110 if(code >= 8)
111 p = &mpeg3_spBMBtab2[code - 8];
112 else
113 {
114 /* fprintf(stderr,"mpeg3video_getsp_bmb_type: invalid macroblock_type code\n"); */
115 slice->fault = 1;
116 return 0;
117 }
118
119 mpeg3slice_flushbits(slice_buffer, p->len);
120 return p->val;
121}
122
123static inline int mpeg3video_get_imb_type(mpeg3_slice_t *slice)
124{
125 mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
126 if(mpeg3slice_getbit(slice_buffer))
127 {
128 return 1;
129 }
130
131 if(!mpeg3slice_getbit(slice_buffer))
132 {
133 /* fprintf(stderr,"mpeg3video_get_imb_type: invalid macroblock_type code\n"); */
134 slice->fault = 1;
135 }
136
137 return 17;
138}
139
140static inline int mpeg3video_get_pmb_type(mpeg3_slice_t *slice)
141{
142 int code;
143 mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
144
145 if((code = mpeg3slice_showbits(slice_buffer, 6)) >= 8)
146 {
147 code >>= 3;
148 mpeg3slice_flushbits(slice_buffer, mpeg3_PMBtab0[code].len);
149 return mpeg3_PMBtab0[code].val;
150 }
151
152 if(code == 0)
153 {
154 /* fprintf(stderr,"mpeg3video_get_pmb_type: invalid macroblock_type code\n"); */
155 slice->fault = 1;
156 return 0;
157 }
158
159 mpeg3slice_flushbits(slice_buffer, mpeg3_PMBtab1[code].len);
160 return mpeg3_PMBtab1[code].val;
161}
162
163static inline int mpeg3video_get_bmb_type(mpeg3_slice_t *slice)
164{
165 int code;
166 mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
167
168 if((code = mpeg3slice_showbits(slice_buffer, 6)) >= 8)
169 {
170 code >>= 2;
171 mpeg3slice_flushbits(slice_buffer, mpeg3_BMBtab0[code].len);
172 return mpeg3_BMBtab0[code].val;
173 }
174
175 if(code == 0)
176 {
177 /* fprintf(stderr,"mpeg3video_get_bmb_type: invalid macroblock_type code\n"); */
178 slice->fault = 1;
179 return 0;
180 }
181
182 mpeg3slice_flushbits(slice_buffer, mpeg3_BMBtab1[code].len);
183
184 return mpeg3_BMBtab1[code].val;
185}
186
187static inline int mpeg3video_get_dmb_type(mpeg3_slice_t *slice)
188{
189 if(!mpeg3slice_getbit(slice->slice_buffer))
190 {
191 /* fprintf(stderr,"mpeg3video_get_dmb_type: invalid macroblock_type code\n"); */
192 slice->fault=1;
193 }
194
195 return 1;
196}
197
198
199static inline int mpeg3video_get_snrmb_type(mpeg3_slice_t *slice)
200{
201 mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
202 int code = mpeg3slice_showbits(slice_buffer, 3);
203
204 if(code == 0)
205 {
206/* fprintf(stderr,"mpeg3video_get_snrmb_type: invalid macroblock_type code\n"); */
207 slice->fault = 1;
208 return 0;
209 }
210
211 mpeg3slice_flushbits(slice_buffer, mpeg3_SNRMBtab[code].len);
212 return mpeg3_SNRMBtab[code].val;
213}
214
215int mpeg3video_get_mb_type(mpeg3_slice_t *slice, mpeg3video_t *video)
216{
217 if(video->scalable_mode == SC_SNR)
218 {
219 return mpeg3video_get_snrmb_type(slice);
220 }
221 else
222 {
223 switch(video->pict_type)
224 {
225 case I_TYPE: return video->pict_scal ? mpeg3video_getsp_imb_type(slice) : mpeg3video_get_imb_type(slice);
226 case P_TYPE: return video->pict_scal ? mpeg3video_getsp_pmb_type(slice) : mpeg3video_get_pmb_type(slice);
227 case B_TYPE: return video->pict_scal ? mpeg3video_getsp_bmb_type(slice) : mpeg3video_get_bmb_type(slice);
228 case D_TYPE: return mpeg3video_get_dmb_type(slice);
229 default:
230 /*fprintf(stderr, "mpeg3video_getmbtype: unknown coding type\n"); */
231 break;
232/* MPEG-1 only, not implemented */
233 }
234 }
235
236 return 0;
237}
238
239int mpeg3video_macroblock_modes(mpeg3_slice_t *slice,
240 mpeg3video_t *video,
241 int *pmb_type,
242 int *pstwtype,
243 int *pstwclass,
244 int *pmotion_type,
245 int *pmv_count,
246 int *pmv_format,
247 int *pdmv,
248 int *pmvscale,
249 int *pdct_type)
250{
251 int mb_type;
252 int stwtype, stwcode, stwclass;
253 int motion_type = 0, mv_count, mv_format, dmv, mvscale;
254 int dct_type;
255 mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
256 static unsigned char stwc_table[3][4]
257 = { {6,3,7,4}, {2,1,5,4}, {2,5,7,4} };
258 static unsigned char stwclass_table[9]
259 = {0, 1, 2, 1, 1, 2, 3, 3, 4};
260
261/* get macroblock_type */
262 mb_type = mpeg3video_get_mb_type(slice, video);
263
264 if(slice->fault) return 1;
265
266/* get spatial_temporal_weight_code */
267 if(mb_type & MB_WEIGHT)
268 {
269 if(video->stwc_table_index == 0)
270 stwtype = 4;
271 else
272 {
273 stwcode = mpeg3slice_getbits2(slice_buffer);
274 stwtype = stwc_table[video->stwc_table_index - 1][stwcode];
275 }
276 }
277 else
278 stwtype = (mb_type & MB_CLASS4) ? 8 : 0;
279
280/* derive spatial_temporal_weight_class (Table 7-18) */
281 stwclass = stwclass_table[stwtype];
282
283/* get frame/field motion type */
284 if(mb_type & (MB_FORWARD | MB_BACKWARD))
285 {
286 if(video->pict_struct == FRAME_PICTURE)
287 {
288/* frame_motion_type */
289 motion_type = video->frame_pred_dct ? MC_FRAME : mpeg3slice_getbits2(slice_buffer);
290 }
291 else
292 {
293/* field_motion_type */
294 motion_type = mpeg3slice_getbits2(slice_buffer);
295 }
296 }
297 else
298 if((mb_type & MB_INTRA) && video->conceal_mv)
299 {
300/* concealment motion vectors */
301 motion_type = (video->pict_struct == FRAME_PICTURE) ? MC_FRAME : MC_FIELD;
302 }
303
304/* derive mv_count, mv_format and dmv, (table 6-17, 6-18) */
305 if(video->pict_struct == FRAME_PICTURE)
306 {
307 mv_count = (motion_type == MC_FIELD && stwclass < 2) ? 2 : 1;
308 mv_format = (motion_type == MC_FRAME) ? MV_FRAME : MV_FIELD;
309 }
310 else
311 {
312 mv_count = (motion_type == MC_16X8) ? 2 : 1;
313 mv_format = MV_FIELD;
314 }
315
316 dmv = (motion_type == MC_DMV); /* dual prime */
317
318/* field mv predictions in frame pictures have to be scaled */
319 mvscale = ((mv_format == MV_FIELD) && (video->pict_struct == FRAME_PICTURE));
320
321/* get dct_type (frame DCT / field DCT) */
322 dct_type = (video->pict_struct == FRAME_PICTURE) &&
323 (!video->frame_pred_dct) &&
324 (mb_type & (MB_PATTERN | MB_INTRA)) ?
325 mpeg3slice_getbit(slice_buffer) : 0;
326
327/* return values */
328 *pmb_type = mb_type;
329 *pstwtype = stwtype;
330 *pstwclass = stwclass;
331 *pmotion_type = motion_type;
332 *pmv_count = mv_count;
333 *pmv_format = mv_format;
334 *pdmv = dmv;
335 *pmvscale = mvscale;
336 *pdct_type = dct_type;
337 return 0;
338}
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 @@
1/*
2 * the input data is tranposed and each 16 bit element in the 8x8 matrix
3 * is left aligned:
4 * for example in 11...1110000 format
5 * If the iDCT is of I macroblock then 0.5 needs to be added to the;DC Component
6 * (element[0][0] of the matrix)
7 */
8
9/* extrn re_matrix */
10
11/* constants */
12
13.data
14 .align 16
15 .type preSC, @object
16preSC: .short 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520
17 .short 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270
18 .short 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906
19 .short 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315
20 .short 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520
21 .short 12873, 17855, 16819, 15137, 25746, 20228, 13933, 7103
22 .short 17734, 24598, 23170, 20853, 17734, 13933, 9597, 4892
23 .short 18081, 25080, 23624, 21261, 18081, 14206, 9785, 4988
24 .sizepreSC, 128
25 .align 8
26 .typex0005000200010001, @object
27 .sizex0005000200010001, 8
28x0005000200010001:
29 .long0x00010001, 0x00050002
30 .align 8
31 .typex0040000000000000, @object
32 .sizex0040000000000000, 8
33x0040000000000000:
34 .long0, 0x00400000
35 .align 8
36 .typex5a825a825a825a82, @object
37 .sizex5a825a825a825a82, 8
38x5a825a825a825a82:
39 .long0x5a825a82, 0x5a825a82
40 .align 8
41 .typex539f539f539f539f, @object
42 .sizex539f539f539f539f, 8
43x539f539f539f539f:
44 .long0x539f539f, 0x539f539f
45 .align 8
46 .typex4546454645464546, @object
47 .sizex4546454645464546, 8
48x4546454645464546:
49 .long0x45464546, 0x45464546
50 .align 8
51 .typex61f861f861f861f8, @object
52 .sizex61f861f861f861f8, 8
53x61f861f861f861f8:
54 .long0x61f861f8, 0x61f861f8
55/* Static variables */
56 .align 8
57 .type x0, @object
58 .size x0, 8
59x0:
60 .long 0, 0
61/* Procedure */
62
63
64 .align 8
65.text
66 .align 4
67.globl IDCT_mmx
68 .type IDCT_mmx, @function
69IDCT_mmx:
70 pushl %ebp
71 movl %esp, %ebp
72 pushl %ebx
73 pushl %ecx
74 pushl %edx
75 pushl %esi
76 pushl %edi
77
78 pushl $0 /* allocate the temp variables */
79 pushl $0
80 pushl $0
81 pushl $0
82 pushl $0
83 pushl $0
84 pushl $0
85 pushl $0
86
87 movl 8(%ebp), %esi /* source matrix */
88 leal preSC, %ecx
89/* column 0: even part
90 * use V4, V12, V0, V8 to produce V22..V25
91 */
92 movq 8*12(%ecx), %mm0 /* maybe the first mul can be done together */
93 /* with the dequantization in iHuff module */
94 pmulhw 8*12(%esi), %mm0 /* V12 */
95 movq 8*4(%ecx), %mm1
96 pmulhw 8*4(%esi), %mm1 /* V4 */
97 movq (%ecx), %mm3
98 psraw $1, %mm0 /* t64=t66 */
99 pmulhw (%esi), %mm3 /* V0 */
100 movq 8*8(%ecx), %mm5 /* duplicate V4 */
101 movq %mm1, %mm2 /* added 11/1/96 */
102 pmulhw 8*8(%esi),%mm5 /* V8 */
103 psubsw %mm0, %mm1 /* V16 */
104 pmulhw x5a825a825a825a82, %mm1/* 23170 ->V18 */
105 paddsw %mm0, %mm2 /* V17 */
106 movq %mm2, %mm0 /* duplicate V17 */
107 psraw $1, %mm2 /* t75=t82 */
108 psraw $2, %mm0 /* t72 */
109 movq %mm3, %mm4 /* duplicate V0 */
110 paddsw %mm5, %mm3 /* V19 */
111 psubsw %mm5, %mm4 /* V20 ;mm5 free */
112/* moved from the block below */
113 movq 8*10(%ecx), %mm7
114 psraw $1, %mm3 /* t74=t81 */
115 movq %mm3, %mm6 /* duplicate t74=t81 */
116 psraw $2, %mm4 /* t77=t79 */
117 psubsw %mm0, %mm1 /* V21 ; mm0 free */
118 paddsw %mm2, %mm3 /* V22 */
119 movq %mm1, %mm5 /* duplicate V21 */
120 paddsw %mm4, %mm1 /* V23 */
121 movq %mm3, 8*4(%esi) /* V22 */
122 psubsw %mm5, %mm4 /* V24; mm5 free */
123 movq %mm1, 8*12(%esi) /* V23 */
124 psubsw %mm2, %mm6 /* V25; mm2 free */
125 movq %mm4, (%esi) /* V24 */
126/* keep mm6 alive all along the next block */
127 /* movq %mm6, 8*8(%esi) V25 */
128/* column 0: odd part
129 * use V2, V6, V10, V14 to produce V31, V39, V40, V41
130 */
131/* moved above: movq 8*10(%ecx), %mm7 */
132
133 pmulhw 8*10(%esi), %mm7 /* V10 */
134 movq 8*6(%ecx), %mm0
135 pmulhw 8*6(%esi), %mm0 /* V6 */
136 movq 8*2(%ecx), %mm5
137 movq %mm7, %mm3 /* duplicate V10 */
138 pmulhw 8*2(%esi), %mm5 /* V2 */
139 movq 8*14(%ecx), %mm4
140 psubsw %mm0, %mm7 /* V26 */
141 pmulhw 8*14(%esi), %mm4 /* V14 */
142 paddsw %mm0, %mm3 /* V29 ; free mm0 */
143 movq %mm7, %mm1 /* duplicate V26 */
144 psraw $1, %mm3 /* t91=t94 */
145 pmulhw x539f539f539f539f,%mm7/* V33 */
146 psraw $1, %mm1 /* t96 */
147 movq %mm5, %mm0 /* duplicate V2 */
148 psraw $2, %mm4 /* t85=t87 */
149 paddsw %mm4,%mm5 /* V27 */
150 psubsw %mm4, %mm0 /* V28 ; free mm4 */
151 movq %mm0, %mm2 /* duplicate V28 */
152 psraw $1, %mm5 /* t90=t93 */
153 pmulhw x4546454645464546,%mm0/* V35 */
154 psraw $1, %mm2 /* t97 */
155 movq %mm5, %mm4 /* duplicate t90=t93 */
156 psubsw %mm2, %mm1 /* V32 ; free mm2 */
157 pmulhw x61f861f861f861f8,%mm1/* V36 */
158 psllw $1, %mm7 /* t107 */
159 paddsw %mm3, %mm5 /* V31 */
160 psubsw %mm3, %mm4 /* V30 ; free mm3 */
161 pmulhw x5a825a825a825a82,%mm4/* V34 */
162 nop
163 psubsw %mm1, %mm0 /* V38 */
164 psubsw %mm7, %mm1 /* V37 ; free mm7 */
165 psllw $1, %mm1 /* t114 */
166/* move from the next block */
167 movq %mm6, %mm3 /* duplicate V25 */
168/* move from the next block */
169 movq 8*4(%esi), %mm7 /* V22 */
170 psllw $1, %mm0 /* t110 */
171 psubsw %mm5, %mm0 /* V39 (mm5 needed for next block) */
172 psllw $2, %mm4 /* t112 */
173/* moved from the next block */
174 movq 8*12(%esi), %mm2 /* V23 */
175 psubsw %mm0, %mm4 /* V40 */
176 paddsw %mm4, %mm1 /* V41; free mm0 */
177/* moved from the next block */
178 psllw $1, %mm2 /* t117=t125 */
179/* column 0: output butterfly */
180/* moved above:
181 * movq %mm6, %mm3 duplicate V25
182 * movq 8*4(%esi), %mm7 V22
183 * movq 8*12(%esi), %mm2 V23
184 * psllw $1, %mm2 t117=t125
185 */
186 psubsw %mm1, %mm6 /* tm6 */
187 paddsw %mm1, %mm3 /* tm8; free mm1 */
188 movq %mm7, %mm1 /* duplicate V22 */
189 paddsw %mm5, %mm7 /* tm0 */
190 movq %mm3, 8*8(%esi) /* tm8; free mm3 */
191 psubsw %mm5, %mm1 /* tm14; free mm5 */
192 movq %mm6, 8*6(%esi) /* tm6; free mm6 */
193 movq %mm2, %mm3 /* duplicate t117=t125 */
194 movq (%esi), %mm6 /* V24 */
195 paddsw %mm0, %mm2 /* tm2 */
196 movq %mm7, (%esi) /* tm0; free mm7 */
197 psubsw %mm0, %mm3 /* tm12; free mm0 */
198 movq %mm1, 8*14(%esi) /* tm14; free mm1 */
199 psllw $1, %mm6 /* t119=t123 */
200 movq %mm2, 8*2(%esi) /* tm2; free mm2 */
201 movq %mm6, %mm0 /* duplicate t119=t123 */
202 movq %mm3, 8*12(%esi) /* tm12; free mm3 */
203 paddsw %mm4, %mm6 /* tm4 */
204/* moved from next block */
205 movq 8*5(%ecx), %mm1
206 psubsw %mm4, %mm0 /* tm10; free mm4 */
207/* moved from next block */
208 pmulhw 8*5(%esi), %mm1 /* V5 */
209 movq %mm6, 8*4(%esi) /* tm4; free mm6 */
210 movq %mm0, 8*10(%esi) /* tm10; free mm0 */
211/* column 1: even part
212 * use V5, V13, V1, V9 to produce V56..V59
213 */
214/* moved to prev block:
215 *movq 8*5(%ecx), %mm1
216 * pmulhw 8*5(%esi), %mm1 V5
217 */
218 movq 8*13(%ecx), %mm7
219 psllw $1, %mm1 /* t128=t130 */
220 pmulhw 8*13(%esi), %mm7 /* V13 */
221 movq %mm1, %mm2 /* duplicate t128=t130 */
222 movq 8(%ecx), %mm3
223 pmulhw 8(%esi), %mm3 /* V1 */
224 movq 8*9(%ecx), %mm5
225 psubsw %mm7, %mm1 /* V50 */
226 pmulhw 8*9(%esi), %mm5 /* V9 */
227 paddsw %mm7, %mm2 /* V51 */
228 pmulhw x5a825a825a825a82, %mm1/* 23170 ->V52 */
229 movq %mm2, %mm6 /* duplicate V51 */
230 psraw $1, %mm2 /* t138=t144 */
231 movq %mm3, %mm4 /* duplicate V1 */
232 psraw $2, %mm6 /* t136 */
233 paddsw %mm5, %mm3 /* V53 */
234 psubsw %mm5, %mm4 /* V54 ;mm5 free */
235 movq %mm3, %mm7 /* duplicate V53 */
236/* moved from next block */
237 movq 8*11(%ecx), %mm0
238 psraw $1, %mm4 /* t140=t142 */
239 psubsw %mm6, %mm1 /* V55 ; mm6 free */
240 paddsw %mm2, %mm3 /* V56 */
241 movq %mm4, %mm5 /* duplicate t140=t142 */
242 paddsw %mm1, %mm4 /* V57 */
243 movq %mm3, 8*5(%esi) /* V56 */
244 psubsw %mm1, %mm5 /* V58; mm1 free */
245 movq %mm4, 8*13(%esi) /* V57 */
246 psubsw %mm2, %mm7 /* V59; mm2 free */
247 movq %mm5, 8*9(%esi) /* V58 */
248/* keep mm7 alive all along the next block
249 * movq %mm7, 8(%esi) V59
250 * moved above
251 *movq 8*11(%ecx), %mm0
252 */
253 pmulhw 8*11(%esi), %mm0 /* V11 */
254 movq 8*7(%ecx), %mm6
255 pmulhw 8*7(%esi), %mm6 /* V7 */
256 movq 8*15(%ecx), %mm4
257 movq %mm0, %mm3 /* duplicate V11 */
258 pmulhw 8*15(%esi), %mm4 /* V15 */
259 movq 8*3(%ecx), %mm5
260 psllw $1, %mm6 /* t146=t152 */
261 pmulhw 8*3(%esi), %mm5 /* V3 */
262 paddsw %mm6, %mm0 /* V63 */
263/* note that V15 computation has a correction step:
264 * this is a 'magic' constant that rebiases the results to be closer to the
265 * expected result. this magic constant can be refined to reduce the error
266 * even more by doing the correction step in a later stage when the number
267 * is actually multiplied by 16
268 */
269 paddw x0005000200010001, %mm4
270 psubsw %mm6, %mm3 /* V60 ; free mm6 */
271 psraw $1, %mm0 /* t154=t156 */
272 movq %mm3, %mm1 /* duplicate V60 */
273 pmulhw x539f539f539f539f, %mm1/* V67 */
274 movq %mm5, %mm6 /* duplicate V3 */
275 psraw $2, %mm4 /* t148=t150 */
276 paddsw %mm4, %mm5 /* V61 */
277 psubsw %mm4, %mm6 /* V62 ; free mm4 */
278 movq %mm5, %mm4 /* duplicate V61 */
279 psllw $1, %mm1 /* t169 */
280 paddsw %mm0, %mm5 /* V65 -> result */
281 psubsw %mm0, %mm4 /* V64 ; free mm0 */
282 pmulhw x5a825a825a825a82, %mm4/* V68 */
283 psraw $1, %mm3 /* t158 */
284 psubsw %mm6, %mm3 /* V66 */
285 movq %mm5, %mm2 /* duplicate V65 */
286 pmulhw x61f861f861f861f8, %mm3/* V70 */
287 psllw $1, %mm6 /* t165 */
288 pmulhw x4546454645464546, %mm6/* V69 */
289 psraw $1, %mm2 /* t172 */
290/* moved from next block */
291 movq 8*5(%esi), %mm0 /* V56 */
292 psllw $1, %mm4 /* t174 */
293/* moved from next block */
294 psraw $1, %mm0 /* t177=t188 */
295 nop
296 psubsw %mm3, %mm6 /* V72 */
297 psubsw %mm1, %mm3 /* V71 ; free mm1 */
298 psubsw %mm2, %mm6 /* V73 ; free mm2 */
299/* moved from next block */
300 psraw $1, %mm5 /* t178=t189 */
301 psubsw %mm6, %mm4 /* V74 */
302/* moved from next block */
303 movq %mm0, %mm1 /* duplicate t177=t188 */
304 paddsw %mm4, %mm3 /* V75 */
305/* moved from next block */
306 paddsw %mm5, %mm0 /* tm1 */
307/* location
308 * 5 - V56
309 * 13 - V57
310 * 9 - V58
311 * X - V59, mm7
312 * X - V65, mm5
313 * X - V73, mm6
314 * X - V74, mm4
315 * X - V75, mm3
316 * free mm0, mm1 & mm2
317 * moved above
318 * movq 8*5(%esi), %mm0 V56
319 * psllw $1, %mm0 t177=t188 ! new !!
320 * psllw $1, %mm5 t178=t189 ! new !!
321 * movq %mm0, %mm1 duplicate t177=t188
322 * paddsw %mm5, %mm0 tm1
323 */
324 movq 8*13(%esi), %mm2 /* V57 */
325 psubsw %mm5, %mm1 /* tm15; free mm5 */
326 movq %mm0, 8(%esi) /* tm1; free mm0 */
327 psraw $1, %mm7 /* t182=t184 ! new !! */
328/* save the store as used directly in the transpose
329 * movq %mm1, 120(%esi) tm15; free mm1
330 */
331 movq %mm7, %mm5 /* duplicate t182=t184 */
332 psubsw %mm3, %mm7 /* tm7 */
333 paddsw %mm3, %mm5 /* tm9; free mm3 */
334 movq 8*9(%esi), %mm0 /* V58 */
335 movq %mm2, %mm3 /* duplicate V57 */
336 movq %mm7, 8*7(%esi) /* tm7; free mm7 */
337 psubsw %mm6, %mm3 /* tm13 */
338 paddsw %mm6, %mm2 /* tm3 ; free mm6 */
339/* moved up from the transpose */
340 movq %mm3, %mm7
341/* moved up from the transpose */
342 punpcklwd %mm1, %mm3
343 movq %mm0, %mm6 /* duplicate V58 */
344 movq %mm2, 8*3(%esi) /* tm3; free mm2 */
345 paddsw %mm4, %mm0 /* tm5 */
346 psubsw %mm4, %mm6 /* tm11; free mm4 */
347/* moved up from the transpose */
348 punpckhwd %mm1, %mm7
349 movq %mm0, 8*5(%esi) /* tm5; free mm0 */
350/* moved up from the transpose */
351 movq %mm5, %mm2
352/* transpose - M4 part
353 * --------- ---------
354 * | M1 | M2 | | M1'| M3'|
355 * --------- --> ---------
356 * | M3 | M4 | | M2'| M4'|
357 * --------- ---------
358 * Two alternatives: use full mmword approach so the following code can be
359 * scheduled before the transpose is done without stores, or use the faster
360 * half mmword stores (when possible)
361 */
362 movd %mm3, 8*9+4(%esi) /* MS part of tmt9 */
363 punpcklwd %mm6, %mm5
364 movd %mm7, 8*13+4(%esi) /* MS part of tmt13 */
365 punpckhwd %mm6, %mm2
366 movd %mm5, 8*9(%esi) /* LS part of tmt9 */
367 punpckhdq %mm3, %mm5 /* free mm3 */
368 movd %mm2, 8*13(%esi) /* LS part of tmt13 */
369 punpckhdq %mm7, %mm2 /* free mm7 */
370/* moved up from the M3 transpose */
371 movq 8*8(%esi), %mm0
372/* moved up from the M3 transpose */
373 movq 8*10(%esi), %mm1
374/* moved up from the M3 transpose */
375 movq %mm0, %mm3
376/* shuffle the rest of the data, and write it with 2 mmword writes */
377 movq %mm5, 8*11(%esi) /* tmt11 */
378/* moved up from the M3 transpose */
379 punpcklwd %mm1, %mm0
380 movq %mm2, 8*15(%esi) /* tmt15 */
381/* moved up from the M3 transpose */
382 punpckhwd %mm1, %mm3
383/* transpose - M3 part
384 * moved up to previous code section
385 *movq 8*8(%esi), %mm0
386 *movq 8*10(%esi), %mm1
387 *movq %mm0, %mm3
388 *punpcklwd %mm1, %mm0
389 *punpckhwd %mm1, %mm3
390 */
391 movq 8*12(%esi), %mm6
392 movq 8*14(%esi), %mm4
393 movq %mm6, %mm2
394/* shuffle the data and write the lower parts of the transposed in 4 dwords */
395 punpcklwd %mm4, %mm6
396 movq %mm0, %mm1
397 punpckhdq %mm6, %mm1
398 movq %mm3, %mm7
399 punpckhwd %mm4, %mm2 /* free mm4 */
400 punpckldq %mm6, %mm0 /* free mm6 */
401/* moved from next block */
402 movq 8*13(%esi), %mm4 /* tmt13 */
403 punpckldq %mm2, %mm3
404 punpckhdq %mm2, %mm7 /* free mm2 */
405/* moved from next block */
406 movq %mm3, %mm5 /* duplicate tmt5 */
407/* column 1: even part (after transpose)
408* moved above
409 * movq %mm3, %mm5 duplicate tmt5
410 * movq 8*13(%esi), %mm4 tmt13
411*/
412 psubsw %mm4, %mm3 /* V134 */
413 pmulhw x5a825a825a825a82, %mm3/* 23170 ->V136 */
414 movq 8*9(%esi), %mm6 /* tmt9 */
415 paddsw %mm4, %mm5 /* V135 ; mm4 free */
416 movq %mm0, %mm4 /* duplicate tmt1 */
417 paddsw %mm6, %mm0 /* V137 */
418 psubsw %mm6, %mm4 /* V138 ; mm6 free */
419 psllw $2, %mm3 /* t290 */
420 psubsw %mm5, %mm3 /* V139 */
421 movq %mm0, %mm6 /* duplicate V137 */
422 paddsw %mm5, %mm0 /* V140 */
423 movq %mm4, %mm2 /* duplicate V138 */
424 paddsw %mm3, %mm2 /* V141 */
425 psubsw %mm3, %mm4 /* V142 ; mm3 free */
426 movq %mm0, 8*9(%esi) /* V140 */
427 psubsw %mm5, %mm6 /* V143 ; mm5 free */
428/* moved from next block */
429 movq 8*11(%esi), %mm0 /* tmt11 */
430 movq %mm2, 8*13(%esi) /* V141 */
431/* moved from next block */
432 movq %mm0, %mm2 /* duplicate tmt11 */
433/* column 1: odd part (after transpose) */
434/* moved up to the prev block
435 * movq 8*11(%esi), %mm0 tmt11
436 * movq %mm0, %mm2 duplicate tmt11
437 */
438 movq 8*15(%esi), %mm5 /* tmt15 */
439 psubsw %mm7, %mm0 /* V144 */
440 movq %mm0, %mm3 /* duplicate V144 */
441 paddsw %mm7, %mm2 /* V147 ; free mm7 */
442 pmulhw x539f539f539f539f, %mm0/* 21407-> V151 */
443 movq %mm1, %mm7 /* duplicate tmt3 */
444 paddsw %mm5, %mm7 /* V145 */
445 psubsw %mm5, %mm1 /* V146 ; free mm5 */
446 psubsw %mm1, %mm3 /* V150 */
447 movq %mm7, %mm5 /* duplicate V145 */
448 pmulhw x4546454645464546, %mm1/* 17734-> V153 */
449 psubsw %mm2, %mm5 /* V148 */
450 pmulhw x61f861f861f861f8, %mm3/* 25080-> V154 */
451 psllw $2, %mm0 /* t311 */
452 pmulhw x5a825a825a825a82, %mm5/* 23170-> V152 */
453 paddsw %mm2, %mm7 /* V149 ; free mm2 */
454 psllw $1, %mm1 /* t313 */
455 nop/* without the nop - freeze here for one clock */
456 movq %mm3, %mm2 /* duplicate V154 */
457 psubsw %mm0, %mm3 /* V155 ; free mm0 */
458 psubsw %mm2, %mm1 /* V156 ; free mm2 */
459/* moved from the next block */
460 movq %mm6, %mm2 /* duplicate V143 */
461/* moved from the next block */
462 movq 8*13(%esi), %mm0 /* V141 */
463 psllw $1, %mm1 /* t315 */
464 psubsw %mm7, %mm1 /* V157 (keep V149) */
465 psllw $2, %mm5 /* t317 */
466 psubsw %mm1, %mm5 /* V158 */
467 psllw $1, %mm3 /* t319 */
468 paddsw %mm5, %mm3 /* V159 */
469/* column 1: output butterfly (after transform)
470 * moved to the prev block
471 * movq %mm6, %mm2 duplicate V143
472 * movq 8*13(%esi), %mm0 V141
473 */
474 psubsw %mm3, %mm2 /* V163 */
475 paddsw %mm3, %mm6 /* V164 ; free mm3 */
476 movq %mm4, %mm3 /* duplicate V142 */
477 psubsw %mm5, %mm4 /* V165 ; free mm5 */
478 movq %mm2, (%esp) /* out7 */
479 psraw $4, %mm6
480 psraw $4, %mm4
481 paddsw %mm5, %mm3 /* V162 */
482 movq 8*9(%esi), %mm2 /* V140 */
483 movq %mm0, %mm5 /* duplicate V141 */
484/* in order not to perculate this line up,
485 * we read 72(%esi) very near to this location
486 */
487 movq %mm6, 8*9(%esi) /* out9 */
488 paddsw %mm1, %mm0 /* V161 */
489 movq %mm3, 8(%esp) /* out5 */
490 psubsw %mm1, %mm5 /* V166 ; free mm1 */
491 movq %mm4, 8*11(%esi) /* out11 */
492 psraw $4, %mm5
493 movq %mm0, 16(%esp) /* out3 */
494 movq %mm2, %mm4 /* duplicate V140 */
495 movq %mm5, 8*13(%esi) /* out13 */
496 paddsw %mm7, %mm2 /* V160 */
497/* moved from the next block */
498 movq 8(%esi), %mm0
499 psubsw %mm7, %mm4 /* V167 ; free mm7 */
500/* moved from the next block */
501 movq 8*3(%esi), %mm7
502 psraw $4, %mm4
503 movq %mm2, 24(%esp) /* out1 */
504/* moved from the next block */
505 movq %mm0, %mm1
506 movq %mm4, 8*15(%esi) /* out15 */
507/* moved from the next block */
508 punpcklwd %mm7, %mm0
509/* transpose - M2 parts
510 * moved up to the prev block
511 *movq 8(%esi), %mm0
512 *movq 8*3(%esi), %mm7
513 *movq %mm0, %mm1
514 *punpcklwd %mm7, %mm0
515 */
516 movq 8*5(%esi), %mm5
517 punpckhwd %mm7, %mm1
518 movq 8*7(%esi), %mm4
519 movq %mm5, %mm3
520/* shuffle the data and write the lower parts of the trasposed in 4 dwords */
521 movd %mm0, 8*8(%esi) /* LS part of tmt8 */
522 punpcklwd %mm4, %mm5
523 movd %mm1, 8*12(%esi) /* LS part of tmt12 */
524 punpckhwd %mm4, %mm3
525 movd %mm5, 8*8+4(%esi) /* MS part of tmt8 */
526 punpckhdq %mm5, %mm0 /* tmt10 */
527 movd %mm3, 8*12+4(%esi) /* MS part of tmt12 */
528 punpckhdq %mm3, %mm1 /* tmt14 */
529/* transpose - M1 parts */
530 movq (%esi), %mm7
531 movq 8*2(%esi), %mm2
532 movq %mm7, %mm6
533 movq 8*4(%esi), %mm5
534 punpcklwd %mm2, %mm7
535 movq 8*6(%esi), %mm4
536 punpckhwd %mm2, %mm6 /* free mm2 */
537 movq %mm5, %mm3
538 punpcklwd %mm4, %mm5
539 punpckhwd %mm4, %mm3 /* free mm4 */
540 movq %mm7, %mm2
541 movq %mm6, %mm4
542 punpckldq %mm5, %mm7 /* tmt0 */
543 punpckhdq %mm5, %mm2 /* tmt2 ; free mm5 */
544/* shuffle the rest of the data, and write it with 2 mmword writes */
545 punpckldq %mm3, %mm6 /* tmt4 */
546/* moved from next block */
547 movq %mm2, %mm5 /* duplicate tmt2 */
548 punpckhdq %mm3, %mm4 /* tmt6 ; free mm3 */
549/* moved from next block */
550 movq %mm0, %mm3 /* duplicate tmt10 */
551/* column 0: odd part (after transpose)
552 *moved up to prev block
553 * movq %mm0, %mm3 duplicate tmt10
554 * movq %mm2, %mm5 duplicate tmt2
555 */
556 psubsw %mm4, %mm0 /* V110 */
557 paddsw %mm4, %mm3 /* V113 ; free mm4 */
558 movq %mm0, %mm4 /* duplicate V110 */
559 paddsw %mm1, %mm2 /* V111 */
560 pmulhw x539f539f539f539f, %mm0/* 21407-> V117 */
561 psubsw %mm1, %mm5 /* V112 ; free mm1 */
562 psubsw %mm5, %mm4 /* V116 */
563 movq %mm2, %mm1 /* duplicate V111 */
564 pmulhw x4546454645464546, %mm5/* 17734-> V119 */
565 psubsw %mm3, %mm2 /* V114 */
566 pmulhw x61f861f861f861f8, %mm4/* 25080-> V120 */
567 paddsw %mm3, %mm1 /* V115 ; free mm3 */
568 pmulhw x5a825a825a825a82, %mm2/* 23170-> V118 */
569 psllw $2, %mm0 /* t266 */
570 movq %mm1, (%esi) /* save V115 */
571 psllw $1, %mm5 /* t268 */
572 psubsw %mm4, %mm5 /* V122 */
573 psubsw %mm0, %mm4 /* V121 ; free mm0 */
574 psllw $1, %mm5 /* t270 */
575 psubsw %mm1, %mm5 /* V123 ; free mm1 */
576 psllw $2, %mm2 /* t272 */
577 psubsw %mm5, %mm2 /* V124 (keep V123) */
578 psllw $1, %mm4 /* t274 */
579 movq %mm5, 8*2(%esi) /* save V123 ; free mm5 */
580 paddsw %mm2, %mm4 /* V125 (keep V124) */
581/* column 0: even part (after transpose) */
582 movq 8*12(%esi), %mm0 /* tmt12 */
583 movq %mm6, %mm3 /* duplicate tmt4 */
584 psubsw %mm0, %mm6 /* V100 */
585 paddsw %mm0, %mm3 /* V101 ; free mm0 */
586 pmulhw x5a825a825a825a82, %mm6/* 23170 ->V102 */
587 movq %mm7, %mm5 /* duplicate tmt0 */
588 movq 8*8(%esi), %mm1 /* tmt8 */
589 paddsw %mm1, %mm7 /* V103 */
590 psubsw %mm1, %mm5 /* V104 ; free mm1 */
591 movq %mm7, %mm0 /* duplicate V103 */
592 psllw $2, %mm6 /* t245 */
593 paddsw %mm3, %mm7 /* V106 */
594 movq %mm5, %mm1 /* duplicate V104 */
595 psubsw %mm3, %mm6 /* V105 */
596 psubsw %mm3, %mm0 /* V109; free mm3 */
597 paddsw %mm6, %mm5 /* V107 */
598 psubsw %mm6, %mm1 /* V108 ; free mm6 */
599/* column 0: output butterfly (after transform) */
600 movq %mm1, %mm3 /* duplicate V108 */
601 paddsw %mm2, %mm1 /* out4 */
602 psraw $4, %mm1
603 psubsw %mm2, %mm3 /* out10 ; free mm2 */
604 psraw $4, %mm3
605 movq %mm0, %mm6 /* duplicate V109 */
606 movq %mm1, 8*4(%esi) /* out4 ; free mm1 */
607 psubsw %mm4, %mm0 /* out6 */
608 movq %mm3, 8*10(%esi) /* out10 ; free mm3 */
609 psraw $4, %mm0
610 paddsw %mm4, %mm6 /* out8 ; free mm4 */
611 movq %mm7, %mm1 /* duplicate V106 */
612 movq %mm0, 8*6(%esi) /* out6 ; free mm0 */
613 psraw $4, %mm6
614 movq (%esi), %mm4 /* V115 */
615 movq %mm6, 8*8(%esi) /* out8 ; free mm6 */
616 movq %mm5, %mm2 /* duplicate V107 */
617 movq 8*2(%esi), %mm3 /* V123 */
618 paddsw %mm4, %mm7 /* out0 */
619/* moved up from next block */
620 movq 16(%esp), %mm0
621 psraw $4, %mm7
622/* moved up from next block */
623 movq 8(%esp), %mm6
624 psubsw %mm4, %mm1 /* out14 ; free mm4 */
625 paddsw %mm3, %mm5 /* out2 */
626 psraw $4, %mm1
627 movq %mm7, (%esi) /* out0 ; free mm7 */
628 psraw $4, %mm5
629 movq %mm1, 8*14(%esi) /* out14 ; free mm1 */
630 psubsw %mm3, %mm2 /* out12 ; free mm3 */
631 movq %mm5, 8*2(%esi) /* out2 ; free mm5 */
632 psraw $4, %mm2
633/* moved up to the prev block */
634 movq (%esp), %mm4
635/* moved up to the prev block */
636 psraw $4, %mm0
637 movq %mm2, 8*12(%esi) /* out12 ; free mm2 */
638/* moved up to the prev block */
639 psraw $4, %mm6
640/* move back the data to its correct place
641* moved up to the prev block
642 *movq 16(%esp), %mm0
643 *movq 8(%esp), %mm6
644 *movq (%esp), %mm4
645 *psraw $4, %mm0
646 *psraw $4, %mm6
647*/
648 movq 24(%esp), %mm1
649 psraw $4, %mm4
650 movq %mm0, 8*3(%esi) /* out3 */
651 psraw $4, %mm1
652 movq %mm6, 8*5(%esi) /* out5 */
653 movq %mm4, 8*7(%esi) /* out7 */
654 movq %mm1, 8(%esi) /* out1 */
655
656 popl %edi /* Pop off the temp variables */
657 popl %edi
658 popl %edi
659 popl %edi
660 popl %edi
661 popl %edi
662 popl %edi
663 popl %edi
664
665 popl %edi /* Pop off the old variables */
666 popl %esi
667 popl %edx
668 popl %ecx
669 popl %ebx
670 movl %ebp, %esp
671 popl %ebp
672
673 ret
674.Lfe1:
675 .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 @@
1#include "../libmpeg3.h"
2#include "../mpeg3protos.h"
3
4#include <stdio.h>
5#include <string.h>
6
7int mpeg3_mmx_test()
8{
9 int result = 0;
10 FILE *proc;
11 char string[MPEG3_STRLEN];
12
13
14#ifdef HAVE_MMX
15 if(!(proc = fopen(MPEG3_PROC_CPUINFO, "r")))
16 {
17 return 0;
18 }
19
20 while(!feof(proc))
21 {
22 fgets(string, MPEG3_STRLEN, proc);
23/* Got the flags line */
24 if(!strncmp(string, "flags", 5))
25 {
26 char *needle;
27 needle = strstr(string, "mmx");
28 if(!needle) return 0;
29 if(!strncmp(needle, "mmx", 3)) return 1;
30 }
31 }
32#endif
33
34 return 0;
35}
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 @@
1#include "mpeg3video.h"
2#include "../libmpeg3.h"
3#include "../mpeg3protos.h"
4#include "vlc.h"
5
6#include <stdio.h>
7
8
9/* calculate motion vector component */
10
11static inline void mpeg3video_calc_mv(int *pred, int r_size, int motion_code, int motion_r, int full_pel_vector)
12{
13 int lim = 16 << r_size;
14 int vec = full_pel_vector ? (*pred >> 1) : (*pred);
15
16 if(motion_code > 0)
17 {
18 vec += ((motion_code - 1) << r_size) + motion_r + 1;
19 if(vec >= lim) vec -= lim + lim;
20 }
21 else
22 if(motion_code < 0)
23 {
24 vec -= ((-motion_code - 1) << r_size) + motion_r + 1;
25 if(vec < -lim) vec += lim + lim;
26 }
27 *pred = full_pel_vector ? (vec << 1) : vec;
28}
29
30
31/*
32int *dmvector, * differential motion vector *
33int mvx, int mvy * decoded mv components (always in field format) *
34*/
35void mpeg3video_calc_dmv(mpeg3video_t *video,
36 int DMV[][2],
37 int *dmvector,
38 int mvx,
39 int mvy)
40{
41 if(video->pict_struct == FRAME_PICTURE)
42 {
43 if(video->topfirst)
44 {
45/* vector for prediction of top field from bottom field */
46 DMV[0][0] = ((mvx + (mvx>0)) >> 1) + dmvector[0];
47 DMV[0][1] = ((mvy + (mvy>0)) >> 1) + dmvector[1] - 1;
48
49/* vector for prediction of bottom field from top field */
50 DMV[1][0] = ((3 * mvx + (mvx > 0)) >> 1) + dmvector[0];
51 DMV[1][1] = ((3 * mvy + (mvy > 0)) >> 1) + dmvector[1] + 1;
52 }
53 else
54 {
55/* vector for prediction of top field from bottom field */
56 DMV[0][0] = ((3 * mvx + (mvx>0)) >> 1) + dmvector[0];
57 DMV[0][1] = ((3 * mvy + (mvy>0)) >> 1) + dmvector[1] - 1;
58
59/* vector for prediction of bottom field from top field */
60 DMV[1][0] = ((mvx + (mvx>0)) >> 1) + dmvector[0];
61 DMV[1][1] = ((mvy + (mvy>0)) >> 1) + dmvector[1] + 1;
62 }
63 }
64 else
65 {
66/* vector for prediction from field of opposite 'parity' */
67 DMV[0][0] = ((mvx + (mvx > 0)) >> 1) + dmvector[0];
68 DMV[0][1] = ((mvy + (mvy > 0)) >> 1) + dmvector[1];
69
70/* correct for vertical field shift */
71 if(video->pict_struct == TOP_FIELD)
72 DMV[0][1]--;
73 else
74 DMV[0][1]++;
75 }
76}
77
78static inline int mpeg3video_get_mv(mpeg3_slice_t *slice)
79{
80 int code;
81 mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
82
83 if(mpeg3slice_getbit(slice_buffer))
84 {
85 return 0;
86 }
87
88 if((code = mpeg3slice_showbits9(slice_buffer)) >= 64)
89 {
90 code >>= 6;
91 mpeg3slice_flushbits(slice_buffer, mpeg3_MVtab0[code].len);
92 return mpeg3slice_getbit(slice_buffer) ? -mpeg3_MVtab0[code].val : mpeg3_MVtab0[code].val;
93 }
94
95 if(code >= 24)
96 {
97 code >>= 3;
98 mpeg3slice_flushbits(slice_buffer, mpeg3_MVtab1[code].len);
99 return mpeg3slice_getbit(slice_buffer) ? -mpeg3_MVtab1[code].val : mpeg3_MVtab1[code].val;
100 }
101
102 if((code -= 12) < 0)
103 {
104 /* fprintf(stdout,"mpeg3video_get_mv: invalid motion_vector code\n"); */
105 slice->fault = 1;
106 return 1;
107 }
108
109 mpeg3slice_flushbits(slice_buffer, mpeg3_MVtab2[code].len);
110 return mpeg3slice_getbit(slice_buffer) ? -mpeg3_MVtab2[code].val : mpeg3_MVtab2[code].val;
111}
112
113/* get differential motion vector (for dual prime prediction) */
114
115static inline int mpeg3video_get_dmv(mpeg3_slice_t *slice)
116{
117 mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
118 if(mpeg3slice_getbit(slice_buffer))
119 {
120 return mpeg3slice_getbit(slice_buffer) ? -1 : 1;
121 }
122 else
123 {
124 return 0;
125 }
126}
127
128
129
130/* get and decode motion vector and differential motion vector */
131
132void mpeg3video_motion_vector(mpeg3_slice_t *slice,
133 mpeg3video_t *video,
134 int *PMV,
135 int *dmvector,
136 int h_r_size,
137 int v_r_size,
138 int dmv,
139 int mvscale,
140 int full_pel_vector)
141{
142 int motion_r;
143 int motion_code = mpeg3video_get_mv(slice);
144 mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
145
146 if(slice->fault) return;
147 motion_r = (h_r_size != 0 && motion_code != 0) ? mpeg3slice_getbits(slice_buffer, h_r_size) : 0;
148
149 mpeg3video_calc_mv(&PMV[0], h_r_size, motion_code, motion_r, full_pel_vector);
150
151 if(dmv) dmvector[0] = mpeg3video_get_dmv(slice);
152
153 motion_code = mpeg3video_get_mv(slice);
154 if(slice->fault) return;
155 motion_r = (v_r_size != 0 && motion_code != 0) ? mpeg3slice_getbits(slice_buffer, v_r_size) : 0;
156
157/* DIV 2 */
158 if(mvscale) PMV[1] >>= 1;
159
160 mpeg3video_calc_mv(&PMV[1], v_r_size, motion_code, motion_r, full_pel_vector);
161
162 if(mvscale) PMV[1] <<= 1;
163 if(dmv) dmvector[1] = mpeg3video_get_dmv(slice);
164}
165
166int mpeg3video_motion_vectors(mpeg3_slice_t *slice,
167 mpeg3video_t *video,
168 int PMV[2][2][2],
169 int dmvector[2],
170 int mv_field_sel[2][2],
171 int s,
172 int mv_count,
173 int mv_format,
174 int h_r_size,
175 int v_r_size,
176 int dmv,
177 int mvscale)
178{
179 int result = 0;
180 mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
181 if(mv_count == 1)
182 {
183 if(mv_format == MV_FIELD && !dmv)
184 {
185 mv_field_sel[1][s] = mv_field_sel[0][s] = mpeg3slice_getbit(slice_buffer);
186 }
187
188 mpeg3video_motion_vector(slice,
189 video,
190 PMV[0][s],
191 dmvector,
192 h_r_size,
193 v_r_size,
194 dmv,
195 mvscale,
196 0);
197 if(slice->fault) return 1;
198
199/* update other motion vector predictors */
200 PMV[1][s][0] = PMV[0][s][0];
201 PMV[1][s][1] = PMV[0][s][1];
202 }
203 else
204 {
205 mv_field_sel[0][s] = mpeg3slice_getbit(slice_buffer);
206 mpeg3video_motion_vector(slice,
207 video,
208 PMV[0][s],
209 dmvector,
210 h_r_size,
211 v_r_size,
212 dmv,
213 mvscale,
214 0);
215 if(slice->fault) return 1;
216
217 mv_field_sel[1][s] = mpeg3slice_getbit(slice_buffer);
218 mpeg3video_motion_vector(slice,
219 video,
220 PMV[1][s],
221 dmvector,
222 h_r_size,
223 v_r_size,
224 dmv,
225 mvscale,
226 0);
227 if(slice->fault) return 1;
228 }
229 return 0;
230}
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 @@
1#include "../libmpeg3.h"
2#include "../mpeg3protos.h"
3#include "mpeg3video.h"
4#include "mpeg3videoprotos.h"
5#include <stdlib.h>
6
7unsigned char mpeg3_zig_zag_scan_mmx[64] =
8{
9 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*/,
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*/,
11 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*/,
12 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*/,
13 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*/,
14 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*/,
15 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*/,
16 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*/
17};
18
19/* alternate scan */
20unsigned char mpeg3_alternate_scan_mmx[64] =
21{
22 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*/,
23 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*/,
24 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*/,
25 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*/,
26 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*/,
27 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*/,
28 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*/,
29 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*/
30};
31
32
33
34/* zig-zag scan */
35unsigned char mpeg3_zig_zag_scan_nommx[64] =
36{
37 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5,
38 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28,
39 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
40 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63
41};
42
43/* alternate scan */
44unsigned char mpeg3_alternate_scan_nommx[64] =
45{
46 0, 8, 16, 24, 1, 9, 2, 10, 17, 25, 32, 40, 48, 56, 57, 49,
47 41, 33, 26, 18, 3, 11, 4, 12, 19, 27, 34, 42, 50, 58, 35, 43,
48 51, 59, 20, 28, 5, 13, 6, 14, 21, 29, 36, 44, 52, 60, 37, 45,
49 53, 61, 22, 30, 7, 15, 23, 31, 38, 46, 54, 62, 39, 47, 55, 63
50};
51
52/* default intra quantization matrix */
53unsigned char mpeg3_default_intra_quantizer_matrix[64] =
54{
55 8, 16, 19, 22, 26, 27, 29, 34,
56 16, 16, 22, 24, 27, 29, 34, 37,
57 19, 22, 26, 27, 29, 34, 34, 38,
58 22, 22, 26, 27, 29, 34, 37, 40,
59 22, 26, 27, 29, 32, 35, 40, 48,
60 26, 27, 29, 32, 35, 40, 48, 58,
61 26, 27, 29, 34, 38, 46, 56, 69,
62 27, 29, 35, 38, 46, 56, 69, 83
63};
64
65unsigned char mpeg3_non_linear_mquant_table[32] =
66{
67 0, 1, 2, 3, 4, 5, 6, 7,
68 8, 10, 12, 14, 16, 18, 20, 22,
69 24, 28, 32, 36, 40, 44, 48, 52,
70 56, 64, 72, 80, 88, 96, 104, 112
71};
72
73double mpeg3_frame_rate_table[16] =
74{
75 0.0, /* Pad */
76 24000.0/1001.0, /* Official frame rates */
77 24.0,
78 25.0,
79 30000.0/1001.0,
80 30.0,
81 50.0,
82 ((60.0*1000.0)/1001.0),
83 60.0,
84
85 1, /* Unofficial economy rates */
86 5,
87 10,
88 12,
89 15,
90 0,
91 0,
92};
93
94int mpeg3video_initdecoder(mpeg3video_t *video)
95{
96 int blk_cnt_tab[3] = {6, 8, 12};
97 int cc;
98 int i;
99 long size[4], padding[2]; /* Size of Y, U, and V buffers */
100
101 if(!video->mpeg2)
102 {
103/* force MPEG-1 parameters */
104 video->prog_seq = 1;
105 video->prog_frame = 1;
106 video->pict_struct = FRAME_PICTURE;
107 video->frame_pred_dct = 1;
108 video->chroma_format = CHROMA420;
109 video->matrix_coefficients = 5;
110 }
111
112/* Get dimensions rounded to nearest multiple of coded macroblocks */
113 video->mb_width = (video->horizontal_size + 15) / 16;
114 video->mb_height = (video->mpeg2 && !video->prog_seq) ?
115 (2 * ((video->vertical_size + 31) / 32)) :
116 ((video->vertical_size + 15) / 16);
117 video->coded_picture_width = 16 * video->mb_width;
118 video->coded_picture_height = 16 * video->mb_height;
119 video->chrom_width = (video->chroma_format == CHROMA444) ?
120 video->coded_picture_width :
121 (video->coded_picture_width >> 1);
122 video->chrom_height = (video->chroma_format != CHROMA420) ?
123 video->coded_picture_height :
124 (video->coded_picture_height >> 1);
125 video->blk_cnt = blk_cnt_tab[video->chroma_format - 1];
126
127/* Get sizes of YUV buffers */
128 padding[0] = 16 * video->coded_picture_width;
129 size[0] = video->coded_picture_width * video->coded_picture_height + padding[0] * 2;
130
131 padding[1] = 16 * video->chrom_width;
132 size[1] = video->chrom_width * video->chrom_height + 2 * padding[1];
133
134 size[2] = (video->llw * video->llh);
135 size[3] = (video->llw * video->llh) / 4;
136
137/* Allocate contiguous fragments for YUV buffers for hardware YUV decoding */
138 video->yuv_buffer[0] = (unsigned char*)calloc(1, (size[0] + padding[0]) + 2 * (size[1] + padding[1]));
139 video->yuv_buffer[1] = (unsigned char*)calloc(1, (size[0] + padding[0]) + 2 * (size[1] + padding[1]));
140 video->yuv_buffer[2] = (unsigned char*)calloc(1, (size[0] + padding[0]) + 2 * (size[1] + padding[1]));
141
142 if(video->scalable_mode == SC_SPAT)
143 {
144 video->yuv_buffer[3] = (unsigned char*)calloc(1, size[2] + 2 * size[3]);
145 video->yuv_buffer[4] = (unsigned char*)calloc(1, size[2] + 2 * size[3]);
146 }
147
148 /* Direct pointers to areas of contiguous fragments in YVU order per Microsoft */
149 for(cc = 0; cc < 3; cc++)
150 {
151 video->llframe0[cc] = 0;
152 video->llframe1[cc] = 0;
153 video->newframe[cc] = 0;
154 }
155
156 video->refframe[0] = video->yuv_buffer[0];
157 video->oldrefframe[0] = video->yuv_buffer[1];
158 video->auxframe[0] = video->yuv_buffer[2];
159 video->refframe[2] = video->yuv_buffer[0] + size[0] + padding[0];
160 video->oldrefframe[2] = video->yuv_buffer[1] + size[0] + padding[0];
161 video->auxframe[2] = video->yuv_buffer[2] + size[0] + padding[0];
162 video->refframe[1] = video->yuv_buffer[0] + size[0] + padding[0] + size[1] + padding[1];
163 video->oldrefframe[1] = video->yuv_buffer[1] + size[0] + padding[0] + size[1] + padding[1];
164 video->auxframe[1] = video->yuv_buffer[2] + size[0] + padding[0] + size[1] + padding[1];
165
166 if(video->scalable_mode == SC_SPAT)
167 {
168/* this assumes lower layer is 4:2:0 */
169 video->llframe0[0] = video->yuv_buffer[3] + padding[0] ;
170 video->llframe1[0] = video->yuv_buffer[4] + padding[0] ;
171 video->llframe0[2] = video->yuv_buffer[3] + padding[1] + size[2] ;
172 video->llframe1[2] = video->yuv_buffer[4] + padding[1] + size[2] ;
173 video->llframe0[1] = video->yuv_buffer[3] + padding[1] + size[2] + size[3];
174 video->llframe1[1] = video->yuv_buffer[4] + padding[1] + size[2] + size[3];
175 }
176
177/* Initialize the YUV tables for software YUV decoding */
178 video->cr_to_r = (long*)malloc(sizeof(long) * 256);
179 video->cr_to_g = (long*)malloc(sizeof(long) * 256);
180 video->cb_to_g = (long*)malloc(sizeof(long) * 256);
181 video->cb_to_b = (long*)malloc(sizeof(long) * 256);
182 video->cr_to_r_ptr = video->cr_to_r + 128;
183 video->cr_to_g_ptr = video->cr_to_g + 128;
184 video->cb_to_g_ptr = video->cb_to_g + 128;
185 video->cb_to_b_ptr = video->cb_to_b + 128;
186
187 for(i = -128; i < 128; i++)
188 {
189 video->cr_to_r_ptr[i] = (long)( 1.371 * 65536 * i);
190 video->cr_to_g_ptr[i] = (long)(-0.698 * 65536 * i);
191 video->cb_to_g_ptr[i] = (long)(-0.336 * 65536 * i);
192 video->cb_to_b_ptr[i] = (long)( 1.732 * 65536 * i);
193 }
194
195 return 0;
196}
197
198int mpeg3video_deletedecoder(mpeg3video_t *video)
199{
200 int i, padding;
201
202 free(video->yuv_buffer[0]);
203 free(video->yuv_buffer[1]);
204 free(video->yuv_buffer[2]);
205
206 if(video->llframe0[0])
207 {
208 free(video->yuv_buffer[3]);
209 free(video->yuv_buffer[4]);
210 }
211
212 free(video->cr_to_r);
213 free(video->cr_to_g);
214 free(video->cb_to_g);
215 free(video->cb_to_b);
216 return 0;
217}
218
219void mpeg3video_init_scantables(mpeg3video_t *video)
220{
221#ifdef HAVE_MMX
222 if(video->have_mmx)
223 {
224 video->mpeg3_zigzag_scan_table = mpeg3_zig_zag_scan_mmx;
225 video->mpeg3_alternate_scan_table = mpeg3_alternate_scan_mmx;
226 }
227 else
228#endif
229 {
230 video->mpeg3_zigzag_scan_table = mpeg3_zig_zag_scan_nommx;
231 video->mpeg3_alternate_scan_table = mpeg3_alternate_scan_nommx;
232 }
233}
234
235mpeg3video_t* mpeg3video_allocate_struct(mpeg3_t *file, mpeg3_vtrack_t *track)
236{
237 int i;
238 mpeg3video_t *video = (mpeg3video_t*)calloc(1, sizeof(mpeg3video_t));
239 pthread_mutexattr_t mutex_attr;
240
241 video->file = file;
242 video->track = track;
243 video->vstream = mpeg3bits_new_stream(file, track->demuxer);
244 video->last_number = -1;
245
246/* First frame is all green */
247 video->framenum = -1;
248 video->have_mmx = file->have_mmx;
249
250 video->percentage_seek = -1;
251 video->frame_seek = -1;
252
253 mpeg3video_init_scantables(video);
254 mpeg3video_init_output();
255
256 pthread_mutexattr_init(&mutex_attr);
257 pthread_mutex_init(&(video->test_lock), &mutex_attr);
258 pthread_mutex_init(&(video->slice_lock), &mutex_attr);
259 return video;
260}
261
262int mpeg3video_delete_struct(mpeg3video_t *video)
263{
264 int i;
265 mpeg3bits_delete_stream(video->vstream);
266 pthread_mutex_destroy(&(video->test_lock));
267 pthread_mutex_destroy(&(video->slice_lock));
268 if(video->x_table)
269 {
270 free(video->x_table);
271 free(video->y_table);
272 }
273 if(video->total_slice_decoders)
274 {
275 for(i = 0; i < video->total_slice_decoders; i++)
276 mpeg3_delete_slice_decoder(&video->slice_decoders[i]);
277 }
278 for(i = 0; i < video->slice_buffers_initialized; i++)
279 mpeg3_delete_slice_buffer(&(video->slice_buffers[i]));
280
281 free(video);
282}
283
284
285int mpeg3video_read_frame_backend(mpeg3video_t *video, int skip_bframes)
286{
287 int result = 0;
288
289 if(mpeg3bits_eof(video->vstream)) result = 1;
290
291 if(!result) result = mpeg3video_get_header(video, 0);
292
293//printf("frame type %d\n", video->pict_type);
294/* skip_bframes is the number of bframes we can skip successfully. */
295/* This is in case a skipped B-frame is repeated and the second repeat happens */
296/* to be a B frame we need. */
297 video->skip_bframes = skip_bframes;
298
299 if(!result)
300 result = mpeg3video_getpicture(video, video->framenum);
301
302#ifdef HAVE_MMX
303 if(video->have_mmx)
304 __asm__ __volatile__ ("emms");
305#endif
306
307 if(!result)
308 {
309 video->last_number = video->framenum;
310 video->framenum++;
311 }
312 return result;
313}
314
315int* mpeg3video_get_scaletable(int input_w, int output_w)
316{
317 int *result = (int*)malloc(sizeof(int) * output_w);
318 float i;
319 float scale = (float)input_w / output_w;
320 for(i = 0; i < output_w; i++)
321 {
322 result[(int)i] = (int)(scale * i);
323 }
324 return result;
325}
326
327/* Get the first frame read. */
328int mpeg3video_get_firstframe(mpeg3video_t *video)
329{
330 int result = 0;
331 if(video->framenum < 0)
332 {
333 video->repeat_count = video->current_repeat = 0;
334 result = mpeg3video_read_frame_backend(video, 0);
335 mpeg3bits_seek_byte(video->vstream, 0);
336 mpeg3video_match_refframes(video);
337 }
338 return result;
339}
340
341
342/* ======================================================================= */
343/* ENTRY POINTS */
344/* ======================================================================= */
345
346
347
348mpeg3video_t* mpeg3video_new(mpeg3_t *file, mpeg3_vtrack_t *track)
349{
350 mpeg3video_t *video;
351 int result = 0;
352
353 video = mpeg3video_allocate_struct(file, track);
354 result = mpeg3video_get_header(video, 1);
355
356 if(!result)
357 {
358 int hour, minute, second, frame;
359 int gop_found;
360
361 mpeg3video_initdecoder(video);
362 video->decoder_initted = 1;
363 track->width = video->horizontal_size;
364 track->height = video->vertical_size;
365 track->frame_rate = video->frame_rate;
366
367/* Get the length of the file from an elementary stream */
368 if(file->is_video_stream)
369 {
370/* Load the first GOP */
371 mpeg3bits_seek_start(video->vstream);
372 result = mpeg3video_next_code(video->vstream, MPEG3_GOP_START_CODE);
373 if(!result) mpeg3bits_getbits(video->vstream, 32);
374 if(!result) result = mpeg3video_getgophdr(video);
375
376 hour = video->gop_timecode.hour;
377 minute = video->gop_timecode.minute;
378 second = video->gop_timecode.second;
379 frame = video->gop_timecode.frame;
380 video->first_frame = (long)(hour * 3600 * video->frame_rate +
381 minute * 60 * video->frame_rate +
382 second * video->frame_rate +
383 frame);
384
385/* GOPs always have 16 frames */
386 video->frames_per_gop = 16;
387
388/* Read the last GOP in the file by seeking backward. */
389 mpeg3bits_seek_end(video->vstream);
390 mpeg3bits_start_reverse(video->vstream);
391 result = mpeg3video_prev_code(video->vstream, MPEG3_GOP_START_CODE);
392 mpeg3bits_start_forward(video->vstream);
393 mpeg3bits_getbits(video->vstream, 8);
394 if(!result) result = mpeg3video_getgophdr(video);
395
396 hour = video->gop_timecode.hour;
397 minute = video->gop_timecode.minute;
398 second = video->gop_timecode.second;
399 frame = video->gop_timecode.frame;
400
401 video->last_frame = (long)(hour * 3600 * video->frame_rate +
402 minute * 60 * video->frame_rate +
403 second * video->frame_rate +
404 frame);
405
406/* Count number of frames to end */
407 while(!result)
408 {
409 result = mpeg3video_next_code(video->vstream, MPEG3_PICTURE_START_CODE);
410 if(!result)
411 {
412 mpeg3bits_getbyte_noptr(video->vstream);
413 video->last_frame++;
414 }
415 }
416
417 track->total_frames = video->last_frame - video->first_frame + 1;
418 mpeg3bits_seek_start(video->vstream);
419 }
420 else
421 {
422/* Gross approximation from a multiplexed file. */
423 video->first_frame = 0;
424 track->total_frames = video->last_frame =
425 (long)(mpeg3demux_length(video->vstream->demuxer) *
426 video->frame_rate);
427 video->first_frame = 0;
428 }
429
430 video->maxframe = track->total_frames;
431 mpeg3bits_seek_start(video->vstream);
432 }
433 else
434 {
435 mpeg3video_delete(video);
436 video = 0;
437 }
438
439 return video;
440}
441
442int mpeg3video_delete(mpeg3video_t *video)
443{
444 if(video->decoder_initted)
445 {
446 mpeg3video_deletedecoder(video);
447 }
448 mpeg3video_delete_struct(video);
449 return 0;
450}
451
452int mpeg3video_set_cpus(mpeg3video_t *video, int cpus)
453{
454 return 0;
455}
456
457int mpeg3video_set_mmx(mpeg3video_t *video, int use_mmx)
458{
459 video->have_mmx = use_mmx;
460 mpeg3video_init_scantables(video);
461 return 0;
462}
463
464int mpeg3video_seek_percentage(mpeg3video_t *video, double percentage)
465{
466 video->percentage_seek = percentage;
467 return 0;
468}
469
470int mpeg3video_previous_frame(mpeg3video_t *video)
471{
472 if(mpeg3bits_tell_percentage(video->vstream) <= 0) return 1;
473 mpeg3bits_start_reverse(video->vstream);
474 mpeg3video_prev_code(video->vstream, MPEG3_PICTURE_START_CODE);
475 mpeg3bits_getbits_reverse(video->vstream, 32);
476
477 if(mpeg3bits_bof(video->vstream)) mpeg3bits_seek_percentage(video->vstream, 0);
478 mpeg3bits_start_forward(video->vstream);
479 video->repeat_count = 0;
480 return 0;
481}
482
483int mpeg3video_seek_frame(mpeg3video_t *video, long frame)
484{
485 video->frame_seek = frame;
486 return 0;
487}
488
489/* Read all the way up to and including the next picture start code */
490int mpeg3video_read_raw(mpeg3video_t *video, unsigned char *output, long *size, long max_size)
491{
492 unsigned MPEG3_INT32 code = 0;
493 mpeg3_bits_t *vstream = video->vstream;
494
495 *size = 0;
496 while(code != MPEG3_PICTURE_START_CODE &&
497 code != MPEG3_SEQUENCE_END_CODE &&
498 *size < max_size &&
499 !mpeg3bits_eof(vstream))
500 {
501 code <<= 8;
502 *output = mpeg3bits_getbyte_noptr(vstream);
503 code |= *output++;
504 (*size)++;
505 }
506 return mpeg3bits_eof(vstream);
507}
508
509int mpeg3video_read_frame(mpeg3video_t *video,
510 long frame_number,
511 unsigned char **output_rows,
512 int in_x,
513 int in_y,
514 int in_w,
515 int in_h,
516 int out_w,
517 int out_h,
518 int color_model)
519{
520 int result = 0;
521
522 video->want_yvu = 0;
523 video->output_rows = output_rows;
524 video->color_model = color_model;
525
526/* Get scaling tables */
527 if(video->out_w != out_w || video->out_h != out_h ||
528 video->in_w != in_w || video->in_h != in_h ||
529 video->in_x != in_x || video->in_y != in_y)
530 {
531 if(video->x_table)
532 {
533 free(video->x_table);
534 free(video->y_table);
535 video->x_table = 0;
536 video->y_table = 0;
537 }
538 }
539
540 video->out_w = out_w;
541 video->out_h = out_h;
542 video->in_w = in_w;
543 video->in_h = in_h;
544 video->in_x = in_x;
545 video->in_y = in_y;
546
547 if(!video->x_table)
548 {
549 video->x_table = mpeg3video_get_scaletable(video->in_w, video->out_w);
550 video->y_table = mpeg3video_get_scaletable(video->in_h, video->out_h);
551 }
552
553 mpeg3video_get_firstframe(video);
554
555 if(!result) result = mpeg3video_seek(video);
556
557 if(!result) result = mpeg3video_read_frame_backend(video, 0);
558
559 if(video->output_src) mpeg3video_present_frame(video);
560
561 video->percentage_seek = -1;
562 return result;
563}
564
565int mpeg3video_read_yuvframe(mpeg3video_t *video,
566 long frame_number,
567 char *y_output,
568 char *u_output,
569 char *v_output,
570 int in_x,
571 int in_y,
572 int in_w,
573 int in_h)
574{
575 int result = 0;
576
577 video->want_yvu = 1;
578 video->y_output = y_output;
579 video->u_output = u_output;
580 video->v_output = v_output;
581 video->in_x = in_x;
582 video->in_y = in_y;
583 video->in_w = in_w;
584 video->in_h = in_h;
585
586 mpeg3video_get_firstframe(video);
587
588 if(!result) result = mpeg3video_seek(video);
589
590 if(!result) result = mpeg3video_read_frame_backend(video, 0);
591
592 if(video->output_src) mpeg3video_present_frame(video);
593
594 video->want_yvu = 0;
595 video->percentage_seek = -1;
596 return result;
597}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef MPEGVIDEO_H
21#define MPEGVIDEO_H
22
23#include "../bitstream.h"
24#include "../mpeg3private.inc"
25#include "idct.h"
26#include "slice.h"
27#include "../timecode.h"
28
29/* zig-zag scan */
30extern unsigned char mpeg3_zig_zag_scan_nommx[64];
31extern unsigned char mpeg3_zig_zag_scan_mmx[64];
32
33/* alternate scan */
34extern unsigned char mpeg3_alternate_scan_nommx[64];
35extern unsigned char mpeg3_alternate_scan_mmx[64];
36
37/* default intra quantization matrix */
38extern unsigned char mpeg3_default_intra_quantizer_matrix[64];
39
40/* Frame rate table must agree with the one in the encoder */
41extern double mpeg3_frame_rate_table[16];
42
43/* non-linear quantization coefficient table */
44extern unsigned char mpeg3_non_linear_mquant_table[32];
45
46#define CHROMA420 1 /* chroma_format */
47#define CHROMA422 2
48#define CHROMA444 3
49
50#define TOP_FIELD 1 /* picture structure */
51#define BOTTOM_FIELD 2
52#define FRAME_PICTURE 3
53
54#define SEQ_ID 1 /* extension start code IDs */
55#define DISP_ID 2
56#define QUANT_ID 3
57#define SEQSCAL_ID 5
58#define PANSCAN_ID 7
59#define CODING_ID 8
60#define SPATSCAL_ID 9
61#define TEMPSCAL_ID 10
62
63#define ERROR (-1)
64
65#define SC_NONE 0 /* scalable_mode */
66#define SC_DP 1
67#define SC_SPAT 2
68#define SC_SNR 3
69#define SC_TEMP 4
70
71#define I_TYPE 1 /* picture coding type */
72#define P_TYPE 2
73#define B_TYPE 3
74#define D_TYPE 4
75
76 #define MB_INTRA 1 /* macroblock type */
77#define MB_PATTERN 2
78#define MB_BACKWARD 4
79#define MB_FORWARD 8
80#define MB_QUANT 16
81#define MB_WEIGHT 32
82#define MB_CLASS4 64
83
84#define MC_FIELD 1 /* motion_type */
85#define MC_FRAME 2
86#define MC_16X8 2
87#define MC_DMV 3
88
89#define MV_FIELD 0 /* mv_format */
90#define MV_FRAME 1
91
92#define CLIP(x) ((x) >= 0 ? ((x) < 255 ? (x) : 255) : 0)
93
94/* Statically allocate as little as possible so a fake video struct */
95/* can be used for reading the GOP headers. */
96
97struct mpeg3video_rec
98{
99 struct mpeg3_rec* file;
100 struct mpeg3_vtrack_rec* track;
101
102/* ================================= Seeking variables ========================= */
103 mpeg3_bits_t *vstream;
104 int decoder_initted;
105 unsigned char **output_rows; /* Output frame buffer supplied by user */
106 int in_x, in_y, in_w, in_h, out_w, out_h; /* Output dimensions */
107 int *x_table, *y_table; /* Location of every output pixel in the input */
108 int color_model;
109 int want_yvu; /* Want to return a YUV frame */
110 char *y_output, *u_output, *v_output; /* Output pointers for a YUV frame */
111
112 mpeg3_slice_t slice_decoders[MPEG3_MAX_CPUS]; /* One slice decoder for every CPU */
113 int total_slice_decoders; /* Total slice decoders in use */
114 mpeg3_slice_buffer_t slice_buffers[MPEG3_MAX_CPUS]; /* Buffers for holding the slice data */
115 int total_slice_buffers; /* Total buffers in the array to be decompressed */
116 int slice_buffers_initialized; /* Total buffers initialized in the array */
117 pthread_mutex_t slice_lock; /* Lock slice array while getting the next buffer */
118 pthread_mutex_t test_lock;
119
120 int blockreadsize;
121 long maxframe; /* Max value of frame num to read */
122 double percentage_seek; /* Perform a percentage seek before the next frame is read */
123 int frame_seek; /* Perform a frame seek before the next frame is read */
124 long framenum; /* Number of the next frame to be decoded */
125 long last_number; /* Last framenum rendered */
126 int found_seqhdr;
127 long bitrate;
128 mpeg3_timecode_t gop_timecode; /* Timecode for the last GOP header read. */
129
130/* These are only available from elementary streams. */
131 long frames_per_gop; /* Frames per GOP after the first GOP. */
132 long first_gop_frames; /* Frames in the first GOP. */
133 long first_frame; /* Number of first frame stored in timecode */
134 long last_frame; /* Last frame in file */
135
136/* ================================= Compression variables ===================== */
137/* Malloced frame buffers. 2 refframes are swapped in and out. */
138/* while only 1 auxframe is used. */
139 unsigned char *yuv_buffer[5]; /* Make YVU buffers contiguous for all frames */
140 unsigned char *oldrefframe[3], *refframe[3], *auxframe[3];
141 unsigned char *llframe0[3], *llframe1[3];
142 unsigned char *mpeg3_zigzag_scan_table;
143 unsigned char *mpeg3_alternate_scan_table;
144// Source for the next frame presentation
145 unsigned char **output_src;
146/* Pointers to frame buffers. */
147 unsigned char *newframe[3];
148 int horizontal_size, vertical_size, mb_width, mb_height;
149 int coded_picture_width, coded_picture_height;
150 int chroma_format, chrom_width, chrom_height, blk_cnt;
151 int pict_type;
152 int forw_r_size, back_r_size, full_forw, full_back;
153 int prog_seq, prog_frame;
154 int h_forw_r_size, v_forw_r_size, h_back_r_size, v_back_r_size;
155 int dc_prec, pict_struct, topfirst, frame_pred_dct, conceal_mv;
156 int intravlc;
157 int repeatfirst;
158 int repeat_count; /* Number of times to repeat the current frame * 100 since floating point is impossible in MMX */
159 int current_repeat; /* Number of times the current frame has been repeated * 100 */
160 int secondfield;
161 int skip_bframes;
162 int stwc_table_index, llw, llh, hm, hn, vm, vn;
163 int lltempref, llx0, lly0, llprog_frame, llfieldsel;
164 int matrix_coefficients;
165 int framerate_code;
166 float frame_rate;
167 long *cr_to_r, *cr_to_g, *cb_to_g, *cb_to_b;
168 long *cr_to_r_ptr, *cr_to_g_ptr, *cb_to_g_ptr, *cb_to_b_ptr;
169 int have_mmx;
170 int intra_quantizer_matrix[64], non_intra_quantizer_matrix[64];
171 int chroma_intra_quantizer_matrix[64], chroma_non_intra_quantizer_matrix[64];
172 int mpeg2;
173 int qscale_type, altscan; /* picture coding extension */
174 int pict_scal; /* picture spatial scalable extension */
175 int scalable_mode; /* sequence scalable extension */
176};
177
178typedef struct mpeg3video_rec mpeg3video_t;
179
180#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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef MPEG3VIDEOPROTOS_H
21#define MPEG3VIDEOPROTOS_H
22
23void mpeg3video_idct_conversion(short* block);
24unsigned int mpeg3slice_showbits(mpeg3_slice_buffer_t *slice_buffer, int bits);
25
26#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 @@
1#include "../libmpeg3.h"
2#include "../mpeg3protos.h"
3#include "mpeg3video.h"
4#include <string.h>
5
6static LONGLONG mpeg3_MMX_0 = 0L;
7static unsigned long mpeg3_MMX_10w[] = {0x00100010, 0x00100010}; /*dd 00010 0010h, 000100010h */
8static unsigned long mpeg3_MMX_80w[] = {0x00800080, 0x00800080}; /*dd 00080 0080h, 000800080h */
9
10static unsigned long mpeg3_MMX_00FFw[] = {0x00ff00ff, 0x00ff00ff}; /*dd 000FF 00FFh, 000FF00FFh */
11
12static unsigned short mpeg3_MMX_Ublucoeff[] = {0x81, 0x81, 0x81, 0x81}; /*dd 00081 0081h, 000810081h */
13static unsigned short mpeg3_MMX_Vredcoeff[] = {0x66, 0x66, 0x66, 0x66}; /*dd 00066 0066h, 000660066h */
14
15static unsigned short mpeg3_MMX_Ugrncoeff[] = {0xffe8, 0xffe8, 0xffe8, 0xffe8}; /*dd 0FFE7 FFE7h, 0FFE7FFE7h */
16static unsigned short mpeg3_MMX_Vgrncoeff[] = {0xffcd, 0xffcd, 0xffcd, 0xffcd}; /*dd 0FFCC FFCCh, 0FFCCFFCCh */
17
18static unsigned short mpeg3_MMX_Ycoeff[] = {0x4a, 0x4a, 0x4a, 0x4a}; /*dd 0004A 004Ah, 0004A004Ah */
19
20static unsigned short mpeg3_MMX_redmask[] = {0xf800, 0xf800, 0xf800, 0xf800}; /*dd 07c00 7c00h, 07c007c00h */
21
22static unsigned short mpeg3_MMX_grnmask[] = {0x7e0, 0x7e0, 0x7e0, 0x7e0}; /*dd 003e0 03e0h, 003e003e0h */
23
24static unsigned char mpeg3_601_to_rgb[256];
25
26/* Algorithm */
27 /* r = (int)(*y + 1.371 * (*cr - 128)); */
28 /* g = (int)(*y - 0.698 * (*cr - 128) - 0.336 * (*cb - 128)); */
29 /* b = (int)(*y + 1.732 * (*cb - 128)); */
30
31#ifdef HAVE_MMX
32inline void mpeg3video_rgb16_mmx(unsigned char *lum,
33 unsigned char *cr,
34 unsigned char *cb,
35 unsigned char *out,
36 int rows,
37 int cols,
38 int mod)
39{
40 unsigned short *row1;
41 int x;
42 unsigned char *y;
43 int col1;
44
45 row1 = (unsigned short *)out;
46 col1 = cols + mod;
47 mod += cols + mod;
48 mod *= 2;
49 y = lum + cols * rows;
50 x = 0;
51
52 __asm__ __volatile__(
53 ".align 8\n"
54 "1:\n"
55 "movd (%1), %%mm0\n" /* 4 Cb 0 0 0 0 u3 u2 u1 u0 */
56 "pxor %%mm7, %%mm7\n"
57 "movd (%0), %%mm1\n" /* 4 Cr 0 0 0 0 v3 v2 v1 v0 */
58 "punpcklbw %%mm7, %%mm0\n" /* 4 W cb 0 u3 0 u2 0 u1 0 u0 */
59 "punpcklbw %%mm7, %%mm1\n" /* 4 W cr 0 v3 0 v2 0 v1 0 v0 */
60
61 "psubw mpeg3_MMX_80w, %%mm0\n"
62 "psubw mpeg3_MMX_80w, %%mm1\n"
63 "movq %%mm0, %%mm2\n" /* Cb 0 u3 0 u2 0 u1 0 u0 */
64 "movq %%mm1, %%mm3\n" /* Cr */
65 "pmullw mpeg3_MMX_Ugrncoeff, %%mm2\n" /* Cb2green 0 R3 0 R2 0 R1 0 R0 */
66 "movq (%2), %%mm6\n" /* L1 l7 L6 L5 L4 L3 L2 L1 L0 */
67 "pmullw mpeg3_MMX_Ublucoeff, %%mm0\n" /* Cb2blue */
68 "pand mpeg3_MMX_00FFw, %%mm6\n" /* L1 00 L6 00 L4 00 L2 00 L0 */
69 "pmullw mpeg3_MMX_Vgrncoeff, %%mm3\n" /* Cr2green */
70 "movq (%2), %%mm7\n" /* L2 */
71 "pmullw mpeg3_MMX_Vredcoeff, %%mm1\n" /* Cr2red */
72 "psrlw $8, %%mm7\n" /* L2 00 L7 00 L5 00 L3 00 L1 */
73 "pmullw mpeg3_MMX_Ycoeff, %%mm6\n" /* lum1 */
74 "paddw %%mm3, %%mm2\n" /* Cb2green + Cr2green == green */
75 "pmullw mpeg3_MMX_Ycoeff, %%mm7\n" /* lum2 */
76
77 "movq %%mm6, %%mm4\n" /* lum1 */
78 "paddw %%mm0, %%mm6\n" /* lum1 +blue 00 B6 00 B4 00 B2 00 B0 */
79 "movq %%mm4, %%mm5\n" /* lum1 */
80 "paddw %%mm1, %%mm4\n" /* lum1 +red 00 R6 00 R4 00 R2 00 R0 */
81 "paddw %%mm2, %%mm5\n" /* lum1 +green 00 G6 00 G4 00 G2 00 G0 */
82 "psraw $6, %%mm4\n" /* R1 0 .. 64 */
83 "movq %%mm7, %%mm3\n" /* lum2 00 L7 00 L5 00 L3 00 L1 */
84 "psraw $6, %%mm5\n" /* G1 - .. + */
85 "paddw %%mm0, %%mm7\n" /* Lum2 +blue 00 B7 00 B5 00 B3 00 B1 */
86 "psraw $6, %%mm6\n" /* B1 0 .. 64 */
87 "packuswb %%mm4, %%mm4\n" /* R1 R1 */
88 "packuswb %%mm5, %%mm5\n" /* G1 G1 */
89 "packuswb %%mm6, %%mm6\n" /* B1 B1 */
90 "punpcklbw %%mm4, %%mm4\n"
91 "punpcklbw %%mm5, %%mm5\n"
92
93 "pand mpeg3_MMX_redmask, %%mm4\n"
94 "psllw $3, %%mm5\n" /* GREEN 1 */
95 "punpcklbw %%mm6, %%mm6\n"
96 "pand mpeg3_MMX_grnmask, %%mm5\n"
97 "pand mpeg3_MMX_redmask, %%mm6\n"
98 "por %%mm5, %%mm4\n" /* */
99 "psrlw $11, %%mm6\n" /* BLUE 1 */
100 "movq %%mm3, %%mm5\n" /* lum2 */
101 "paddw %%mm1, %%mm3\n" /* lum2 +red 00 R7 00 R5 00 R3 00 R1 */
102 "paddw %%mm2, %%mm5\n" /* lum2 +green 00 G7 00 G5 00 G3 00 G1 */
103 "psraw $6, %%mm3\n" /* R2 */
104 "por %%mm6, %%mm4\n" /* MM4 */
105 "psraw $6, %%mm5\n" /* G2 */
106 "movq (%2, %3), %%mm6\n" /* L3 */
107 "psraw $6, %%mm7\n"
108 "packuswb %%mm3, %%mm3\n"
109 "packuswb %%mm5, %%mm5\n"
110 "packuswb %%mm7, %%mm7\n"
111 "pand mpeg3_MMX_00FFw, %%mm6\n" /* L3 */
112 "punpcklbw %%mm3, %%mm3\n"
113 "punpcklbw %%mm5, %%mm5\n"
114 "pmullw mpeg3_MMX_Ycoeff, %%mm6\n" /* lum3 */
115 "punpcklbw %%mm7, %%mm7\n"
116 "psllw $3, %%mm5\n" /* GREEN 2 */
117 "pand mpeg3_MMX_redmask, %%mm7\n"
118 "pand mpeg3_MMX_redmask, %%mm3\n"
119 "psrlw $11, %%mm7\n" /* BLUE 2 */
120 "pand mpeg3_MMX_grnmask, %%mm5\n"
121 "por %%mm7, %%mm3\n"
122 "movq (%2,%3), %%mm7\n" /* L4 */
123 "por %%mm5, %%mm3\n" /* */
124 "psrlw $8, %%mm7\n" /* L4 */
125 "movq %%mm4, %%mm5\n"
126 "punpcklwd %%mm3, %%mm4\n"
127 "pmullw mpeg3_MMX_Ycoeff, %%mm7\n" /* lum4 */
128 "punpckhwd %%mm3, %%mm5\n"
129
130 "movq %%mm4, (%4)\n"
131 "movq %%mm5, 8(%4)\n"
132
133 "movq %%mm6, %%mm4\n" /* Lum3 */
134 "paddw %%mm0, %%mm6\n" /* Lum3 +blue */
135
136 "movq %%mm4, %%mm5\n" /* Lum3 */
137 "paddw %%mm1, %%mm4\n" /* Lum3 +red */
138 "paddw %%mm2, %%mm5\n" /* Lum3 +green */
139 "psraw $6, %%mm4\n"
140 "movq %%mm7, %%mm3\n"/* Lum4 */
141 "psraw $6, %%mm5\n"
142 "paddw %%mm0, %%mm7\n" /* Lum4 +blue */
143 "psraw $6, %%mm6\n" /* Lum3 +blue */
144 "movq %%mm3, %%mm0\n" /* Lum4 */
145 "packuswb %%mm4, %%mm4\n"
146 "paddw %%mm1, %%mm3\n" /* Lum4 +red */
147 "packuswb %%mm5, %%mm5\n"
148 "paddw %%mm2, %%mm0\n" /* Lum4 +green */
149 "packuswb %%mm6, %%mm6\n"
150 "punpcklbw %%mm4, %%mm4\n"
151 "punpcklbw %%mm5, %%mm5\n"
152 "punpcklbw %%mm6, %%mm6\n"
153 "psllw $3, %%mm5\n" /* GREEN 3 */
154 "pand mpeg3_MMX_redmask, %%mm4\n"
155 "psraw $6, %%mm3\n" /* psr 6 */
156 "psraw $6, %%mm0\n"
157 "pand mpeg3_MMX_redmask, %%mm6\n" /* BLUE */
158 "pand mpeg3_MMX_grnmask, %%mm5\n"
159 "psrlw $11, %%mm6\n" /* BLUE 3 */
160 "por %%mm5, %%mm4\n"
161 "psraw $6, %%mm7\n"
162 "por %%mm6, %%mm4\n"
163 "packuswb %%mm3, %%mm3\n"
164 "packuswb %%mm0, %%mm0\n"
165 "packuswb %%mm7, %%mm7\n"
166 "punpcklbw %%mm3, %%mm3\n"
167 "punpcklbw %%mm0, %%mm0\n"
168 "punpcklbw %%mm7, %%mm7\n"
169 "pand mpeg3_MMX_redmask, %%mm3\n"
170 "pand mpeg3_MMX_redmask, %%mm7\n" /* BLUE */
171 "psllw $3, %%mm0\n" /* GREEN 4 */
172 "psrlw $11, %%mm7\n"
173 "pand mpeg3_MMX_grnmask, %%mm0\n"
174 "por %%mm7, %%mm3\n"
175 "addl $8, %6\n"
176 "por %%mm0, %%mm3\n"
177
178 "movq %%mm4, %%mm5\n"
179
180 "punpcklwd %%mm3, %%mm4\n"
181 "punpckhwd %%mm3, %%mm5\n"
182
183 "movq %%mm4, (%4,%5,2)\n"
184 "movq %%mm5, 8(%4,%5,2)\n"
185
186 "addl $8, %2\n"
187 "addl $4, %0\n"
188 "addl $4, %1\n"
189 "cmpl %3, %6\n"
190 "leal 16(%4), %4\n"
191 "jl 1b\n"
192 "addl %3, %2\n" /* lum += cols */
193 "addl %7, %4\n" /* row1 += mod */
194 "movl $0, %6\n"
195 "cmpl %8, %2\n"
196 "jl 1b\n"
197 : : "r" (cr),
198 "r" (cb),
199 "r" (lum),
200 "r" (cols),
201 "r" (row1) ,
202 "r" (col1),
203 "m" (x),
204 "m" (mod),
205 "m" (y)
206 );
207}
208
209static unsigned LONGLONG mpeg3_MMX_U_80 = 0x0000008000800000LL;
210static unsigned LONGLONG mpeg3_MMX_V_80 = 0x0000000000800080LL;
211static LONGLONG mpeg3_MMX_U_COEF = 0x00000058ffd30000LL;
212static LONGLONG mpeg3_MMX_V_COEF = 0x00000000ffea006fLL;
213static LONGLONG mpeg3_MMX_601_Y_COEF = 0x0000004800480048LL;
214static LONGLONG mpeg3_MMX_601_Y_DIFF = 0x0000000000000010LL;
215
216inline void mpeg3_bgra32_mmx(unsigned long y,
217 unsigned long u,
218 unsigned long v,
219 unsigned long *output)
220{
221asm("
222/* Output will be 0x00rrggbb with the 00 trailing so this can also be used */
223/* for bgr24. */
224 movd (%0), %%mm0; /* Load y 0x00000000000000yy */
225 movd (%1), %%mm1; /* Load u 0x00000000000000cr */
226 movq %%mm0, %%mm3; /* Copy y to temp */
227 psllq $16, %%mm1; /* Shift u 0x0000000000cr0000 */
228 movd (%2), %%mm2; /* Load v 0x00000000000000cb */
229 psllq $16, %%mm3; /* Shift y */
230 movq %%mm1, %%mm4; /* Copy u to temp */
231 por %%mm3, %%mm0; /* Overlay new y byte 0x0000000000yy00yy */
232 psllq $16, %%mm4; /* Shift u */
233 movq %%mm2, %%mm5; /* Copy v to temp */
234 psllq $16, %%mm3; /* Shift y */
235 por %%mm4, %%mm1; /* Overlay new u byte 0x000000cr00cr0000 */
236 psllq $16, %%mm5; /* Shift v */
237 por %%mm3, %%mm0; /* Overlay new y byte 0x000000yy00yy00yy */
238 por %%mm5, %%mm2; /* Overlay new v byte 0x0000000000cb00cb */
239
240/* mm0: 0x000000yy00yy00yy mm1: 0x000000uu00uu0000 mm2: 0x0000000000vv00vv */
241 psubw mpeg3_MMX_U_80, %%mm1; /* Subtract 128 from u 0x000000uu00uu0000 */
242 pmullw mpeg3_MMX_U_COEF, %%mm1; /* Multiply u coeffs 0x0000uuuuuuuu0000 */
243 psllw $6, %%mm0; /* Shift y coeffs 0x0000yyy0yyy0yyy0 */
244 psubw mpeg3_MMX_V_80, %%mm2; /* Subtract 128 from v 0x0000000000cb00cb */
245 pmullw mpeg3_MMX_V_COEF, %%mm2; /* Multiply v coeffs 0x0000crcrcrcrcrcr */
246
247/* mm0: 0x000000yy00yy00yy mm1: 0x0000uuuuuuuu0000 mm2: 0x00000000vvvvvvvv */
248 paddsw %%mm1, %%mm0; /* Add u to result */
249 paddsw %%mm2, %%mm0; /* Add v to result 0x0000rrrrggggbbbb */
250 psraw $6, %%mm0; /* Demote precision */
251 packuswb %%mm0, %%mm0; /* Pack into ARGB 0x0000000000rrggbb */
252 movd %%mm0, (%3); /* Store output */
253 "
254:
255: "r" (&y), "r" (&u), "r" (&v), "r" (output));
256}
257
258inline void mpeg3_601_bgra32_mmx(unsigned long y,
259 unsigned long u,
260 unsigned long v,
261 unsigned long *output)
262{
263asm("
264/* Output will be 0x00rrggbb with the 00 trailing so this can also be used */
265/* for bgr24. */
266 movd (%0), %%mm0; /* Load y 0x00000000000000yy */
267 psubsw mpeg3_MMX_601_Y_DIFF, %%mm0; /* Subtract 16 from y */
268 movd (%1), %%mm1; /* Load u 0x00000000000000cr */
269 movq %%mm0, %%mm3; /* Copy y to temp */
270 psllq $16, %%mm1; /* Shift u 0x0000000000cr0000 */
271 movd (%2), %%mm2; /* Load v 0x00000000000000cb */
272 psllq $16, %%mm3; /* Shift y */
273 movq %%mm1, %%mm4; /* Copy u to temp */
274 por %%mm3, %%mm0; /* Overlay new y byte 0x0000000000yy00yy */
275 psllq $16, %%mm4; /* Shift u */
276 movq %%mm2, %%mm5; /* Copy v to temp */
277 psllq $16, %%mm3; /* Shift y */
278 por %%mm4, %%mm1; /* Overlay new u byte 0x000000cr00cr0000 */
279 psllq $16, %%mm5; /* Shift v */
280 por %%mm3, %%mm0; /* Overlay new y byte 0x000000yy00yy00yy */
281 por %%mm5, %%mm2; /* Overlay new v byte 0x0000000000cb00cb */
282
283/* mm0: 0x000000yy00yy00yy mm1: 0x000000uu00uu0000 mm2: 0x0000000000vv00vv */
284 pmullw mpeg3_MMX_601_Y_COEF, %%mm0; /* Scale and shift y coeffs */
285 psubw mpeg3_MMX_U_80, %%mm1; /* Subtract 128 from u 0x000000uu00uu0000 */
286 pmullw mpeg3_MMX_U_COEF, %%mm1; /* Multiply u coeffs 0x0000uuuuuuuu0000 */
287 psubw mpeg3_MMX_V_80, %%mm2; /* Subtract 128 from v 0x0000000000cb00cb */
288 pmullw mpeg3_MMX_V_COEF, %%mm2; /* Multiply v coeffs 0x0000crcrcrcrcrcr */
289
290/* mm0: 0x000000yy00yy00yy mm1: 0x0000uuuuuuuu0000 mm2: 0x00000000vvvvvvvv */
291 paddsw %%mm1, %%mm0; /* Add u to result */
292 paddsw %%mm2, %%mm0; /* Add v to result 0x0000rrrrggggbbbb */
293 psraw $6, %%mm0; /* Demote precision */
294 packuswb %%mm0, %%mm0; /* Pack into ARGB 0x0000000000rrggbb */
295 movd %%mm0, (%3); /* Store output */
296 "
297:
298: "r" (&y), "r" (&u), "r" (&v), "r" (output));
299}
300
301static unsigned LONGLONG mpeg3_MMX_U_80_RGB = 0x0000000000800080LL;
302static unsigned LONGLONG mpeg3_MMX_V_80_RGB = 0x0000008000800000LL;
303static LONGLONG mpeg3_MMX_U_COEF_RGB = 0x00000000ffd30058LL;
304static LONGLONG mpeg3_MMX_V_COEF_RGB = 0x0000006fffea0000LL;
305
306inline void mpeg3_rgba32_mmx(unsigned long y,
307 unsigned long u,
308 unsigned long v,
309 unsigned long *output)
310{
311asm("
312/* Output will be 0x00bbggrr with the 00 trailing so this can also be used */
313/* for rgb24. */
314 movd (%0), %%mm0; /* Load y 0x00000000000000yy */
315 movd (%1), %%mm1; /* Load v 0x00000000000000vv */
316 movq %%mm0, %%mm3; /* Copy y to temp */
317 psllq $16, %%mm1; /* Shift v 0x0000000000vv0000 */
318 movd (%2), %%mm2; /* Load u 0x00000000000000uu */
319 psllq $16, %%mm3; /* Shift y */
320 movq %%mm1, %%mm4; /* Copy v to temp */
321 por %%mm3, %%mm0; /* Overlay new y byte 0x0000000000yy00yy */
322 psllq $16, %%mm4; /* Shift v */
323 movq %%mm2, %%mm5; /* Copy u to temp */
324 psllq $16, %%mm3; /* Shift y */
325 por %%mm4, %%mm1; /* Overlay new v byte 0x000000vv00vv0000 */
326 psllq $16, %%mm5; /* Shift u */
327 por %%mm3, %%mm0; /* Overlay new y byte 0x000000yy00yy00yy */
328 por %%mm5, %%mm2; /* Overlay new u byte 0x0000000000uu00uu */
329
330/* mm0: 0x000000yy00yy00yy mm1: 0x000000vv00vv0000 mm2: 0x0000000000uu00uu */
331 psubw mpeg3_MMX_V_80_RGB, %%mm1; /* Subtract 128 from v 0x000000vv00vv0000 */
332 pmullw mpeg3_MMX_V_COEF_RGB, %%mm1; /* Multiply v coeffs 0x0000vvvvvvvv0000 */
333 psllw $6, %%mm0; /* Shift y coeffs 0x0000yyy0yyy0yyy0 */
334 psubw mpeg3_MMX_U_80_RGB, %%mm2; /* Subtract 128 from u 0x0000000000uu00uu */
335 pmullw mpeg3_MMX_U_COEF_RGB, %%mm2; /* Multiply u coeffs 0x0000uuuuuuuuuuuu */
336
337/* mm0: 0x000000yy00yy00yy mm1: 0x0000vvvvvvvv0000 mm2: 0x00000000uuuuuuuu */
338 paddsw %%mm1, %%mm0; /* Add v to result */
339 paddsw %%mm2, %%mm0; /* Add u to result 0x0000bbbbggggrrrr */
340 psraw $6, %%mm0; /* Demote precision */
341 packuswb %%mm0, %%mm0; /* Pack into RGBA 0x0000000000bbggrr */
342 movd %%mm0, (%3); /* Store output */
343 "
344:
345: "r" (&y), "r" (&v), "r" (&u), "r" (output));
346}
347
348inline void mpeg3_601_rgba32_mmx(unsigned long y,
349 unsigned long u,
350 unsigned long v,
351 unsigned long *output)
352{
353asm("
354/* Output will be 0x00bbggrr with the 00 trailing so this can also be used */
355/* for rgb24. */
356 movd (%0), %%mm0; /* Load y 0x00000000000000yy */
357 psubsw mpeg3_MMX_601_Y_DIFF, %%mm0; /* Subtract 16 from y */
358 movd (%1), %%mm1; /* Load v 0x00000000000000vv */
359 movq %%mm0, %%mm3; /* Copy y to temp */
360 psllq $16, %%mm1; /* Shift v 0x0000000000vv0000 */
361 movd (%2), %%mm2; /* Load u 0x00000000000000uu */
362 psllq $16, %%mm3; /* Shift y */
363 movq %%mm1, %%mm4; /* Copy v to temp */
364 por %%mm3, %%mm0; /* Overlay new y byte 0x0000000000yy00yy */
365 psllq $16, %%mm4; /* Shift v */
366 movq %%mm2, %%mm5; /* Copy u to temp */
367 psllq $16, %%mm3; /* Shift y */
368 por %%mm4, %%mm1; /* Overlay new v byte 0x000000vv00vv0000 */
369 psllq $16, %%mm5; /* Shift u */
370 por %%mm3, %%mm0; /* Overlay new y byte 0x000000yy00yy00yy */
371 por %%mm5, %%mm2; /* Overlay new u byte 0x0000000000uu00uu */
372
373/* mm0: 0x000000yy00yy00yy mm1: 0x000000vv00vv0000 mm2: 0x0000000000uu00uu */
374 pmullw mpeg3_MMX_601_Y_COEF, %%mm0; /* Scale y coeffs */
375 psubw mpeg3_MMX_V_80_RGB, %%mm1; /* Subtract 128 from v 0x000000vv00vv0000 */
376 pmullw mpeg3_MMX_V_COEF_RGB, %%mm1; /* Multiply v coeffs 0x0000vvvvvvvv0000 */
377 psubw mpeg3_MMX_U_80_RGB, %%mm2; /* Subtract 128 from u 0x0000000000uu00uu */
378 pmullw mpeg3_MMX_U_COEF_RGB, %%mm2; /* Multiply u coeffs 0x0000uuuuuuuuuuuu */
379
380/* mm0: 0x000000yy00yy00yy mm1: 0x0000vvvvvvvv0000 mm2: 0x00000000uuuuuuuu */
381 paddsw %%mm1, %%mm0; /* Add v to result */
382 paddsw %%mm2, %%mm0; /* Add u to result 0x0000bbbbggggrrrr */
383 psraw $6, %%mm0; /* Demote precision */
384 packuswb %%mm0, %%mm0; /* Pack into RGBA 0x0000000000bbggrr */
385 movd %%mm0, (%3); /* Store output */
386 "
387:
388: "r" (&y), "r" (&v), "r" (&u), "r" (output));
389}
390
391#endif
392
393#define DITHER_ROW_HEAD \
394 for(h = 0; h < video->out_h; h++) \
395 { \
396 y_in = &src[0][(video->y_table[h] + video->in_y) * video->coded_picture_width] + video->in_x; \
397 cb_in = &src[1][((video->y_table[h] + video->in_y) >> 1) * video->chrom_width] + (video->in_x >> 2); \
398 cr_in = &src[2][((video->y_table[h] + video->in_y) >> 1) * video->chrom_width] + (video->in_x >> 1); \
399 data = output_rows[h];
400
401#define DITHER_ROW_TAIL \
402 }
403
404#define DITHER_SCALE_HEAD \
405 for(w = 0; w < video->out_w; w++) \
406 { \
407 uv_subscript = video->x_table[w] / 2; \
408 y_l = y_in[video->x_table[w]]; \
409 y_l <<= 16; \
410 r_l = (y_l + video->cr_to_r[cr_in[uv_subscript]]) >> 16; \
411 g_l = (y_l + video->cr_to_g[cr_in[uv_subscript]] + video->cb_to_g[cb_in[uv_subscript]]) >> 16; \
412 b_l = (y_l + video->cb_to_b[cb_in[uv_subscript]]) >> 16;
413
414#define DITHER_SCALE_601_HEAD \
415 for(w = 0; w < video->out_w; w++) \
416 { \
417 uv_subscript = video->x_table[w] / 2; \
418 y_l = mpeg3_601_to_rgb[y_in[video->x_table[w]]]; \
419 y_l <<= 16; \
420 r_l = (y_l + video->cr_to_r[cr_in[uv_subscript]]) >> 16; \
421 g_l = (y_l + video->cr_to_g[cr_in[uv_subscript]] + video->cb_to_g[cb_in[uv_subscript]]) >> 16; \
422 b_l = (y_l + video->cb_to_b[cb_in[uv_subscript]]) >> 16;
423
424#define DITHER_SCALE_TAIL \
425 }
426
427#define DITHER_MMX_SCALE_HEAD \
428 for(w = 0; w < video->out_w; w++) \
429 { \
430 uv_subscript = video->x_table[w] / 2;
431
432#define DITHER_MMX_SCALE_TAIL \
433 data += step; \
434 }
435
436#define DITHER_MMX_HEAD \
437 for(w = 0; w < video->out_w; w += 2) \
438 {
439
440#define DITHER_MMX_TAIL \
441 data += step; \
442 cr_in++; \
443 cb_in++; \
444 }
445
446#define DITHER_HEAD \
447 for(w = 0; w < video->horizontal_size; w++) \
448 { \
449 y_l = *y_in++; \
450 y_l <<= 16; \
451 r_l = (y_l + video->cr_to_r[*cr_in]) >> 16; \
452 g_l = (y_l + video->cr_to_g[*cr_in] + video->cb_to_g[*cb_in]) >> 16; \
453 b_l = (y_l + video->cb_to_b[*cb_in]) >> 16;
454
455#define DITHER_601_HEAD \
456 for(w = 0; w < video->horizontal_size; w++) \
457 { \
458 y_l = mpeg3_601_to_rgb[*y_in++]; \
459 y_l <<= 16; \
460 r_l = (y_l + video->cr_to_r[*cr_in]) >> 16; \
461 g_l = (y_l + video->cr_to_g[*cr_in] + video->cb_to_g[*cb_in]) >> 16; \
462 b_l = (y_l + video->cb_to_b[*cb_in]) >> 16;
463
464#define DITHER_TAIL \
465 if(w & 1) \
466 { \
467 cr_in++; \
468 cb_in++; \
469 } \
470 }
471
472
473#define STORE_PIXEL_BGR888 \
474 *data++ = CLIP(b_l); \
475 *data++ = CLIP(g_l); \
476 *data++ = CLIP(r_l);
477
478#define STORE_PIXEL_BGRA8888 \
479 *data++ = CLIP(b_l); \
480 *data++ = CLIP(g_l); \
481 *data++ = CLIP(r_l); \
482 *data++ = 0;
483
484#define STORE_PIXEL_RGB565 \
485 *((unsigned short*)data)++ = \
486 ((CLIP(r_l) & 0xf8) << 8) | \
487 ((CLIP(g_l) & 0xfc) << 3) | \
488 ((CLIP(b_l) & 0xf8) >> 3);
489
490#define STORE_PIXEL_RGB888 \
491 *data++ = CLIP(r_l); \
492 *data++ = CLIP(g_l); \
493 *data++ = CLIP(b_l);
494
495#define STORE_PIXEL_RGBA8888 \
496 *data++ = CLIP(r_l); \
497 *data++ = CLIP(g_l); \
498 *data++ = CLIP(b_l); \
499 *data++ = 0;
500
501#define STORE_PIXEL_RGBA16161616 \
502 *data_s++ = CLIP(r_l); \
503 *data_s++ = CLIP(g_l); \
504 *data_s++ = CLIP(b_l); \
505 *data_s++ = 0;
506
507
508
509/* Only good for YUV 4:2:0 */
510int mpeg3video_ditherframe(mpeg3video_t *video, unsigned char **src, unsigned char **output_rows)
511{
512 int h = 0;
513 register unsigned char *y_in, *cb_in, *cr_in;
514 long y_l, r_l, b_l, g_l;
515 register unsigned char *data;
516 register int uv_subscript, step, w = -1;
517
518#ifdef HAVE_MMX
519/* =================================== MMX ===================================== */
520 if(video->have_mmx &&
521 video->out_w == video->horizontal_size &&
522 video->out_h == video->vertical_size &&
523 video->in_w == video->out_w &&
524 video->in_h == video->out_h &&
525 video->in_x == 0 &&
526 video->in_y == 0 &&
527 (video->color_model == MPEG3_RGB565 || video->color_model == MPEG3_601_RGB565))
528 {
529/* Unscaled 16 bit */
530 mpeg3video_rgb16_mmx(src[0],
531 src[2],
532 src[1],
533 output_rows[0],
534 video->out_h,
535 video->out_w,
536 (output_rows[1] - output_rows[0]) / 2 - video->out_w);
537 }
538 else
539 if(video->have_mmx &&
540 (video->color_model == MPEG3_BGRA8888 ||
541 video->color_model == MPEG3_BGR888 ||
542 /* video->color_model == MPEG3_RGB888 || */
543 video->color_model == MPEG3_RGBA8888 ||
544 video->color_model == MPEG3_601_BGR888 ||
545 video->color_model == MPEG3_601_BGRA8888 ||
546 video->color_model == MPEG3_601_RGB888 ||
547 video->color_model == MPEG3_601_RGBA8888))
548 {
549/* Original MMX */
550 if(video->color_model == MPEG3_BGRA8888 ||
551 video->color_model == MPEG3_RGBA8888 ||
552 video->color_model == MPEG3_601_BGRA8888 ||
553 video->color_model == MPEG3_601_RGBA8888) step = 4;
554 else
555 if(video->color_model == MPEG3_BGR888 ||
556 video->color_model == MPEG3_RGB888 ||
557 video->color_model == MPEG3_601_BGR888 ||
558 video->color_model == MPEG3_601_RGB888) step = 3;
559
560 DITHER_ROW_HEAD
561/* Transfer row with scaling */
562 if(video->out_w != video->horizontal_size)
563 {
564 switch(video->color_model)
565 {
566 case MPEG3_BGRA8888:
567 case MPEG3_BGR888:
568 DITHER_MMX_SCALE_HEAD
569 mpeg3_bgra32_mmx(y_in[video->x_table[w]],
570 cr_in[uv_subscript],
571 cb_in[uv_subscript],
572 (unsigned long*)data);
573 DITHER_MMX_SCALE_TAIL
574 break;
575
576 case MPEG3_601_BGRA8888:
577 case MPEG3_601_BGR888:
578 DITHER_MMX_SCALE_HEAD
579 mpeg3_601_bgra32_mmx(y_in[video->x_table[w]],
580 cr_in[uv_subscript],
581 cb_in[uv_subscript],
582 (unsigned long*)data);
583 DITHER_MMX_SCALE_TAIL
584 break;
585
586 case MPEG3_RGBA8888:
587 case MPEG3_RGB888:
588 DITHER_MMX_SCALE_HEAD
589 mpeg3_rgba32_mmx(y_in[video->x_table[w]],
590 cr_in[uv_subscript],
591 cb_in[uv_subscript],
592 (unsigned long*)data);
593 DITHER_MMX_SCALE_TAIL
594 break;
595
596 case MPEG3_601_RGBA8888:
597 case MPEG3_601_RGB888:
598 DITHER_MMX_SCALE_HEAD
599 mpeg3_601_rgba32_mmx(y_in[video->x_table[w]],
600 cr_in[uv_subscript],
601 cb_in[uv_subscript],
602 (unsigned long*)data);
603 DITHER_MMX_SCALE_TAIL
604 break;
605 }
606 }
607 else
608/* Transfer row unscaled */
609 {
610 switch(video->color_model)
611 {
612/* MMX byte swap 24 and 32 bit */
613 case MPEG3_BGRA8888:
614 case MPEG3_BGR888:
615 DITHER_MMX_HEAD
616 mpeg3_bgra32_mmx(*y_in++,
617 *cr_in,
618 *cb_in,
619 (unsigned long*)data);
620 data += step;
621 mpeg3_bgra32_mmx(*y_in++,
622 *cr_in,
623 *cb_in,
624 (unsigned long*)data);
625 DITHER_MMX_TAIL
626 break;
627
628/* MMX 601 byte swap 24 and 32 bit */
629 case MPEG3_601_BGRA8888:
630 case MPEG3_601_BGR888:
631 DITHER_MMX_HEAD
632 mpeg3_601_bgra32_mmx(*y_in++,
633 *cr_in,
634 *cb_in,
635 (unsigned long*)data);
636 data += step;
637 mpeg3_601_bgra32_mmx(*y_in++,
638 *cr_in,
639 *cb_in,
640 (unsigned long*)data);
641 DITHER_MMX_TAIL
642 break;
643
644/* MMX 24 and 32 bit no byte swap */
645 case MPEG3_RGBA8888:
646 case MPEG3_RGB888:
647 DITHER_MMX_HEAD
648 mpeg3_rgba32_mmx(*y_in++,
649 *cr_in,
650 *cb_in,
651 (unsigned long*)data);
652 data += step;
653 mpeg3_rgba32_mmx(*y_in++,
654 *cr_in,
655 *cb_in,
656 (unsigned long*)data);
657 DITHER_MMX_TAIL
658 break;
659
660/* MMX 601 24 and 32 bit no byte swap */
661 case MPEG3_601_RGBA8888:
662 case MPEG3_601_RGB888:
663 DITHER_MMX_HEAD
664 mpeg3_601_rgba32_mmx(*y_in++,
665 *cr_in,
666 *cb_in,
667 (unsigned long*)data);
668 data += step;
669 mpeg3_601_rgba32_mmx(*y_in++,
670 *cr_in,
671 *cb_in,
672 (unsigned long*)data);
673 DITHER_MMX_TAIL
674 break;
675 }
676 }
677 DITHER_ROW_TAIL
678 }
679 else
680#endif
681/* ================================== NO MMX ==================================== */
682 {
683 DITHER_ROW_HEAD
684/* Transfer row with scaling */
685 if(video->out_w != video->horizontal_size)
686 {
687 switch(video->color_model)
688 {
689 case MPEG3_BGR888:
690 DITHER_SCALE_HEAD
691 STORE_PIXEL_BGR888
692 DITHER_SCALE_TAIL
693 break;
694 case MPEG3_BGRA8888:
695 DITHER_SCALE_HEAD
696 STORE_PIXEL_BGRA8888
697 DITHER_SCALE_TAIL
698 break;
699 case MPEG3_RGB565:
700 DITHER_SCALE_HEAD
701 STORE_PIXEL_RGB565
702 DITHER_SCALE_TAIL
703 break;
704 case MPEG3_RGB888:
705 DITHER_SCALE_HEAD
706 STORE_PIXEL_RGB888
707 DITHER_SCALE_TAIL
708 break;
709 case MPEG3_RGBA8888:
710 DITHER_SCALE_HEAD
711 STORE_PIXEL_RGBA8888
712 DITHER_SCALE_TAIL
713 break;
714 case MPEG3_601_BGR888:
715 DITHER_SCALE_601_HEAD
716 STORE_PIXEL_BGR888
717 DITHER_SCALE_TAIL
718 break;
719 case MPEG3_601_BGRA8888:
720 DITHER_SCALE_601_HEAD
721 STORE_PIXEL_BGRA8888
722 DITHER_SCALE_TAIL
723 break;
724 case MPEG3_601_RGB565:
725 DITHER_SCALE_601_HEAD
726 STORE_PIXEL_RGB565
727 DITHER_SCALE_TAIL
728 break;
729 case MPEG3_601_RGB888:
730 DITHER_SCALE_601_HEAD
731 STORE_PIXEL_RGB888
732 DITHER_SCALE_TAIL
733 break;
734 case MPEG3_601_RGBA8888:
735 DITHER_SCALE_601_HEAD
736 STORE_PIXEL_RGBA8888
737 DITHER_SCALE_TAIL
738 break;
739 case MPEG3_RGBA16161616:
740 {
741 register unsigned short *data_s = (unsigned short*)data;
742 DITHER_SCALE_HEAD
743 STORE_PIXEL_RGBA16161616
744 DITHER_SCALE_TAIL
745 }
746 break;
747 }
748 }
749 else
750 {
751/* Transfer row unscaled */
752 switch(video->color_model)
753 {
754 case MPEG3_BGR888:
755 DITHER_HEAD
756 STORE_PIXEL_BGR888
757 DITHER_TAIL
758 break;
759 case MPEG3_BGRA8888:
760 DITHER_HEAD
761 STORE_PIXEL_BGRA8888
762 DITHER_TAIL
763 break;
764 case MPEG3_RGB565:
765 DITHER_HEAD
766 STORE_PIXEL_RGB565
767 DITHER_TAIL
768 break;
769 case MPEG3_RGB888:
770 DITHER_HEAD
771 STORE_PIXEL_RGB888
772 DITHER_TAIL
773 break;
774 case MPEG3_RGBA8888:
775 DITHER_HEAD
776 STORE_PIXEL_RGBA8888
777 DITHER_TAIL
778 break;
779 case MPEG3_601_BGR888:
780 DITHER_601_HEAD
781 STORE_PIXEL_BGR888
782 DITHER_TAIL
783 break;
784 case MPEG3_601_BGRA8888:
785 DITHER_601_HEAD
786 STORE_PIXEL_RGB565
787 DITHER_TAIL
788 break;
789 case MPEG3_601_RGB565:
790 DITHER_601_HEAD
791 STORE_PIXEL_RGB565
792 DITHER_TAIL
793 break;
794 case MPEG3_601_RGB888:
795 DITHER_601_HEAD
796 STORE_PIXEL_RGB888
797 DITHER_TAIL
798 break;
799 case MPEG3_601_RGBA8888:
800 DITHER_601_HEAD
801 STORE_PIXEL_RGBA8888
802 DITHER_TAIL
803 break;
804 case MPEG3_RGBA16161616:
805 {
806 register unsigned short *data_s = (unsigned short*)data;
807 DITHER_HEAD
808 STORE_PIXEL_RGBA16161616
809 DITHER_TAIL
810 }
811 break;
812 }
813 }
814 DITHER_ROW_TAIL
815 } /* End of non-MMX */
816
817#ifdef HAVE_MMX
818 if(video->have_mmx)
819 __asm__ __volatile__ ("emms");
820#endif
821 return 0;
822}
823
824int mpeg3video_ditherframe444(mpeg3video_t *video, unsigned char *src[])
825{
826 return 0;
827}
828
829int mpeg3video_dithertop(mpeg3video_t *video, unsigned char *src[])
830{
831 return mpeg3video_ditherframe(video, src, video->output_rows);
832}
833
834int mpeg3video_dithertop444(mpeg3video_t *video, unsigned char *src[])
835{
836 return 0;
837}
838
839int mpeg3video_ditherbot(mpeg3video_t *video, unsigned char *src[])
840{
841 return 0;
842}
843
844int mpeg3video_ditherbot444(mpeg3video_t *video, unsigned char *src[])
845{
846 return 0;
847}
848
849void memcpy_fast(unsigned char *output, unsigned char *input, long len)
850{
851 int i, len2;
852/* 8 byte alignment */
853/*
854 * if(!((long)input & 0x7))
855 * {
856 * len2 = len >> 4;
857 * for(i = 0; i < len2; )
858 * {
859 * ((MPEG3_INT64*)output)[i] = ((MPEG3_INT64*)input)[i];
860 * i++;
861 * ((MPEG3_INT64*)output)[i] = ((MPEG3_INT64*)input)[i];
862 * i++;
863 * }
864 *
865 * for(i *= 16; i < len; i++)
866 * {
867 * output[i] = input[i];
868 * }
869 * }
870 * else
871 */
872 memcpy(output, input, len);
873}
874
875int mpeg3video_init_output()
876{
877 int i, value;
878 for(i = 0; i < 256; i++)
879 {
880 value = (int)(1.1644 * i - 255 * 0.0627 + 0.5);
881 if(value < 0) value = 0;
882 else
883 if(value > 255) value = 255;
884 mpeg3_601_to_rgb[i] = value;
885 }
886 return 0;
887}
888
889int mpeg3video_present_frame(mpeg3video_t *video)
890{
891 int i, j, k, l;
892 unsigned char **src = video->output_src;
893
894/* Copy YUV buffers */
895 if(video->want_yvu)
896 {
897 long size[2];
898 long offset[2];
899
900/* Drop a frame */
901 if(!video->y_output) return 0;
902
903/* Copy a frame */
904 if(video->in_x == 0 &&
905 video->in_w >= video->coded_picture_width)
906 {
907 size[0] = video->coded_picture_width * video->in_h;
908 size[1] = video->chrom_width * (int)((float)video->in_h / 2 + 0.5);
909 offset[0] = video->coded_picture_width * video->in_y;
910 offset[1] = video->chrom_width * (int)((float)video->in_y / 2 + 0.5);
911
912/*
913 * if(video->in_y > 0)
914 * {
915 * offset[1] += video->chrom_width / 2;
916 * size[1] += video->chrom_width / 2;
917 * }
918 */
919
920 memcpy(video->y_output, src[0] + offset[0], size[0]);
921 memcpy(video->u_output, src[1] + offset[1], size[1]);
922 memcpy(video->v_output, src[2] + offset[1], size[1]);
923 }
924 else
925 {
926 for(i = 0, j = video->in_y; i < video->in_h; i++, j++)
927 {
928 memcpy(video->y_output + i * video->in_w,
929 src[0] + j * video->coded_picture_width + video->in_x,
930 video->in_w);
931 memcpy(video->u_output + i * video->in_w / 4,
932 src[1] + j * video->chrom_width / 2 + video->in_x / 4,
933 video->in_w / 4);
934 memcpy(video->v_output + i * video->in_w / 4,
935 src[2] + j * video->chrom_width / 2 + video->in_x / 4,
936 video->in_w / 4);
937 }
938 }
939
940 return 0;
941 }
942
943/* Want RGB buffer */
944/* Copy the frame to the output with YUV to RGB conversion */
945 if(video->prog_seq)
946 {
947 if(video->chroma_format != CHROMA444)
948 {
949 mpeg3video_ditherframe(video, src, video->output_rows);
950 }
951 else
952 mpeg3video_ditherframe444(video, src);
953 }
954 else
955 {
956 if((video->pict_struct == FRAME_PICTURE && video->topfirst) ||
957 video->pict_struct == BOTTOM_FIELD)
958 {
959/* top field first */
960 if(video->chroma_format != CHROMA444)
961 {
962 mpeg3video_dithertop(video, src);
963 mpeg3video_ditherbot(video, src);
964 }
965 else
966 {
967 mpeg3video_dithertop444(video, src);
968 mpeg3video_ditherbot444(video, src);
969 }
970 }
971 else
972 {
973/* bottom field first */
974 if(video->chroma_format != CHROMA444)
975 {
976 mpeg3video_ditherbot(video, src);
977 mpeg3video_dithertop(video, src);
978 }
979 else
980 {
981 mpeg3video_ditherbot444(video, src);
982 mpeg3video_dithertop444(video, src);
983 }
984 }
985 }
986 return 0;
987}
988
989int mpeg3video_display_second_field(mpeg3video_t *video)
990{
991/* Not used */
992 return 0;
993}
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 @@
1 ADD_1: dd 01010101h, 01010101h
2 MASK_AND:dd 7f7f7f7fh, 7f7f7f7fh
3 PLUS_384:dd 01800180h, 01800180h
4 PLUS_128:dd 00800080h, 00800080h
5
6%assign LocalFrameSize 0
7%assign RegisterStorageSize 16
8
9; Arguments:
10%assign source LocalFrameSize + RegisterStorageSize + 4
11%assign dest LocalFrameSize + RegisterStorageSize + 8
12%assign lx2 LocalFrameSize + RegisterStorageSize + 12
13%assign h LocalFrameSize + RegisterStorageSize + 16
14
15; Locals (on local stack frame)
16
17
18; extern void C rec_mmx (
19; unsigned char *source,
20; unsigned char *dest,
21; int lx2,
22; int h
23;
24; The local variables are on the stack,
25;
26
27global recva_mmx
28global recvac_mmx
29global rech_mmx
30global rechc_mmx
31global add_block_mmx
32global set_block_mmx
33
34
35 align 16
36rech_mmx:
37 push esi
38 push edi
39 push ecx
40 push ebx
41 mov esi, [esp+source]
42 mov edi, [esp+dest]
43 mov ecx, [esp+h]
44 mov ebx, [esp+lx2]
45 movq mm5, [MASK_AND]
46 movq mm6, [ADD_1]
47.rech1:
48 movq mm0,[esi]
49 movq mm1,[esi+1]
50 movq mm2,[esi+8]
51 movq mm3,[esi+9]
52 psrlw mm0,1
53 psrlw mm1,1
54 psrlw mm2,1
55 psrlw mm3,1
56 pand mm0,mm5
57 pand mm1,mm5
58 pand mm2,mm5
59 pand mm3,mm5
60 paddusb mm0,mm1
61 paddusb mm2,mm3
62 paddusb mm0,mm6
63 paddusb mm2,mm6
64 movq [edi],mm0
65 add esi,ebx
66 movq [edi+8],mm2
67 add edi,ebx
68 dec ecx
69 jnz .rech1
70 emms
71 pop ebx
72 pop ecx
73 pop edi
74 pop esi
75 ret
76
77 align 16
78rechc_mmx:
79 push esi
80 push edi
81 push ecx
82 push ebx
83; sub esp, LocalFrameSize
84 mov esi, [esp+source]
85 mov edi, [esp+dest]
86 mov ecx, [esp+h]
87 mov ebx, [esp+lx2]
88 movq mm5, [MASK_AND]
89 movq mm6, [ADD_1]
90.rechc1:
91 movq mm0,[esi]
92 movq mm1,[esi+1]
93 psrlw mm0,1
94 psrlw mm1,1
95 pand mm0,mm5
96 pand mm1,mm5
97 paddusb mm0,mm1
98 paddusb mm0,mm6
99 movq [edi],mm0
100 add edi,ebx
101 add esi,ebx
102 dec ecx
103 jnz .rechc1
104 emms
105; add esp, LocalFrameSize
106 pop ebx
107 pop ecx
108 pop edi
109 pop esi
110 ret
111
112
113
114%assign RegisterStorageSize 20
115%assign source LocalFrameSize + RegisterStorageSize + 4
116%assign dest LocalFrameSize + RegisterStorageSize + 8
117%assign lx LocalFrameSize + RegisterStorageSize + 12
118%assign lx2 LocalFrameSize + RegisterStorageSize + 16
119%assign h LocalFrameSize + RegisterStorageSize + 20
120
121 align 16
122recva_mmx:
123 push esi
124 push edi
125 push ecx
126 push ebx
127 push edx
128 mov esi, [esp+source]
129 mov edi, [esp+dest]
130 mov ecx, [esp+h]
131 mov ebx, [esp+lx2]
132 mov edx, [esp+lx]
133 movq mm7, [MASK_AND]
134 movq mm6, [ADD_1]
135.recva1:
136 movq mm0,[esi]
137 movq mm1,[esi+edx]
138 movq mm2,[esi+8]
139 movq mm3,[esi+edx+8]
140 movq mm4,[edi]
141 movq mm5,[edi+8]
142 psrlw mm0,1
143 psrlw mm1,1
144 psrlw mm2,1
145 psrlw mm3,1
146 psrlw mm4,1
147 psrlw mm5,1
148 pand mm0,mm7
149 pand mm1,mm7
150 pand mm2,mm7
151 pand mm3,mm7
152 pand mm4,mm7
153 pand mm5,mm7
154 paddusb mm0,mm1
155 paddusb mm2,mm3
156 paddusb mm0,mm6
157 paddusb mm2,mm6
158 psrlw mm0,1
159 psrlw mm2,1
160 pand mm0,mm7
161 pand mm2,mm7
162 paddusb mm4,mm0
163 paddusb mm5,mm2
164 paddusb mm4,mm6
165 paddusb mm5,mm6
166 movq [edi],mm4
167 movq [edi+8],mm5
168 add edi,ebx
169 add esi,ebx
170 dec ecx
171 jnz near .recva1
172 emms
173 pop edx
174 pop ebx
175 pop ecx
176 pop edi
177 pop esi
178 ret
179
180 align 16
181recvac_mmx:
182 push esi
183 push edi
184 push ecx
185 push ebx
186 push edx
187 mov esi, [esp+source]
188 mov edi, [esp+dest]
189 mov ecx, [esp+h]
190 mov ebx, [esp+lx2]
191 mov edx, [esp+lx]
192 movq mm5, [MASK_AND]
193 movq mm6, [ADD_1]
194.recvac1:
195 movq mm0,[esi]
196 movq mm1,[esi+edx]
197 movq mm4,[edi]
198 psrlw mm0,1
199 psrlw mm1,1
200 psrlw mm4,1
201 pand mm0,mm5
202 pand mm1,mm5
203 pand mm4,mm5
204 paddusb mm0,mm1
205 paddusb mm0,mm6
206 psrlw mm0,1
207 pand mm0,mm5
208 paddusb mm4,mm0
209 paddusb mm4,mm6
210 movq [edi],mm4
211 add edi,ebx
212 add esi,ebx
213 dec ecx
214 jnz .recvac1
215 emms
216 pop edx
217 pop ebx
218 pop ecx
219 pop edi
220 pop esi
221 ret
222
223%assign RegisterStorageSize 20
224%assign rfp LocalFrameSize + RegisterStorageSize + 4
225%assign bp LocalFrameSize + RegisterStorageSize + 8
226%assign iincr LocalFrameSize + RegisterStorageSize + 12
227
228; FIXME clipping needs to be done
229
230 align 16
231add_block_mmx:
232 push esi
233 push edi
234 push ecx
235 push ebx
236 push edx
237 mov esi, [esp+bp]
238 mov edi, [esp+rfp]
239 mov ebx, [esp+iincr]
240; movq mm7, [PLUS_384]
241 mov ecx,8
242 pxor mm2,mm2 ; clear
243%rep 8
244 movq mm0, [edi] ; get dest
245 movq mm1,mm0
246 punpcklbw mm0,mm2
247 punpckhbw mm1,mm2
248 paddsw mm0, [esi]
249 paddsw mm1, [esi+8]
250; paddsw mm0, mm7
251; paddsw mm1, mm7
252 packuswb mm0,mm1
253 movq [edi], mm0
254 add edi,ebx
255 add esi,16
256%endrep
257 emms
258 pop edx
259 pop ebx
260 pop ecx
261 pop edi
262 pop esi
263 ret
264
265 align 16
266set_block_mmx:
267 push esi
268 push edi
269 push ecx
270 push ebx
271 push edx
272 mov esi, [esp+bp]
273 mov edi, [esp+rfp]
274 mov ebx, [esp+iincr]
275 movq mm7, [PLUS_128]
276%rep 4
277 movq mm0, [esi]
278 movq mm1, [esi+8]
279 paddsw mm0, mm7
280 movq mm2, [esi+16]
281 paddsw mm1, mm7
282 movq mm3, [esi+24]
283 paddsw mm2, mm7
284 packuswb mm0, mm1
285 paddsw mm3, mm7
286 movq [edi], mm0
287 packuswb mm2, mm3
288 add edi, ebx
289 add esi, 32
290 movq [edi], mm2
291 add edi, ebx
292%endrep
293 emms
294 pop edx
295 pop ebx
296 pop ecx
297 pop edi
298 pop esi
299 ret
300
301
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 @@
1#include "../libmpeg3.h"
2#include "../mpeg3protos.h"
3#include "mpeg3video.h"
4#include <stdio.h>
5
6#ifdef HAVE_MMX
7
8#ifdef HAVE_3Dnow
9static inline void recva_mmx(unsigned char *s, unsigned char *d, int lx, int lx2, int h)
10{
11 __asm__(
12 ".align8\n"
13 "1:"
14 "movq (%1),%%mm0\n" /* 8 s */
15 "movq 8(%1),%%mm1\n" /* 8 s */
16 "movq (%4),%%mm2\n" /* 8 s +lx */
17 "movq 8(%4),%%mm3\n" /* 8 s +lx **/
18
19 "pavgusb %%mm2, %%mm0\n"
20 "addl %3, %1\n"
21 "pavgusb %%mm3, %%mm1\n"
22
23 "movq (%2),%%mm2\n" /* 8 d */
24 "movq 8(%2),%%mm3\n" /* 8 d */
25 "pavgusb %%mm2, %%mm0\n"
26 "addl %3, %4\n"
27 "pavgusb %%mm3, %%mm1\n"
28
29 "movq %%mm0,(%2)\n"
30 "movq %%mm1,8(%2)\n"
31 "addl %3, %2\n"
32 "loop 1b\n"
33 :
34 : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx)
35 );
36}
37
38static inline void recvac_mmx(unsigned char *s, unsigned char *d, int lx,int lx2, int h)
39{
40 __asm__(
41 ".align8\n"
42 "1:"
43 "movq (%1),%%mm0\n" /* 8 s */
44 "movq (%4),%%mm2\n" /* 8 s +lx */
45 "addl %3, %1\n"
46 "pavgusb %%mm2, %%mm0\n"
47 "movq (%2),%%mm3\n" /* 8 d */
48 "addl %3, %4\n"
49 "pavgusb %%mm3, %%mm0\n"
50 "movq %%mm0,(%2)\n"
51 "addl %3, %2\n"
52 "loop 1b\n"
53 :
54 : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx)
55 );
56}
57
58static inline void rech_mmx(unsigned char *s, unsigned char *d, int lx2, int h)
59{
60 __asm__ (
61 ".align8\n"
62 "1:"
63 "movq (%1),%%mm0\n" /* 8 s */
64 "movq 8(%1),%%mm1\n" /* 8 s */
65 "movq 1(%1),%%mm2\n" /* 8 s */
66 "movq 9(%1),%%mm3\n" /* 8 s */
67
68 "pavgusb %%mm2, %%mm0\n"
69 "addl %3, %1\n"
70 "pavgusb %%mm3, %%mm1\n"
71
72 "movq %%mm0,(%2)\n"
73 "movq %%mm1,8(%2)\n"
74 "addl %3, %2\n"
75 "loop 1b\n"
76 :
77 : "c" (h), "r" (s), "r" (d), "r" (lx2)
78 );
79}
80
81static inline void rechc_mmx(unsigned char *s, unsigned char *d, int lx2, int h)
82{
83 __asm__ (
84 ".align8\n"
85 "1:"
86 "movq (%1),%%mm0\n" /* 8 s */
87 "movq 1(%1),%%mm2\n" /* 8 s +1 */
88 "addl %3, %1\n"
89 "pavgusb %%mm2, %%mm0\n"
90 "movq %%mm0,(%2)\n"
91 "addl %3, %2\n"
92 "loop 1b\n"
93 :
94 : "c" (h), "r" (s), "r" (d), "r" (lx2)
95 );
96}
97
98static inline void recha_mmx(unsigned char *s, unsigned char *d,int lx2, int h)
99{
100 __asm__ (
101 ".align8\n"
102 "1:"
103 "movq (%1),%%mm0\n" /* 8 s */
104 "movq 8(%1),%%mm1\n" /* 8 s */
105 "movq 1(%1),%%mm2\n" /* 8 s */
106 "movq 9(%1),%%mm3\n" /* 8 s */
107
108 "pavgusb %%mm2, %%mm0\n"
109 "addl %3, %1\n"
110 "pavgusb %%mm3, %%mm1\n"
111
112 "movq (%2),%%mm2\n" /* 8 d */
113 "movq 8(%2),%%mm3\n" /* 8 d */
114 "pavgusb %%mm2, %%mm0\n"
115 "pavgusb %%mm3, %%mm1\n"
116
117 "movq %%mm0,(%2)\n"
118 "movq %%mm1,8(%2)\n"
119 "addl %3, %2\n"
120 "loop 1b\n"
121 :
122 : "c" (h), "r" (s), "r" (d), "r" (lx2)
123 );
124}
125
126static inline void rechac_mmx(unsigned char *s,unsigned char *d, int lx2, int h)
127{
128 __asm__ (
129 ".align8\n"
130 "1:"
131 "movq (%1),%%mm0\n" /* 8 s */
132 "movq 1(%1),%%mm2\n" /* 8 s */
133
134 "addl %3, %1\n"
135 "pavgusb %%mm2, %%mm0\n"
136
137 "movq (%2),%%mm1\n" /* 8 d */
138 "pavgusb %%mm1, %%mm0\n"
139
140 "movq %%mm0,(%2)\n"
141 "addl %3, %2\n"
142 "loop 1b\n"
143 :
144 : "c" (h), "r" (s), "r" (d), "r" (lx2)
145 );
146}
147
148static inline void rec4_mmx(unsigned char *s, unsigned char *d, int lx, int lx2, int h)
149{
150 __asm__ __volatile__(
151 "movq (%1),%%mm0\n" /* 8 s */
152 "movq 8(%1),%%mm1\n" /* 8 s */
153 "movq 1(%1),%%mm2\n" /* 8 s +1*/
154 "movq 9(%1),%%mm3\n" /* 8 s +1*/
155 ".align 8\n"
156 "1:"
157 "movq (%4),%%mm4\n" /* 8 s+lx */
158 "pavgusb %%mm2, %%mm0\n"
159 "movq 8(%4),%%mm5\n" /* 8 s+lx */
160 "pavgusb %%mm3, %%mm1\n"
161
162 "movq 1(%4),%%mm6\n" /* 8 s+lx +1*/
163 "pavgusb %%mm4, %%mm0\n"
164 "movq 9(%4),%%mm7\n" /* 8 s+lx +1*/
165 "pavgusb %%mm5, %%mm1\n"
166
167 "pavgusb %%mm6, %%mm0\n"
168 "addl %3, %4\n"
169 "pavgusb %%mm7, %%mm1\n"
170 "movq %%mm0,(%2)\n"
171 "movq %%mm6,%%mm2\n"
172 "movq %%mm7,%%mm3\n"
173 "movq %%mm1,8(%2)\n"
174 "movq %%mm4,%%mm0\n"
175 "movq %%mm5,%%mm1\n"
176 "addl %3, %2\n"
177 "loop 1b\n"
178 :
179 : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx)
180 );
181}
182
183static inline void rec4c_mmx(unsigned char *s, unsigned char *d, int lx, int lx2, int h)
184{
185 __asm__ __volatile__(
186 "movq (%1),%%mm0\n" /* 8 s */
187 "movq 1(%1),%%mm2\n" /* 8 s +1*/
188 ".align 8\n"
189 "1:"
190 "movq (%4),%%mm4\n" /* 8 s+lx */
191 "pavgusb %%mm2, %%mm0\n"
192
193 "movq 1(%4),%%mm6\n" /* 8 s+lx +1*/
194 "pavgusb %%mm4, %%mm0\n"
195
196 "addl %3, %4\n"
197 "pavgusb %%mm6, %%mm0\n"
198 "movq %%mm0,(%2)\n"
199 "movq %%mm6,%%mm2\n"
200 "movq %%mm4,%%mm0\n"
201 "addl %3, %2\n"
202 "loop 1b\n"
203 :
204 : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx)
205 );
206}
207
208static inline void rec4a_mmx(unsigned char *s, unsigned char *d, int lx, int lx2, int h)
209{
210 __asm__ __volatile__(
211 "movq (%1),%%mm0\n" /* 8 s */
212 "movq 8(%1),%%mm1\n" /* 8 s */
213 "movq 1(%1),%%mm2\n" /* 8 s +1*/
214 "movq 9(%1),%%mm3\n" /* 8 s +1*/
215 ".align 8\n"
216 "1:"
217 "movq (%4),%%mm4\n" /* 8 s+lx */
218 "pavgusb %%mm2, %%mm0\n"
219 "movq 8(%4),%%mm5\n" /* 8 s+lx */
220 "pavgusb %%mm3, %%mm1\n"
221
222 "movq 1(%4),%%mm6\n" /* 8 s+lx +1*/
223 "pavgusb %%mm4, %%mm0\n"
224 "movq 9(%4),%%mm7\n" /* 8 s+lx +1*/
225 "pavgusb %%mm5, %%mm1\n"
226 "movq (%2),%%mm2\n"
227 "pavgusb %%mm6, %%mm0\n"
228 "movq 8(%2),%%mm3\n"
229
230 "pavgusb %%mm2, %%mm0\n"
231 "addl %3, %4\n"
232 "pavgusb %%mm3, %%mm1\n"
233 "movq %%mm0,(%2)\n"
234
235 "pavgusb %%mm7, %%mm1\n"
236 "movq %%mm6,%%mm2\n"
237 "movq %%mm7,%%mm3\n"
238 "movq %%mm1,8(%2)\n"
239 "movq %%mm4,%%mm0\n"
240 "movq %%mm5,%%mm1\n"
241 "addl %3, %2\n"
242 "loop 1b\n"
243 :
244 : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx)
245 );
246}
247
248static inline void rec4ac_mmx(unsigned char *s, unsigned char *d, int lx, int lx2, int h)
249{
250 __asm__ __volatile__(
251 "movq (%1),%%mm0\n" /* 8 s */
252 "movq 1(%1),%%mm2\n" /* 8 s +1*/
253 ".align 8\n"
254 "1:"
255 "movq (%4),%%mm4\n" /* 8 s+lx */
256 "pavgusb %%mm2, %%mm0\n"
257
258 "movq 1(%4),%%mm6\n" /* 8 s+lx +1*/
259 "pavgusb %%mm4, %%mm0\n"
260 "movq (%2),%%mm1\n" /* 8 d */
261 "pavgusb %%mm6, %%mm0\n"
262 "addl %3, %4\n"
263 "pavgusb %%mm1, %%mm0\n"
264 "movq %%mm6,%%mm2\n"
265 "movq %%mm0,(%2)\n"
266 "movq %%mm4,%%mm0\n"
267 "addl %3, %2\n"
268 "loop 1b\n"
269 :
270 : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx)
271 );
272}
273
274#else // HAVE_3DNOW
275 static LONGLONG ADD_1 =0x0101010101010101LL;
276 static LONGLONG MASK_AND = 0x7f7f7f7f7f7f7f7fLL;
277#endif
278
279static inline void rec_mmx(unsigned char *s, unsigned char *d, int lx2, int h)
280{
281 __asm__ __volatile__(
282 ".align 8\n"
283 "1:\t"
284 "movq ( %1 ), %%mm0\n" /* 8 s */
285 "movq 8( %1 ), %%mm2\n" /* 16 s */
286 "movq %%mm0, ( %2 )\n"
287 "addl %3, %1\n"
288 "movq %%mm2, 8( %2 )\n"
289 "decl %0\n"
290 "leal (%2, %3), %2\n"
291 "jnz 1b"
292 :
293 : "c" (h), "r" (s), "r" (d), "r" (lx2)
294 );
295}
296
297
298static inline void recc_mmx(unsigned char *s, unsigned char *d, int lx2, int h)
299{
300 __asm__ __volatile__(
301 ".align 8\n"
302 "1:\t"
303 "movq ( %1 ), %%mm0\n"
304 "addl %3, %1\n"
305 "movq %%mm0, ( %2 )\n"
306 "decl %0\n"
307 "leal (%2, %3), %2\n"
308 "jnz 1b"
309 :
310 : "c" (h), "r" (s), "r" (d), "r" (lx2)
311 );
312}
313
314
315static inline void reca_mmx(unsigned char *s, unsigned char *d, int lx2, int h)
316{
317#ifdef HAVE_3Dnow
318 __asm__ (
319 ".align8\n"
320 "1:"
321 "movq (%1),%%mm0\n" /* 8 s */
322 "movq (%2),%%mm2\n" /* 8 d */
323 "movq 8(%1),%%mm1\n" /* 8 s */
324 "movq 8(%2),%%mm3\n" /* 8 d */
325 "pavgusb %%mm2, %%mm0\n"
326 "addl %3, %1\n"
327 "pavgusb %%mm3, %%mm1\n"
328
329 "movq %%mm0,(%2)\n"
330 "movq %%mm1,8(%2)\n"
331 "addl %3, %2\n"
332 "loop 1b\n"
333 :
334 : "c" (h), "r" (s), "r" (d), "r" (lx2)
335 );
336#else /* No 3dnow */
337 __asm__ (
338 "movq MASK_AND, %%mm5\n"
339 "movq ADD_1, %%mm6\n"
340 "1:\t"
341 "movq (%1),%%mm0\n" /* Load 16 pixels from each row */
342 "movq (%2),%%mm1\n"
343 "movq 8(%1),%%mm2\n"
344 "movq 8(%2),%%mm3\n"
345 "psrlw $1,%%mm0\n" /* Shift pixels down */
346 "psrlw $1,%%mm1\n"
347 "pand %%mm5,%%mm0\n" /* Zero out significant bit */
348 "psrlw $1,%%mm2\n"
349 "pand %%mm5,%%mm1\n"
350 "psrlw $1,%%mm3\n"
351 "pand %%mm5,%%mm2\n"
352 "paddusb %%mm1,%%mm0\n" /* Add pixels */
353 "pand %%mm5,%%mm3\n"
354 "paddusb %%mm3,%%mm2\n"
355 "paddusb %%mm6,%%mm0\n" /* Add 1 to results */
356 "paddusb %%mm6,%%mm2\n"
357 "movq %%mm0,(%2)\n"
358 "addl %3,%1\n"
359 "movq %%mm2, 8(%2)\n"
360 "decl %0\n"
361 "leal (%2, %3), %2\n"
362 "jnz 1b\n"
363 :
364 : "c" (h), "r" (s), "r" (d), "r" (lx2)
365 );
366#endif
367}
368
369
370static inline void recac_mmx(unsigned char *s, unsigned char *d, int lx2, int h)
371{
372#ifdef HAVE_3Dnow
373 __asm__ (
374 ".align8\n"
375 "1:"
376 "movq (%1),%%mm0\n" /* 8 s */
377 "movq (%2),%%mm2\n" /* 8 d */
378 "pavgusb %%mm2, %%mm0\n"
379 "addl %3, %1\n"
380 "movq %%mm0,(%2)\n"
381 "addl %3, %2\n"
382 "loop 1b\n"
383 :
384 : "c" (h), "r" (s), "r" (d), "r" (lx2)
385 );
386#else /* No 3dnow */
387 __asm__ (
388 "movq MASK_AND, %%mm5\n"
389 "movq ADD_1, %%mm6\n"
390 "1:\t"
391 "movq (%1),%%mm0\n"
392 "movq (%2),%%mm1\n"
393 "psrlw $1,%%mm0\n"
394 "psrlw $1,%%mm1\n"
395 "pand %%mm5,%%mm0\n"
396 "pand %%mm5,%%mm1\n"
397 "paddusb %%mm1,%%mm0\n"
398 "paddusb %%mm6,%%mm0\n"
399 "addl %3,%1\n"
400 "movq %%mm0,(%2)\n"
401 "decl %0\n"
402 "leal (%2, %3), %2\n"
403 "jnz 1b\n"
404 :
405 : "c" (h), "r" (s), "r" (d), "r" (lx2)
406 );
407#endif
408}
409
410
411static inline void recv_mmx(unsigned char *s, unsigned char *d, int lx, int lx2, int h)
412{
413#ifdef HAVE_3Dnow
414 __asm__(
415 ".align8\n"
416 "1:"
417 "movq (%1),%%mm0\n" /* 8 s */
418 "movq (%4),%%mm2\n" /* 8 s +lx */
419 "movq 8(%1),%%mm1\n" /* 8 s */
420 "movq 8(%4),%%mm3\n" /* 8 s +lx **/
421
422 "pavgusb %%mm2, %%mm0\n"
423 "addl %3, %1\n"
424 "pavgusb %%mm3, %%mm1\n"
425
426 "movq %%mm0,(%2)\n"
427 "addl %3, %4\n"
428 "movq %%mm1,8(%2)\n"
429 "addl %3, %2\n"
430 "loop 1b\n"
431 :
432 : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx)
433 );
434#else
435 __asm__ (
436 "movq MASK_AND, %%mm5\n"
437 "movq ADD_1, %%mm6\n"
438 "1:\t"
439 "movq (%1),%%mm0\n" /* 8 s */
440 "movq (%4),%%mm1\n" /* 8 s +lx */
441 "movq 8(%1),%%mm2\n" /* 8 s */
442 "movq 8(%4),%%mm3\n" /* 8 s +lx **/
443 "psrlw $1,%%mm0\n"
444 "psrlw $1,%%mm1\n"
445 "pand %%mm5,%%mm0\n"
446 "psrlw $1,%%mm2\n"
447 "pand %%mm5,%%mm1\n"
448 "psrlw $1,%%mm3\n"
449 "pand %%mm5,%%mm2\n"
450 "paddusb %%mm1,%%mm0\n"
451 "pand %%mm5,%%mm3\n"
452 "paddusb %%mm3,%%mm2\n"
453 "paddusb %%mm6,%%mm0\n"
454 "paddusb %%mm6,%%mm2\n"
455 "movq %%mm0,(%2)\n"
456 "addl %3,%1\n"
457 "movq %%mm2, 8(%2)\n"
458 "addl %3,%4\n"
459 "decl %0\n"
460 "leal (%2, %3), %2\n"
461 "jnz 1b\n"
462 :
463 : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx)
464 );
465#endif
466}
467
468
469static inline void recvc_mmx(unsigned char *s, unsigned char *d, int lx, int lx2, int h)
470{
471#ifdef HAVE_3Dnow
472 __asm__(
473 ".align8\n"
474 "1:"
475 "movq (%1),%%mm0\n" /* 8 s */
476 "movq (%4),%%mm2\n" /* 8 s +lx */
477 "addl %3, %1\n"
478 "pavgusb %%mm2, %%mm0\n"
479 "addl %3, %4\n"
480 "movq %%mm0,(%2)\n"
481 "addl %3, %2\n"
482 "loop 1b\n"
483 :
484 : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx)
485 );
486#else
487 __asm__ (
488 "movq MASK_AND, %%mm5\n"
489 "movq ADD_1, %%mm6\n"
490 "1:\t"
491 "movq (%1),%%mm0\n" /* 8 s */
492 "movq (%4),%%mm1\n" /* 8 s +lx */
493 "psrlw $1,%%mm0\n"
494 "psrlw $1,%%mm1\n"
495 "pand %%mm5,%%mm0\n"
496 "pand %%mm5,%%mm1\n"
497 "paddusb %%mm1,%%mm0\n"
498 "addl %3,%1\n"
499 "paddusb %%mm6,%%mm0\n"
500 "addl %3,%4\n"
501 "movq %%mm0,(%2)\n"
502 "decl %0\n"
503 "leal (%2, %3), %2\n"
504 "jnz 1b\n"
505 :
506 : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx)
507 );
508#endif
509}
510
511#endif // HAVE_MMX
512
513static inline void rec(unsigned char *s, unsigned char *d, int lx2, int h)
514{
515 int j;
516 for(j = 0; j < h; j++, s += lx2, d += lx2)
517 {
518 d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; d[3] = s[3];
519 d[4] = s[4]; d[5] = s[5]; d[6] = s[6]; d[7] = s[7];
520 d[8] = s[8]; d[9] = s[9]; d[10] = s[10]; d[11] = s[11];
521 d[12] = s[12]; d[13] = s[13]; d[14] = s[14]; d[15] = s[15];
522 }
523}
524
525
526
527static inline void recc(unsigned char *s, unsigned char *d, int lx2, int h)
528{
529 int j;
530 for(j = 0; j < h; j++, s += lx2, d += lx2)
531 {
532 d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; d[3] = s[3];
533 d[4] = s[4]; d[5] = s[5]; d[6] = s[6]; d[7] = s[7];
534 }
535}
536
537static inline void reca(unsigned char *s, unsigned char *d, int lx2, int h)
538{
539 int j;
540 for(j = 0; j < h; j++, s +=lx2, d +=lx2)
541 {
542 d[0] = (unsigned int)(d[0] + s[0] + 1) >> 1;
543 d[1] = (unsigned int)(d[1] + s[1] + 1) >> 1;
544 d[2] = (unsigned int)(d[2] + s[2] + 1) >> 1;
545 d[3] = (unsigned int)(d[3] + s[3] + 1) >> 1;
546 d[4] = (unsigned int)(d[4] + s[4] + 1) >> 1;
547 d[5] = (unsigned int)(d[5] + s[5] + 1) >> 1;
548 d[6] = (unsigned int)(d[6] + s[6] + 1) >> 1;
549 d[7] = (unsigned int)(d[7] + s[7] + 1) >> 1;
550 d[8] = (unsigned int)(d[8] + s[8] + 1) >> 1;
551 d[9] = (unsigned int)(d[9] + s[9] + 1) >> 1;
552 d[10] = (unsigned int)(d[10] + s[10] + 1) >> 1;
553 d[11] = (unsigned int)(d[11] + s[11] + 1) >> 1;
554 d[12] = (unsigned int)(d[12] + s[12] + 1) >> 1;
555 d[13] = (unsigned int)(d[13] + s[13] + 1) >> 1;
556 d[14] = (unsigned int)(d[14] + s[14] + 1) >> 1;
557 d[15] = (unsigned int)(d[15] + s[15] + 1) >> 1;
558 }
559}
560
561static inline void recac(unsigned char *s, unsigned char *d, int lx2, int h)
562{
563 int j;
564 for(j = 0; j < h; j++, s += lx2, d += lx2)
565 {
566 d[0] = (unsigned int)(d[0] + s[0] + 1)>>1;
567 d[1] = (unsigned int)(d[1] + s[1] + 1)>>1;
568 d[2] = (unsigned int)(d[2] + s[2] + 1)>>1;
569 d[3] = (unsigned int)(d[3] + s[3] + 1)>>1;
570 d[4] = (unsigned int)(d[4] + s[4] + 1)>>1;
571 d[5] = (unsigned int)(d[5] + s[5] + 1)>>1;
572 d[6] = (unsigned int)(d[6] + s[6] + 1)>>1;
573 d[7] = (unsigned int)(d[7] + s[7] + 1)>>1;
574 }
575}
576
577static inline void recv_(unsigned char *s, unsigned char *d, int lx, int lx2, int h)
578{
579 unsigned char *dp,*sp,*sp2;
580 int j;
581 sp = s;
582 sp2 = s + lx;
583 dp = d;
584 for(j = 0; j < h; j++)
585 {
586 dp[0] = (unsigned int)(sp[0] + sp2[0] + 1) >> 1;
587 dp[1] = (unsigned int)(sp[1] + sp2[1] + 1) >> 1;
588 dp[2] = (unsigned int)(sp[2] + sp2[2] + 1) >> 1;
589 dp[3] = (unsigned int)(sp[3] + sp2[3] + 1) >> 1;
590 dp[4] = (unsigned int)(sp[4] + sp2[4] + 1) >> 1;
591 dp[5] = (unsigned int)(sp[5] + sp2[5] + 1) >> 1;
592 dp[6] = (unsigned int)(sp[6] + sp2[6] + 1) >> 1;
593 dp[7] = (unsigned int)(sp[7] + sp2[7] + 1) >> 1;
594 dp[8] = (unsigned int)(sp[8] + sp2[8] + 1) >> 1;
595 dp[9] = (unsigned int)(sp[9] + sp2[9] + 1) >> 1;
596 dp[10] = (unsigned int)(sp[10] + sp2[10] + 1) >> 1;
597 dp[11] = (unsigned int)(sp[11] + sp2[11] + 1) >> 1;
598 dp[12] = (unsigned int)(sp[12] + sp2[12] + 1) >> 1;
599 dp[13] = (unsigned int)(sp[13] + sp2[13] + 1) >> 1;
600 dp[14] = (unsigned int)(sp[14] + sp2[14] + 1) >> 1;
601 dp[15] = (unsigned int)(sp[15] + sp2[15] + 1) >> 1;
602 sp+= lx2;
603 sp2+= lx2;
604 dp+= lx2;
605 }
606}
607
608static inline void recvc(unsigned char *s, unsigned char *d, int lx, int lx2, int h)
609{
610 unsigned char *dp,*sp,*sp2;
611 int j;
612
613 sp = s;
614 sp2 = s+lx;
615 dp = d;
616 for(j = 0; j < h; j++)
617 {
618 dp[0] = (unsigned int)(sp[0]+sp2[0]+1)>>1;
619 dp[1] = (unsigned int)(sp[1]+sp2[1]+1)>>1;
620 dp[2] = (unsigned int)(sp[2]+sp2[2]+1)>>1;
621 dp[3] = (unsigned int)(sp[3]+sp2[3]+1)>>1;
622 dp[4] = (unsigned int)(sp[4]+sp2[4]+1)>>1;
623 dp[5] = (unsigned int)(sp[5]+sp2[5]+1)>>1;
624 dp[6] = (unsigned int)(sp[6]+sp2[6]+1)>>1;
625 dp[7] = (unsigned int)(sp[7]+sp2[7]+1)>>1;
626 sp+= lx2;
627 sp2+= lx2;
628 dp+= lx2;
629 }
630}
631
632
633static inline void recva(unsigned char *s, unsigned char *d, int lx, int lx2, int h)
634{
635 unsigned char *dp,*sp,*sp2;
636 int j;
637
638 sp = s;
639 sp2 = s+lx;
640 dp = d;
641 for (j=0; j<h; j++){
642 dp[0] = (dp[0] + ((unsigned int)(sp[0]+sp2[0]+1)>>1) + 1)>>1;
643 dp[1] = (dp[1] + ((unsigned int)(sp[1]+sp2[1]+1)>>1) + 1)>>1;
644 dp[2] = (dp[2] + ((unsigned int)(sp[2]+sp2[2]+1)>>1) + 1)>>1;
645 dp[3] = (dp[3] + ((unsigned int)(sp[3]+sp2[3]+1)>>1) + 1)>>1;
646 dp[4] = (dp[4] + ((unsigned int)(sp[4]+sp2[4]+1)>>1) + 1)>>1;
647 dp[5] = (dp[5] + ((unsigned int)(sp[5]+sp2[5]+1)>>1) + 1)>>1;
648 dp[6] = (dp[6] + ((unsigned int)(sp[6]+sp2[6]+1)>>1) + 1)>>1;
649 dp[7] = (dp[7] + ((unsigned int)(sp[7]+sp2[7]+1)>>1) + 1)>>1;
650 dp[8] = (dp[8] + ((unsigned int)(sp[8]+sp2[8]+1)>>1) + 1)>>1;
651 dp[9] = (dp[9] + ((unsigned int)(sp[9]+sp2[9]+1)>>1) + 1)>>1;
652 dp[10] = (dp[10] + ((unsigned int)(sp[10]+sp2[10]+1)>>1) + 1)>>1;
653 dp[11] = (dp[11] + ((unsigned int)(sp[11]+sp2[11]+1)>>1) + 1)>>1;
654 dp[12] = (dp[12] + ((unsigned int)(sp[12]+sp2[12]+1)>>1) + 1)>>1;
655 dp[13] = (dp[13] + ((unsigned int)(sp[13]+sp2[13]+1)>>1) + 1)>>1;
656 dp[14] = (dp[14] + ((unsigned int)(sp[14]+sp2[14]+1)>>1) + 1)>>1;
657 dp[15] = (dp[15] + ((unsigned int)(sp[15]+sp2[15]+1)>>1) + 1)>>1;
658 sp+= lx2;
659 sp2+= lx2;
660 dp+= lx2;
661 }
662}
663
664
665static inline void recvac(unsigned char *s, unsigned char *d, int lx,int lx2, int h){
666 unsigned char *dp,*sp,*sp2;
667 int j;
668
669 sp = s;
670 sp2 = s+lx;
671 dp = d;
672 for (j=0; j<h; j++){
673 dp[0] = (dp[0] + ((unsigned int)(sp[0]+sp2[0]+1)>>1) + 1)>>1;
674 dp[1] = (dp[1] + ((unsigned int)(sp[1]+sp2[1]+1)>>1) + 1)>>1;
675 dp[2] = (dp[2] + ((unsigned int)(sp[2]+sp2[2]+1)>>1) + 1)>>1;
676 dp[3] = (dp[3] + ((unsigned int)(sp[3]+sp2[3]+1)>>1) + 1)>>1;
677 dp[4] = (dp[4] + ((unsigned int)(sp[4]+sp2[4]+1)>>1) + 1)>>1;
678 dp[5] = (dp[5] + ((unsigned int)(sp[5]+sp2[5]+1)>>1) + 1)>>1;
679 dp[6] = (dp[6] + ((unsigned int)(sp[6]+sp2[6]+1)>>1) + 1)>>1;
680 dp[7] = (dp[7] + ((unsigned int)(sp[7]+sp2[7]+1)>>1) + 1)>>1;
681 sp+= lx2;
682 sp2+= lx2;
683 dp+= lx2;
684 }
685}
686
687
688static inline void rech(unsigned char *s, unsigned char *d, int lx2, int h){
689 unsigned char *dp,*sp;
690 unsigned int s1,s2;
691 int j;
692
693 sp = s;
694 dp = d;
695 for (j=0; j<h; j++){
696 s1=sp[0];
697 dp[0] = (unsigned int)(s1+(s2=sp[1])+1)>>1;
698 dp[1] = (unsigned int)(s2+(s1=sp[2])+1)>>1;
699 dp[2] = (unsigned int)(s1+(s2=sp[3])+1)>>1;
700 dp[3] = (unsigned int)(s2+(s1=sp[4])+1)>>1;
701 dp[4] = (unsigned int)(s1+(s2=sp[5])+1)>>1;
702 dp[5] = (unsigned int)(s2+(s1=sp[6])+1)>>1;
703 dp[6] = (unsigned int)(s1+(s2=sp[7])+1)>>1;
704 dp[7] = (unsigned int)(s2+(s1=sp[8])+1)>>1;
705 dp[8] = (unsigned int)(s1+(s2=sp[9])+1)>>1;
706 dp[9] = (unsigned int)(s2+(s1=sp[10])+1)>>1;
707 dp[10] = (unsigned int)(s1+(s2=sp[11])+1)>>1;
708 dp[11] = (unsigned int)(s2+(s1=sp[12])+1)>>1;
709 dp[12] = (unsigned int)(s1+(s2=sp[13])+1)>>1;
710 dp[13] = (unsigned int)(s2+(s1=sp[14])+1)>>1;
711 dp[14] = (unsigned int)(s1+(s2=sp[15])+1)>>1;
712 dp[15] = (unsigned int)(s2+sp[16]+1)>>1;
713 sp+= lx2;
714 dp+= lx2;
715 }
716}
717
718
719static inline void rechc(unsigned char *s,unsigned char *d, int lx2, int h){
720 unsigned char *dp,*sp;
721 unsigned int s1,s2;
722 int j;
723
724 sp = s;
725 dp = d;
726 for (j=0; j<h; j++){
727 s1=sp[0];
728 dp[0] = (unsigned int)(s1+(s2=sp[1])+1)>>1;
729 dp[1] = (unsigned int)(s2+(s1=sp[2])+1)>>1;
730 dp[2] = (unsigned int)(s1+(s2=sp[3])+1)>>1;
731 dp[3] = (unsigned int)(s2+(s1=sp[4])+1)>>1;
732 dp[4] = (unsigned int)(s1+(s2=sp[5])+1)>>1;
733 dp[5] = (unsigned int)(s2+(s1=sp[6])+1)>>1;
734 dp[6] = (unsigned int)(s1+(s2=sp[7])+1)>>1;
735 dp[7] = (unsigned int)(s2+sp[8]+1)>>1;
736 sp+= lx2;
737 dp+= lx2;
738 }
739}
740
741static inline void recha(unsigned char *s, unsigned char *d,int lx2, int h)
742{
743 unsigned char *dp,*sp;
744 unsigned int s1,s2;
745 int j;
746
747 sp = s;
748 dp = d;
749 for (j = 0; j < h; j++)
750 {
751 s1 = sp[0];
752 dp[0] = (dp[0] + ((unsigned int)(s1 + (s2 = sp[1]) + 1) >> 1) + 1) >> 1;
753 dp[1] = (dp[1] + ((unsigned int)(s2 + (s1 = sp[2]) + 1) >> 1) + 1) >> 1;
754 dp[2] = (dp[2] + ((unsigned int)(s1 + (s2 = sp[3]) + 1) >> 1) + 1) >> 1;
755 dp[3] = (dp[3] + ((unsigned int)(s2 + (s1 = sp[4]) + 1) >> 1) + 1) >> 1;
756 dp[4] = (dp[4] + ((unsigned int)(s1 + (s2 = sp[5]) + 1) >> 1) + 1) >> 1;
757 dp[5] = (dp[5] + ((unsigned int)(s2 + (s1 = sp[6]) + 1) >> 1) + 1) >> 1;
758 dp[6] = (dp[6] + ((unsigned int)(s1 + (s2 = sp[7]) + 1) >> 1) + 1) >> 1;
759 dp[7] = (dp[7] + ((unsigned int)(s2 + (s1 = sp[8]) + 1) >> 1) + 1) >> 1;
760 dp[8] = (dp[8] + ((unsigned int)(s1 + (s2 = sp[9]) + 1) >> 1) + 1) >> 1;
761 dp[9] = (dp[9] + ((unsigned int)(s2 + (s1 = sp[10]) + 1) >> 1) + 1) >> 1;
762 dp[10] = (dp[10] + ((unsigned int)(s1 + (s2 = sp[11]) + 1) >> 1) + 1) >> 1;
763 dp[11] = (dp[11] + ((unsigned int)(s2 + (s1 = sp[12]) + 1) >> 1) + 1) >> 1;
764 dp[12] = (dp[12] + ((unsigned int)(s1 + (s2 = sp[13]) + 1) >> 1) + 1) >> 1;
765 dp[13] = (dp[13] + ((unsigned int)(s2 + (s1 = sp[14]) + 1) >> 1) + 1) >> 1;
766 dp[14] = (dp[14] + ((unsigned int)(s1 + (s2 = sp[15]) + 1) >> 1) + 1) >> 1;
767 dp[15] = (dp[15] + ((unsigned int)(s2 + sp[16] + 1) >> 1) + 1) >> 1;
768 sp += lx2;
769 dp += lx2;
770 }
771}
772
773
774static inline void rechac(unsigned char *s,unsigned char *d, int lx2, int h)
775{
776 unsigned char *dp,*sp;
777 unsigned int s1,s2;
778 int j;
779
780 sp = s;
781 dp = d;
782 for(j = 0; j < h; j++)
783 {
784 s1 = sp[0];
785 dp[0] = (dp[0] + ((unsigned int)(s1 + (s2 = sp[1]) + 1) >> 1) + 1) >> 1;
786 dp[1] = (dp[1] + ((unsigned int)(s2 + (s1 = sp[2]) + 1) >> 1) + 1) >> 1;
787 dp[2] = (dp[2] + ((unsigned int)(s1 + (s2 = sp[3]) + 1) >> 1) + 1) >> 1;
788 dp[3] = (dp[3] + ((unsigned int)(s2 + (s1 = sp[4]) + 1) >> 1) + 1) >> 1;
789 dp[4] = (dp[4] + ((unsigned int)(s1 + (s2 = sp[5]) + 1) >> 1) + 1) >> 1;
790 dp[5] = (dp[5] + ((unsigned int)(s2 + (s1 = sp[6]) + 1) >> 1) + 1) >> 1;
791 dp[6] = (dp[6] + ((unsigned int)(s1 + (s2 = sp[7]) + 1) >> 1) + 1) >> 1;
792 dp[7] = (dp[7] + ((unsigned int)(s2 + sp[8] + 1) >> 1) + 1) >> 1;
793 sp += lx2;
794 dp += lx2;
795 }
796}
797
798
799static inline void rec4(unsigned char *s, unsigned char *d, int lx, int lx2, int h)
800{
801 unsigned char *dp,*sp,*sp2;
802 unsigned int s1,s2,s3,s4;
803 int j;
804
805 sp = s;
806 sp2 = s+lx;
807 dp = d;
808 for (j=0; j<h; j++){
809 s1=sp[0]; s3=sp2[0];
810 dp[0] = (unsigned int)(s1+(s2=sp[1])+s3+(s4=sp2[1])+2)>>2;
811 dp[1] = (unsigned int)(s2+(s1=sp[2])+s4+(s3=sp2[2])+2)>>2;
812 dp[2] = (unsigned int)(s1+(s2=sp[3])+s3+(s4=sp2[3])+2)>>2;
813 dp[3] = (unsigned int)(s2+(s1=sp[4])+s4+(s3=sp2[4])+2)>>2;
814 dp[4] = (unsigned int)(s1+(s2=sp[5])+s3+(s4=sp2[5])+2)>>2;
815 dp[5] = (unsigned int)(s2+(s1=sp[6])+s4+(s3=sp2[6])+2)>>2;
816 dp[6] = (unsigned int)(s1+(s2=sp[7])+s3+(s4=sp2[7])+2)>>2;
817 dp[7] = (unsigned int)(s2+(s1=sp[8])+s4+(s3=sp2[8])+2)>>2;
818 dp[8] = (unsigned int)(s1+(s2=sp[9])+s3+(s4=sp2[9])+2)>>2;
819 dp[9] = (unsigned int)(s2+(s1=sp[10])+s4+(s3=sp2[10])+2)>>2;
820 dp[10] = (unsigned int)(s1+(s2=sp[11])+s3+(s4=sp2[11])+2)>>2;
821 dp[11] = (unsigned int)(s2+(s1=sp[12])+s4+(s3=sp2[12])+2)>>2;
822 dp[12] = (unsigned int)(s1+(s2=sp[13])+s3+(s4=sp2[13])+2)>>2;
823 dp[13] = (unsigned int)(s2+(s1=sp[14])+s4+(s3=sp2[14])+2)>>2;
824 dp[14] = (unsigned int)(s1+(s2=sp[15])+s3+(s4=sp2[15])+2)>>2;
825 dp[15] = (unsigned int)(s2+sp[16]+s4+sp2[16]+2)>>2;
826 sp+= lx2;
827 sp2+= lx2;
828 dp+= lx2;
829 }
830}
831
832
833static inline void rec4c(unsigned char *s,unsigned char *d, int lx, int lx2, int h)
834{
835 unsigned char *dp,*sp,*sp2;
836 unsigned int s1,s2,s3,s4;
837 int j;
838
839 sp = s;
840 sp2 = s+lx;
841 dp = d;
842 for (j=0; j<h; j++){
843 s1=sp[0]; s3=sp2[0];
844 dp[0] = (unsigned int)(s1+(s2=sp[1])+s3+(s4=sp2[1])+2)>>2;
845 dp[1] = (unsigned int)(s2+(s1=sp[2])+s4+(s3=sp2[2])+2)>>2;
846 dp[2] = (unsigned int)(s1+(s2=sp[3])+s3+(s4=sp2[3])+2)>>2;
847 dp[3] = (unsigned int)(s2+(s1=sp[4])+s4+(s3=sp2[4])+2)>>2;
848 dp[4] = (unsigned int)(s1+(s2=sp[5])+s3+(s4=sp2[5])+2)>>2;
849 dp[5] = (unsigned int)(s2+(s1=sp[6])+s4+(s3=sp2[6])+2)>>2;
850 dp[6] = (unsigned int)(s1+(s2=sp[7])+s3+(s4=sp2[7])+2)>>2;
851 dp[7] = (unsigned int)(s2+sp[8]+s4+sp2[8]+2)>>2;
852 sp+= lx2;
853 sp2+= lx2;
854 dp+= lx2;
855 }
856}
857
858
859static inline void rec4a(unsigned char *s,unsigned char *d, int lx, int lx2, int h)
860{
861 unsigned char *dp=d, *sp=s, *sp2=s+lx;
862 unsigned int s1, s2, s3, s4;
863 int j;
864
865/*
866 sp = s;
867 sp2 = s+lx;
868 dp = d;
869*/
870 for (j=0; j<h; j++){
871 s1=sp[0]; s3=sp2[0];
872 dp[0] = (dp[0] + ((unsigned int)(s1+(s2=sp[1])+s3+(s4=sp2[1])+2)>>2) + 1)>>1;
873 dp[1] = (dp[1] + ((unsigned int)(s2+(s1=sp[2])+s4+(s3=sp2[2])+2)>>2) + 1)>>1;
874 dp[2] = (dp[2] + ((unsigned int)(s1+(s2=sp[3])+s3+(s4=sp2[3])+2)>>2) + 1)>>1;
875 dp[3] = (dp[3] + ((unsigned int)(s2+(s1=sp[4])+s4+(s3=sp2[4])+2)>>2) + 1)>>1;
876 dp[4] = (dp[4] + ((unsigned int)(s1+(s2=sp[5])+s3+(s4=sp2[5])+2)>>2) + 1)>>1;
877 dp[5] = (dp[5] + ((unsigned int)(s2+(s1=sp[6])+s4+(s3=sp2[6])+2)>>2) + 1)>>1;
878 dp[6] = (dp[6] + ((unsigned int)(s1+(s2=sp[7])+s3+(s4=sp2[7])+2)>>2) + 1)>>1;
879 dp[7] = (dp[7] + ((unsigned int)(s2+(s1=sp[8])+s4+(s3=sp2[8])+2)>>2) + 1)>>1;
880 dp[8] = (dp[8] + ((unsigned int)(s1+(s2=sp[9])+s3+(s4=sp2[9])+2)>>2) + 1)>>1;
881 dp[9] = (dp[9] + ((unsigned int)(s2+(s1=sp[10])+s4+(s3=sp2[10])+2)>>2) + 1)>>1;
882 dp[10] = (dp[10] + ((unsigned int)(s1+(s2=sp[11])+s3+(s4=sp2[11])+2)>>2) + 1)>>1;
883 dp[11] = (dp[11] + ((unsigned int)(s2+(s1=sp[12])+s4+(s3=sp2[12])+2)>>2) + 1)>>1;
884 dp[12] = (dp[12] + ((unsigned int)(s1+(s2=sp[13])+s3+(s4=sp2[13])+2)>>2) + 1)>>1;
885 dp[13] = (dp[13] + ((unsigned int)(s2+(s1=sp[14])+s4+(s3=sp2[14])+2)>>2) + 1)>>1;
886 dp[14] = (dp[14] + ((unsigned int)(s1+(s2=sp[15])+s3+(s4=sp2[15])+2)>>2) + 1)>>1;
887 dp[15] = (dp[15] + ((unsigned int)(s2+sp[16]+s4+sp2[16]+2)>>2) + 1)>>1;
888 sp+= lx2;
889 sp2+= lx2;
890 dp+= lx2;
891 }
892}
893
894
895static inline void rec4ac(unsigned char *s,unsigned char *d, int lx, int lx2, int h)
896{
897 unsigned char *dp=d, *sp=s, *sp2=s+lx;
898 unsigned int s1,s2,s3,s4;
899 int j;
900
901/*
902 sp = s;
903 sp2 = s+lx;
904 dp = d;
905*/
906 for (j=0; j<h; j++)
907 {
908 s1=sp[0]; s3=sp2[0];
909 dp[0] = (dp[0] + ((unsigned int)(s1+(s2=sp[1])+s3+(s4=sp2[1])+2)>>2) + 1)>>1;
910 dp[1] = (dp[1] + ((unsigned int)(s2+(s1=sp[2])+s4+(s3=sp2[2])+2)>>2) + 1)>>1;
911 dp[2] = (dp[2] + ((unsigned int)(s1+(s2=sp[3])+s3+(s4=sp2[3])+2)>>2) + 1)>>1;
912 dp[3] = (dp[3] + ((unsigned int)(s2+(s1=sp[4])+s4+(s3=sp2[4])+2)>>2) + 1)>>1;
913 dp[4] = (dp[4] + ((unsigned int)(s1+(s2=sp[5])+s3+(s4=sp2[5])+2)>>2) + 1)>>1;
914 dp[5] = (dp[5] + ((unsigned int)(s2+(s1=sp[6])+s4+(s3=sp2[6])+2)>>2) + 1)>>1;
915 dp[6] = (dp[6] + ((unsigned int)(s1+(s2=sp[7])+s3+(s4=sp2[7])+2)>>2) + 1)>>1;
916 dp[7] = (dp[7] + ((unsigned int)(s2+sp[8]+s4+sp2[8]+2)>>2) + 1)>>1;
917 sp+= lx2;
918 sp2+= lx2;
919 dp+= lx2;
920 }
921}
922
923static inline
924void recon_comp(mpeg3video_t *video,
925 unsigned char *src,
926 unsigned char *dst,
927 int lx,
928 int lx2,
929 int w,
930 int h,
931 int x,
932 int y,
933 int dx,
934 int dy,
935 int addflag)
936{
937 int switcher;
938 unsigned char *s, *d;
939
940/* half pel scaling */
941 switcher = (dx & 1) << 3 | (dy & 1) << 2 | w;
942 if(addflag) switcher |= 2;
943/* origins */
944 s = src + lx * (y + (dy >> 1)) + x + (dx >> 1);
945 d = dst + lx * y + x;
946
947// Accelerated functions
948#ifdef HAVE_3Dnow
949 if(video->have_mmx)
950 {
951 switch(switcher)
952 {
953 case 0x3: reca_mmx(s, d, lx2, h); break;
954 case 0x2:recac_mmx(s, d, lx2, h); break;
955 case 0x1:rec_mmx(s, d, lx2, h); break;
956 case 0x0:recc_mmx(s, d, lx2, h); break;
957 case 0x7: recva_mmx(s, d, lx, lx2, h); break;
958 case 0x6: recvac_mmx(s, d, lx, lx2, h); break;
959 case 0x5:recv_mmx(s, d, lx, lx2, h); break;
960 case 0x4:recvc_mmx(s, d, lx, lx2, h); break;
961 case 0x9:rech_mmx(s, d, lx2, h); break;
962 case 0x8: rechc_mmx(s, d, lx2, h); break;
963 }
964 }
965 else
966#endif
967 {
968 switch(switcher)
969 {
970 case 0x3: reca(s, d, lx2, h); break;
971 case 0x2:recac(s, d, lx2, h); break;
972 case 0x1:rec(s, d, lx2, h); break;
973 case 0x0:recc(s, d, lx2, h); break;
974 case 0x7: recva(s, d, lx, lx2, h); break;
975 case 0x6: recvac(s, d, lx, lx2, h); break;
976 case 0x5:recv_(s, d, lx, lx2, h); break;
977 case 0x4:recvc(s, d, lx, lx2, h); break;
978 case 0x9:rech(s, d, lx2, h); break;
979 case 0x8: rechc(s, d, lx2, h); break;
980 }
981 }
982
983// Unaccelerated functions
984 switch(switcher)
985 {
986 case 0xb: recha(s, d, lx2, h); break;
987 case 0xa:rechac(s, d, lx2, h); break;
988 case 0xf: rec4a(s, d, lx, lx2, h); break;
989 case 0xe:rec4ac(s, d, lx, lx2, h); break;
990 case 0xd:rec4(s, d, lx, lx2, h); break;
991 case 0xc:rec4c(s, d, lx, lx2, h); break;
992 }
993}
994
995/*
996 unsigned char *src[]; * prediction source buffer *
997 int sfield; * prediction source field number (0 or 1) *
998 unsigned char *dst[]; * prediction destination buffer *
999 int dfield; * prediction destination field number (0 or 1)*
1000 int lx,lx2; * horizontal offsets *
1001 int w,h; * prediction block/sub-block width, height *
1002 int x,y; * pixel co-ordinates of top-left sample in current MB *
1003 int dx,dy; * horizontal, vertical motion vector *
1004 int addflag; * add prediction error to prediction ? *
1005*/
1006static void recon(mpeg3video_t *video,
1007 unsigned char *src[],
1008 int sfield,
1009 unsigned char *dst[],
1010 int dfield,
1011 int lx,
1012 int lx2,
1013 int w,
1014 int h,
1015 int x,
1016 int y,
1017 int dx,
1018 int dy,
1019 int addflag)
1020{
1021
1022/* Y */
1023 recon_comp(video, (src[0] + (sfield ? (lx2 >> 1) : 0)),
1024 dst[0] + (dfield ? (lx2 >> 1) : 0),
1025 lx, lx2, w, h, x, y, dx, dy, addflag);
1026
1027 if(video->chroma_format != CHROMA444)
1028 {
1029 lx >>= 1;
1030 dx /= 2;
1031 lx2 >>= 1;
1032 w = 0;
1033 x >>= 1;
1034 }
1035
1036 if(video->chroma_format == CHROMA420)
1037 {
1038 h >>= 1;
1039 dy /= 2;
1040 y >>= 1;
1041 }
1042
1043/* Cb */
1044 recon_comp(video, (src[1] + (sfield ? (lx2 >> 1) : 0)),
1045 dst[1] + (dfield ? (lx2 >> 1) : 0),
1046 lx, lx2, w, h, x, y, dx, dy, addflag);
1047
1048/* Cr */
1049 recon_comp(video, (src[2] + (sfield ? (lx2 >> 1) : 0)),
1050 dst[2] + (dfield ? (lx2 >> 1) : 0),
1051 lx, lx2, w, h, x, y, dx, dy, addflag);
1052}
1053
1054#define WIDTH 1
1055
1056int mpeg3video_reconstruct(mpeg3video_t *video,
1057 int bx,
1058 int by,
1059 int mb_type,
1060 int motion_type,
1061 int PMV[2][2][2],
1062 int mv_field_sel[2][2],
1063 int dmvector[2],
1064 int stwtype)
1065{
1066 int currentfield;
1067 unsigned char **predframe;
1068 int DMV[2][2];
1069 int stwtop, stwbot;
1070
1071 stwtop = stwtype % 3; /* 0:temporal, 1 : (spat+temp) / 2, 2 : spatial */
1072 stwbot = stwtype / 3;
1073
1074 if((mb_type & MB_FORWARD) || (video->pict_type == P_TYPE))
1075 {
1076 if(video->pict_struct == FRAME_PICTURE)
1077 {
1078 if((motion_type == MC_FRAME) || !(mb_type & MB_FORWARD))
1079 {
1080/* frame-based prediction */
1081 {
1082 if(stwtop < 2)
1083 recon(video, video->oldrefframe, 0, video->newframe, 0,
1084 video->coded_picture_width, video->coded_picture_width << 1, WIDTH, 8, bx, by,
1085 PMV[0][0][0], PMV[0][0][1], stwtop);
1086
1087 if(stwbot < 2)
1088 recon(video, video->oldrefframe, 1, video->newframe, 1,
1089 video->coded_picture_width, video->coded_picture_width << 1, WIDTH, 8, bx, by,
1090 PMV[0][0][0], PMV[0][0][1], stwbot);
1091 }
1092 }
1093 else if(motion_type == MC_FIELD) /* field-based prediction */
1094 {
1095/* top field prediction */
1096 if(stwtop < 2)
1097 recon(video, video->oldrefframe, mv_field_sel[0][0], video->newframe, 0,
1098 video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by >> 1,
1099 PMV[0][0][0], PMV[0][0][1] >> 1, stwtop);
1100
1101/* bottom field prediction */
1102 if(stwbot < 2)
1103 recon(video, video->oldrefframe, mv_field_sel[1][0], video->newframe, 1,
1104 video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by >> 1,
1105 PMV[1][0][0], PMV[1][0][1] >> 1, stwbot);
1106 }
1107 else if(motion_type == MC_DMV)
1108 {
1109/* dual prime prediction */
1110/* calculate derived motion vectors */
1111 mpeg3video_calc_dmv(video,
1112 DMV,
1113 dmvector,
1114 PMV[0][0][0],
1115 PMV[0][0][1] >> 1);
1116
1117 if(stwtop < 2)
1118 {
1119/* predict top field from top field */
1120 recon(video, video->oldrefframe, 0, video->newframe, 0,
1121 video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by>>1,
1122 PMV[0][0][0], PMV[0][0][1] >> 1, 0);
1123
1124/* predict and add to top field from bottom field */
1125 recon(video, video->oldrefframe, 1, video->newframe, 0,
1126 video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by>>1,
1127 DMV[0][0], DMV[0][1], 1);
1128 }
1129
1130 if(stwbot < 2)
1131 {
1132/* predict bottom field from bottom field */
1133 recon(video, video->oldrefframe, 1, video->newframe, 1,
1134 video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by>>1,
1135 PMV[0][0][0], PMV[0][0][1]>>1, 0);
1136
1137/* predict and add to bottom field from top field */
1138 recon(video, video->oldrefframe, 0, video->newframe, 1,
1139 video->coded_picture_width << 1, video->coded_picture_width<<1, WIDTH, 8, bx, by>>1,
1140 DMV[1][0], DMV[1][1], 1);
1141 }
1142 }
1143 else
1144/* invalid motion_type */
1145 /* fprintf(stderr, "reconstruct: invalid motion_type\n"); */
1146 ;
1147 }
1148 else
1149 {
1150/* TOP_FIELD or BOTTOM_FIELD */
1151/* field picture */
1152 currentfield = (video->pict_struct == BOTTOM_FIELD);
1153
1154/* determine which frame to use for prediction */
1155 if((video->pict_type == P_TYPE) && video->secondfield
1156 && (currentfield != mv_field_sel[0][0]))
1157 predframe = video->refframe; /* same frame */
1158 else
1159 predframe = video->oldrefframe; /* previous frame */
1160
1161 if((motion_type == MC_FIELD) || !(mb_type & MB_FORWARD))
1162 {
1163/* field-based prediction */
1164 if(stwtop < 2)
1165 recon(video, predframe,mv_field_sel[0][0],video->newframe,0,
1166 video->coded_picture_width << 1,video->coded_picture_width << 1,WIDTH,16,bx,by,
1167 PMV[0][0][0],PMV[0][0][1],stwtop);
1168 }
1169 else
1170 if(motion_type == MC_16X8)
1171 {
1172 if(stwtop < 2)
1173 {
1174 recon(video, predframe, mv_field_sel[0][0], video->newframe, 0,
1175 video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by,
1176 PMV[0][0][0], PMV[0][0][1], stwtop);
1177
1178 /* determine which frame to use for lower half prediction */
1179 if((video->pict_type==P_TYPE) && video->secondfield
1180 && (currentfield!=mv_field_sel[1][0]))
1181 predframe = video->refframe; /* same frame */
1182 else
1183 predframe = video->oldrefframe; /* previous frame */
1184
1185 recon(video, predframe, mv_field_sel[1][0], video->newframe, 0,
1186 video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by+8,
1187 PMV[1][0][0], PMV[1][0][1], stwtop);
1188 }
1189 }
1190 else
1191 if(motion_type == MC_DMV) /* dual prime prediction */
1192 {
1193 if(video->secondfield)
1194 predframe = video->refframe; /* same frame */
1195 else
1196 predframe = video->oldrefframe; /* previous frame */
1197
1198/* calculate derived motion vectors */
1199 mpeg3video_calc_dmv(video,
1200 DMV,
1201 dmvector,
1202 PMV[0][0][0],
1203 PMV[0][0][1]);
1204
1205/* predict from field of same parity */
1206 recon(video, video->oldrefframe, currentfield, video->newframe, 0,
1207 video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 16, bx, by,
1208 PMV[0][0][0], PMV[0][0][1], 0);
1209
1210/* predict from field of opposite parity */
1211 recon(video, predframe, !currentfield, video->newframe, 0,
1212 video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 16, bx, by,
1213 DMV[0][0], DMV[0][1], 1);
1214 }
1215 else
1216/* invalid motion_type */
1217 /* fprintf(stderr, "reconstruct: invalid motion_type\n"); */
1218 ;
1219 }
1220 stwtop = stwbot = 1;
1221 }
1222
1223 if(mb_type & MB_BACKWARD)
1224 {
1225 if(video->pict_struct == FRAME_PICTURE)
1226 {
1227 if(motion_type == MC_FRAME)
1228 {
1229/* frame-based prediction */
1230 if(stwtop < 2)
1231 recon(video, video->refframe, 0, video->newframe, 0,
1232 video->coded_picture_width, video->coded_picture_width << 1, WIDTH, 8, bx, by,
1233 PMV[0][1][0], PMV[0][1][1], stwtop);
1234
1235 if(stwbot < 2)
1236 recon(video, video->refframe, 1, video->newframe, 1,
1237 video->coded_picture_width, video->coded_picture_width << 1, WIDTH, 8, bx, by,
1238 PMV[0][1][0], PMV[0][1][1], stwbot);
1239 }
1240 else
1241 {
1242/* field-based prediction */
1243/* top field prediction */
1244 if(stwtop < 2)
1245 {
1246 recon(video, video->refframe, mv_field_sel[0][1], video->newframe, 0,
1247 (video->coded_picture_width << 1), (video->coded_picture_width<<1), WIDTH, 8, bx, (by >> 1),
1248 PMV[0][1][0], (PMV[0][1][1] >> 1), stwtop);
1249 }
1250
1251/* bottom field prediction */
1252 if(stwbot < 2)
1253 {
1254 recon(video, video->refframe, mv_field_sel[1][1], video->newframe, 1, (video->coded_picture_width << 1),
1255 (video->coded_picture_width << 1), WIDTH, 8, bx, (by>>1),
1256 PMV[1][1][0], (PMV[1][1][1]>>1), stwbot);
1257 }
1258 }
1259 }
1260 else
1261 {
1262/* TOP_FIELD or BOTTOM_FIELD */
1263/* field picture */
1264 if(motion_type == MC_FIELD)
1265 {
1266/* field-based prediction */
1267 recon(video, video->refframe, mv_field_sel[0][1], video->newframe, 0,
1268 video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 16, bx, by,
1269 PMV[0][1][0], PMV[0][1][1], stwtop);
1270 }
1271 else if(motion_type==MC_16X8)
1272 {
1273 recon(video, video->refframe, mv_field_sel[0][1], video->newframe, 0,
1274 video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by,
1275 PMV[0][1][0], PMV[0][1][1], stwtop);
1276
1277 recon(video, video->refframe, mv_field_sel[1][1], video->newframe, 0,
1278 video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by+8,
1279 PMV[1][1][0], PMV[1][1][1], stwtop);
1280 }
1281 else
1282/* invalid motion_type */
1283 /* fprintf(stderr, "reconstruct: invalid motion_type\n"); */
1284 ;
1285 }
1286 } /* mb_type & MB_BACKWARD */
1287 return 0;
1288}
1289
1290
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 @@
1#include "../mpeg3private.h"
2#include "../mpeg3protos.h"
3#include "mpeg3video.h"
4#include <stdlib.h>
5#include <string.h>
6
7unsigned int mpeg3bits_next_startcode(mpeg3_bits_t* stream)
8{
9/* Perform forwards search */
10 mpeg3bits_byte_align(stream);
11
12/* Perform search */
13 while((mpeg3bits_showbits32_noptr(stream) >> 8) != MPEG3_PACKET_START_CODE_PREFIX &&
14 !mpeg3bits_eof(stream))
15 {
16 mpeg3bits_getbyte_noptr(stream);
17 }
18 return mpeg3bits_showbits32_noptr(stream);
19}
20
21/* Line up on the beginning of the next code. */
22int mpeg3video_next_code(mpeg3_bits_t* stream, unsigned int code)
23{
24 while(!mpeg3bits_eof(stream) &&
25 mpeg3bits_showbits32_noptr(stream) != code)
26 {
27 mpeg3bits_getbyte_noptr(stream);
28 }
29 return mpeg3bits_eof(stream);
30}
31
32/* Line up on the beginning of the previous code. */
33int mpeg3video_prev_code(mpeg3_bits_t* stream, unsigned int code)
34{
35 while(!mpeg3bits_bof(stream) &&
36 mpeg3bits_showbits_reverse(stream, 32) != code)
37 {
38 mpeg3bits_getbits_reverse(stream, 8);
39 }
40 return mpeg3bits_bof(stream);
41}
42
43long mpeg3video_goptimecode_to_frame(mpeg3video_t *video)
44{
45/* printf("mpeg3video_goptimecode_to_frame %d %d %d %d %f\n", */
46 /* video->gop_timecode.hour, video->gop_timecode.minute, video->gop_timecode.second, video->gop_timecode.frame, video->frame_rate); */
47 return (long)(video->gop_timecode.hour * 3600 * video->frame_rate +
48 video->gop_timecode.minute * 60 * video->frame_rate +
49 video->gop_timecode.second * video->frame_rate +
50 video->gop_timecode.frame) - 1 - video->first_frame;
51}
52
53int mpeg3video_match_refframes(mpeg3video_t *video)
54{
55 unsigned char *dst, *src;
56 int i, j, size;
57
58 for(i = 0; i < 3; i++)
59 {
60 if(video->newframe[i])
61 {
62 if(video->newframe[i] == video->refframe[i])
63 {
64 src = video->refframe[i];
65 dst = video->oldrefframe[i];
66 }
67 else
68 {
69 src = video->oldrefframe[i];
70 dst = video->refframe[i];
71 }
72
73 if(i == 0)
74 size = video->coded_picture_width * video->coded_picture_height + 32 * video->coded_picture_width;
75 else
76 size = video->chrom_width * video->chrom_height + 32 * video->chrom_width;
77
78 memcpy(dst, src, size);
79 }
80 }
81 return 0;
82}
83
84int mpeg3video_seek(mpeg3video_t *video)
85{
86 long this_gop_start;
87 int result = 0;
88 int back_step;
89 int attempts;
90 mpeg3_t *file = video->file;
91 mpeg3_bits_t *vstream = video->vstream;
92 double percentage;
93 long frame_number;
94 int match_refframes = 1;
95
96/* Seek to a percentage */
97 if(video->percentage_seek >= 0)
98 {
99 percentage = video->percentage_seek;
100 video->percentage_seek = -1;
101 mpeg3bits_seek_percentage(vstream, percentage);
102// Go to previous I-frame
103 mpeg3bits_start_reverse(vstream);
104 result = mpeg3video_prev_code(vstream, MPEG3_GOP_START_CODE);
105 if(!result) mpeg3bits_getbits_reverse(vstream, 32);
106 mpeg3bits_start_forward(vstream);
107
108 if(mpeg3bits_tell_percentage(vstream) < 0) mpeg3bits_seek_percentage(vstream, 0);
109
110// Read up to the correct percentage
111 result = 0;
112 while(!result && mpeg3bits_tell_percentage(vstream) < percentage)
113 {
114 result = mpeg3video_read_frame_backend(video, 0);
115 if(match_refframes)
116 mpeg3video_match_refframes(video);
117 match_refframes = 0;
118 }
119 }
120 else
121/* Seek to a frame */
122 if(video->frame_seek >= 0)
123 {
124 frame_number = video->frame_seek;
125 video->frame_seek = -1;
126 if(frame_number < 0) frame_number = 0;
127 if(frame_number > video->maxframe) frame_number = video->maxframe;
128
129/* Seek to start of file */
130 if(frame_number < 16)
131 {
132 video->repeat_count = video->current_repeat = 0;
133 mpeg3bits_seek_start(vstream);
134 video->framenum = 0;
135 result = mpeg3video_drop_frames(video, frame_number - video->framenum);
136 }
137 else
138 {
139/* Seek to an I frame. */
140 if((frame_number < video->framenum || frame_number - video->framenum > MPEG3_SEEK_THRESHOLD))
141 {
142/* Elementary stream */
143 if(file->is_video_stream)
144 {
145 mpeg3_t *file = video->file;
146 mpeg3_vtrack_t *track = video->track;
147 long byte = (long)((float)(mpeg3demuxer_total_bytes(vstream->demuxer) /
148 track->total_frames) *
149 frame_number);
150 long minimum = 65535;
151 int done = 0;
152
153//printf("seek elementary %d\n", frame_number);
154/* Get GOP just before frame */
155 do
156 {
157 result = mpeg3bits_seek_byte(vstream, byte);
158 mpeg3bits_start_reverse(vstream);
159 if(!result) result = mpeg3video_prev_code(vstream, MPEG3_GOP_START_CODE);
160 mpeg3bits_start_forward(vstream);
161 mpeg3bits_getbits(vstream, 8);
162 if(!result) result = mpeg3video_getgophdr(video);
163 this_gop_start = mpeg3video_goptimecode_to_frame(video);
164
165//printf("wanted %ld guessed %ld byte %ld result %d\n", frame_number, this_gop_start, byte, result);
166 if(labs(this_gop_start - frame_number) >= labs(minimum))
167 done = 1;
168 else
169 {
170 minimum = this_gop_start - frame_number;
171 byte += (long)((float)(frame_number - this_gop_start) *
172 (float)(mpeg3demuxer_total_bytes(vstream->demuxer) /
173 track->total_frames));
174 if(byte < 0) byte = 0;
175 }
176 }while(!result && !done);
177
178//printf("wanted %d guessed %d\n", frame_number, this_gop_start);
179 if(!result)
180 {
181 video->framenum = this_gop_start;
182 result = mpeg3video_drop_frames(video, frame_number - video->framenum);
183 }
184 }
185 else
186/* System stream */
187 {
188 mpeg3bits_seek_time(vstream, (double)frame_number / video->frame_rate);
189 percentage = mpeg3bits_tell_percentage(vstream);
190//printf("seek frame %ld percentage %f byte %ld\n", frame_number, percentage, mpeg3bits_tell(vstream));
191 mpeg3bits_start_reverse(vstream);
192 mpeg3video_prev_code(vstream, MPEG3_GOP_START_CODE);
193 mpeg3bits_getbits_reverse(vstream, 32);
194 mpeg3bits_start_forward(vstream);
195//printf("seek system 1 %f\n", (double)frame_number / video->frame_rate);
196
197 while(!result && mpeg3bits_tell_percentage(vstream) < percentage)
198 {
199 result = mpeg3video_read_frame_backend(video, 0);
200 if(match_refframes)
201 mpeg3video_match_refframes(video);
202
203//printf("seek system 2 %f %f\n", mpeg3bits_tell_percentage(vstream) / percentage);
204 match_refframes = 0;
205 }
206//printf("seek system 3 %f\n", (double)frame_number / video->frame_rate);
207 }
208
209 video->framenum = frame_number;
210 }
211 else
212// Drop frames
213 {
214 mpeg3video_drop_frames(video, frame_number - video->framenum);
215 }
216 }
217 }
218
219 return result;
220}
221
222int mpeg3video_drop_frames(mpeg3video_t *video, long frames)
223{
224 int result = 0;
225 long frame_number = video->framenum + frames;
226
227/* Read the selected number of frames and skip b-frames */
228 while(!result && frame_number > video->framenum)
229 {
230 result = mpeg3video_read_frame_backend(video, frame_number - video->framenum);
231 }
232 return result;
233}
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 @@
1#include "../libmpeg3.h"
2#include "../mpeg3protos.h"
3#include "mpeg3video.h"
4#include "mpeg3videoprotos.h"
5#include "slice.h"
6
7#include <stdlib.h>
8
9static ULONGLONG MMX_128 = 0x80008000800080LL;
10
11int mpeg3_new_slice_buffer(mpeg3_slice_buffer_t *slice_buffer)
12{
13 pthread_mutexattr_t mutex_attr;
14 slice_buffer->data = (unsigned char*)malloc(1024);
15 slice_buffer->buffer_size = 0;
16 slice_buffer->buffer_allocation = 1024;
17 slice_buffer->current_position = 0;
18 slice_buffer->bits_size = 0;
19 slice_buffer->bits = 0;
20 slice_buffer->done = 0;
21 pthread_mutexattr_init(&mutex_attr);
22 pthread_mutex_init(&(slice_buffer->completion_lock), &mutex_attr);
23 return 0;
24}
25
26int mpeg3_delete_slice_buffer(mpeg3_slice_buffer_t *slice_buffer)
27{
28 free(slice_buffer->data);
29 pthread_mutex_destroy(&(slice_buffer->completion_lock));
30 return 0;
31}
32
33int mpeg3_expand_slice_buffer(mpeg3_slice_buffer_t *slice_buffer)
34{
35 int i;
36 unsigned char *new_buffer =
37 (unsigned char*)malloc(slice_buffer->buffer_allocation * 2);
38 for(i = 0; i < slice_buffer->buffer_size; i++)
39 new_buffer[i] = slice_buffer->data[i];
40 free(slice_buffer->data);
41 slice_buffer->data = new_buffer;
42 slice_buffer->buffer_allocation *= 2;
43 return 0;
44}
45
46/* limit coefficients to -2048..2047 */
47
48/* move/add 8x8-Block from block[comp] to refframe */
49
50static inline int mpeg3video_addblock(mpeg3_slice_t *slice,
51 mpeg3video_t *video,
52 int comp,
53 int bx,
54 int by,
55 int dct_type,
56 int addflag)
57{
58 int cc, i, iincr;
59 unsigned char *rfp;
60 short *bp;
61 int spar = slice->sparse[comp];
62/* color component index */
63 cc = (comp < 4) ? 0 : (comp & 1) + 1;
64
65 if(cc == 0)
66 {
67/* luminance */
68 if(video->pict_struct == FRAME_PICTURE)
69 {
70 if(dct_type)
71 {
72/* field DCT coding */
73 rfp = video->newframe[0] +
74 video->coded_picture_width * (by + ((comp & 2) >> 1)) + bx + ((comp & 1) << 3);
75 iincr = (video->coded_picture_width << 1);
76 }
77 else
78 {
79/* frame DCT coding */
80 rfp = video->newframe[0] +
81 video->coded_picture_width * (by + ((comp & 2) << 2)) + bx + ((comp & 1) << 3);
82 iincr = video->coded_picture_width;
83 }
84 }
85 else
86 {
87/* field picture */
88 rfp = video->newframe[0] +
89 (video->coded_picture_width << 1) * (by + ((comp & 2) << 2)) + bx + ((comp & 1) << 3);
90 iincr = (video->coded_picture_width << 1);
91 }
92 }
93 else
94 {
95/* chrominance */
96
97/* scale coordinates */
98 if(video->chroma_format != CHROMA444) bx >>= 1;
99 if(video->chroma_format == CHROMA420) by >>= 1;
100 if(video->pict_struct == FRAME_PICTURE)
101 {
102 if(dct_type && (video->chroma_format != CHROMA420))
103 {
104/* field DCT coding */
105 rfp = video->newframe[cc]
106 + video->chrom_width * (by + ((comp & 2) >> 1)) + bx + (comp & 8);
107 iincr = (video->chrom_width << 1);
108 }
109 else
110 {
111/* frame DCT coding */
112 rfp = video->newframe[cc]
113 + video->chrom_width * (by + ((comp & 2) << 2)) + bx + (comp & 8);
114 iincr = video->chrom_width;
115 }
116 }
117 else
118 {
119/* field picture */
120 rfp = video->newframe[cc]
121 + (video->chrom_width << 1) * (by + ((comp & 2) << 2)) + bx + (comp & 8);
122 iincr = (video->chrom_width << 1);
123 }
124 }
125
126 bp = slice->block[comp];
127
128 if(addflag)
129 {
130#ifdef HAVE_MMX
131 if(video->have_mmx)
132 {
133 if(spar)
134 {
135 __asm__ __volatile__(
136 "movq (%2), %%mm6\n" /* 4 blockvals */
137 "pxor %%mm4, %%mm4\n"
138 "punpcklwd %%mm6, %%mm6\n"
139 "punpcklwd %%mm6, %%mm6\n"
140 ".align 8\n"
141 "1:"
142 "movq (%1), %%mm0\n" /* 8 rindex1 */
143 "movq %%mm0, %%mm2\n"
144 "punpcklbw %%mm4, %%mm0\n"
145 "punpckhbw %%mm4, %%mm2\n"
146 "paddw %%mm6, %%mm0\n"
147 "paddw %%mm6, %%mm2\n"
148
149 "packuswb %%mm2, %%mm0\n"
150 "movq %%mm0, (%1)\n"
151
152 "leal (%1, %3), %1\n"
153 "loop 1b\n"
154 : /* scr dest */
155 : "c" (8),"r" (rfp), "r" (bp), "r" (iincr)
156 );
157 }
158 else
159 {
160 __asm__ __volatile__(
161 "pxor %%mm4, %%mm4\n"
162
163 ".align 8\n"
164 "1:"
165 "movq (%2), %%mm0\n" /* 8 rfp 0 1 2 3 4 5 6 7*/
166 "movq (%1), %%mm6\n" /* 4 blockvals 0 1 2 3 */
167
168 "movq %%mm0, %%mm2\n"
169 "movq 8(%1), %%mm5\n" /* 4 blockvals 0 1 2 3 */
170 "punpcklbw %%mm4, %%mm0\n" /* 0 2 4 6 */
171 "punpckhbw %%mm4, %%mm2\n" /* 1 3 5 7 */
172
173 "paddw %%mm6, %%mm0\n"
174 "paddw %%mm5, %%mm2\n"
175 "packuswb %%mm2, %%mm0\n"
176
177 "addl $16, %1\n"
178 "movq %%mm0, (%2)\n"
179
180 "leal (%2,%3), %2\n"
181 "loop 1b\n"
182 : /* scr dest */
183 : "c" (8),"r" (bp), "r" (rfp), "r" (iincr)
184 );
185 }
186 }
187 else
188#endif
189 for(i = 0; i < 8; i++)
190 {
191 rfp[0] = CLIP(bp[0] + rfp[0]);
192 rfp[1] = CLIP(bp[1] + rfp[1]);
193 rfp[2] = CLIP(bp[2] + rfp[2]);
194 rfp[3] = CLIP(bp[3] + rfp[3]);
195 rfp[4] = CLIP(bp[4] + rfp[4]);
196 rfp[5] = CLIP(bp[5] + rfp[5]);
197 rfp[6] = CLIP(bp[6] + rfp[6]);
198 rfp[7] = CLIP(bp[7] + rfp[7]);
199 rfp += iincr;
200 bp += 8;
201 }
202 }
203 else
204 {
205#ifdef HAVE_MMX
206 if(video->have_mmx)
207 {
208 if(spar)
209 {
210 __asm__ __volatile__(
211 "movd (%2), %%mm0\n" /* " 0 0 0 v1" */
212 "punpcklwd %%mm0, %%mm0\n" /* " 0 0 v1 v1" */
213 "punpcklwd %%mm0, %%mm0\n"
214 "paddw MMX_128, %%mm0\n"
215 "packuswb %%mm0, %%mm0\n"
216 "leal (%0,%1,2), %%eax\n"
217
218 "movq %%mm0, (%0, %1)\n"
219 "movq %%mm0, (%%eax)\n"
220 "leal (%%eax,%1,2), %0\n"
221 "movq %%mm0, (%%eax, %1)\n"
222
223 "movq %%mm0, (%0)\n"
224 "leal (%0,%1,2), %%eax\n"
225 "movq %%mm0, (%0, %1)\n"
226
227 "movq %%mm0, (%%eax)\n"
228 "movq %%mm0, (%%eax, %1)\n"
229 :
230 : "D" (rfp), "c" (iincr), "b" (bp)
231 : "eax");
232 }
233 else
234 {
235 __asm__ __volatile__(
236 "movq MMX_128,%%mm4\n"
237 ".align 8\n"
238 "1:"
239 "movq (%1), %%mm0\n"
240 "movq 8(%1), %%mm1\n"
241 "paddw %%mm4, %%mm0\n"
242
243 "movq 16(%1), %%mm2\n"
244 "paddw %%mm4, %%mm1\n"
245
246 "movq 24(%1), %%mm3\n"
247 "paddw %%mm4, %%mm2\n"
248
249 "packuswb %%mm1, %%mm0\n"
250 "paddw %%mm4, %%mm3\n"
251
252 "addl $32, %1\n"
253 "packuswb %%mm3, %%mm2\n"
254
255 "movq %%mm0, (%2)\n"
256
257 "movq %%mm2, (%2,%3)\n"
258
259 "leal (%2,%3,2), %2\n"
260 "loop 1b\n"
261 :
262 : "c" (4), "r" (bp), "r" (rfp), "r" (iincr)
263 );
264 }
265 }
266 else
267#endif
268 for(i = 0; i < 8; i++)
269 {
270 rfp[0] = CLIP(bp[0] + 128);
271 rfp[1] = CLIP(bp[1] + 128);
272 rfp[2] = CLIP(bp[2] + 128);
273 rfp[3] = CLIP(bp[3] + 128);
274 rfp[4] = CLIP(bp[4] + 128);
275 rfp[5] = CLIP(bp[5] + 128);
276 rfp[6] = CLIP(bp[6] + 128);
277 rfp[7] = CLIP(bp[7] + 128);
278 rfp+= iincr;
279 bp += 8;
280 }
281 }
282 return 0;
283}
284
285int mpeg3_decode_slice(mpeg3_slice_t *slice)
286{
287 mpeg3video_t *video = slice->video;
288 int comp;
289 int mb_type, cbp, motion_type = 0, dct_type;
290 int macroblock_address, mba_inc, mba_max;
291 int slice_vert_pos_ext;
292 unsigned int code;
293 int bx, by;
294 int dc_dct_pred[3];
295 int mv_count, mv_format, mvscale;
296 int pmv[2][2][2], mv_field_sel[2][2];
297 int dmv, dmvector[2];
298 int qs;
299 int stwtype, stwclass;
300 int snr_cbp;
301 int i;
302 mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
303
304/* number of macroblocks per picture */
305 mba_max = video->mb_width * video->mb_height;
306
307/* field picture has half as many macroblocks as frame */
308 if(video->pict_struct != FRAME_PICTURE)
309 mba_max >>= 1;
310
311/* macroblock address */
312 macroblock_address = 0;
313/* first macroblock in slice is not skipped */
314 mba_inc = 0;
315 slice->fault = 0;
316
317 code = mpeg3slice_getbits(slice_buffer, 32);
318/* decode slice header (may change quant_scale) */
319 slice_vert_pos_ext = mpeg3video_getslicehdr(slice, video);
320
321/* reset all DC coefficient and motion vector predictors */
322 dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0;
323 pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0;
324 pmv[0][1][0] = pmv[0][1][1] = pmv[1][1][0] = pmv[1][1][1] = 0;
325
326 for(i = 0;
327 slice_buffer->current_position < slice_buffer->buffer_size;
328 i++)
329 {
330 if(mba_inc == 0)
331 {
332/* Done */
333 if(!mpeg3slice_showbits(slice_buffer, 23)) return 0;
334/* decode macroblock address increment */
335 mba_inc = mpeg3video_get_macroblock_address(slice);
336
337 if(slice->fault) return 1;
338
339 if(i == 0)
340 {
341/* Get the macroblock_address */
342 macroblock_address = ((slice_vert_pos_ext << 7) + (code & 255) - 1) * video->mb_width + mba_inc - 1;
343/* first macroblock in slice: not skipped */
344 mba_inc = 1;
345 }
346 }
347
348 if(slice->fault) return 1;
349
350 if(macroblock_address >= mba_max)
351 {
352/* mba_inc points beyond picture dimensions */
353 /*fprintf(stderr, "mpeg3_decode_slice: too many macroblocks in picture\n"); */
354 return 1;
355 }
356
357/* not skipped */
358 if(mba_inc == 1)
359 {
360 mpeg3video_macroblock_modes(slice,
361 video,
362 &mb_type,
363 &stwtype,
364 &stwclass,
365 &motion_type,
366 &mv_count,
367 &mv_format,
368 &dmv,
369 &mvscale,
370 &dct_type);
371
372 if(slice->fault) return 1;
373
374 if(mb_type & MB_QUANT)
375 {
376 qs = mpeg3slice_getbits(slice_buffer, 5);
377
378 if(video->mpeg2)
379 slice->quant_scale = video->qscale_type ? mpeg3_non_linear_mquant_table[qs] : (qs << 1);
380 else
381 slice->quant_scale = qs;
382
383 if(video->scalable_mode == SC_DP)
384/* make sure quant_scale is valid */
385 slice->quant_scale = slice->quant_scale;
386 }
387
388/* motion vectors */
389
390
391/* decode forward motion vectors */
392 if((mb_type & MB_FORWARD) || ((mb_type & MB_INTRA) && video->conceal_mv))
393 {
394 if(video->mpeg2)
395 mpeg3video_motion_vectors(slice,
396 video,
397 pmv,
398 dmvector,
399 mv_field_sel,
400 0,
401 mv_count,
402 mv_format,
403 video->h_forw_r_size,
404 video->v_forw_r_size,
405 dmv,
406 mvscale);
407 else
408 mpeg3video_motion_vector(slice,
409 video,
410 pmv[0][0],
411 dmvector,
412 video->forw_r_size,
413 video->forw_r_size,
414 0,
415 0,
416 video->full_forw);
417 }
418 if(slice->fault) return 1;
419
420/* decode backward motion vectors */
421 if(mb_type & MB_BACKWARD)
422 {
423 if(video->mpeg2)
424 mpeg3video_motion_vectors(slice,
425 video,
426 pmv,
427 dmvector,
428 mv_field_sel,
429 1,
430 mv_count,
431 mv_format,
432 video->h_back_r_size,
433 video->v_back_r_size,
434 0,
435 mvscale);
436 else
437 mpeg3video_motion_vector(slice,
438 video,
439 pmv[0][1],
440 dmvector,
441 video->back_r_size,
442 video->back_r_size,
443 0,
444 0,
445 video->full_back);
446 }
447
448 if(slice->fault) return 1;
449
450/* remove marker_bit */
451 if((mb_type & MB_INTRA) && video->conceal_mv)
452 mpeg3slice_flushbit(slice_buffer);
453
454/* macroblock_pattern */
455 if(mb_type & MB_PATTERN)
456 {
457 cbp = mpeg3video_get_cbp(slice);
458 if(video->chroma_format == CHROMA422)
459 {
460/* coded_block_pattern_1 */
461 cbp = (cbp << 2) | mpeg3slice_getbits2(slice_buffer);
462 }
463 else
464 if(video->chroma_format == CHROMA444)
465 {
466/* coded_block_pattern_2 */
467 cbp = (cbp << 6) | mpeg3slice_getbits(slice_buffer, 6);
468 }
469 }
470 else
471 cbp = (mb_type & MB_INTRA) ? ((1 << video->blk_cnt) - 1) : 0;
472
473 if(slice->fault) return 1;
474/* decode blocks */
475 mpeg3video_clearblock(slice, 0, video->blk_cnt);
476 for(comp = 0; comp < video->blk_cnt; comp++)
477 {
478 if(cbp & (1 << (video->blk_cnt - comp - 1)))
479 {
480 if(mb_type & MB_INTRA)
481 {
482 if(video->mpeg2)
483 mpeg3video_getmpg2intrablock(slice, video, comp, dc_dct_pred);
484 else
485 mpeg3video_getintrablock(slice, video, comp, dc_dct_pred);
486 }
487 else
488 {
489 if(video->mpeg2)
490 mpeg3video_getmpg2interblock(slice, video, comp);
491 else
492 mpeg3video_getinterblock(slice, video, comp);
493 }
494 if(slice->fault) return 1;
495 }
496 }
497
498/* reset intra_dc predictors */
499 if(!(mb_type & MB_INTRA))
500 dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0;
501
502/* reset motion vector predictors */
503 if((mb_type & MB_INTRA) && !video->conceal_mv)
504 {
505/* intra mb without concealment motion vectors */
506 pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0;
507 pmv[0][1][0] = pmv[0][1][1] = pmv[1][1][0] = pmv[1][1][1] = 0;
508 }
509
510 if((video->pict_type == P_TYPE) && !(mb_type & (MB_FORWARD | MB_INTRA)))
511 {
512/* non-intra mb without forward mv in a P picture */
513 pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0;
514
515/* derive motion_type */
516 if(video->pict_struct == FRAME_PICTURE)
517 motion_type = MC_FRAME;
518 else
519 {
520 motion_type = MC_FIELD;
521/* predict from field of same parity */
522 mv_field_sel[0][0] = (video->pict_struct == BOTTOM_FIELD);
523 }
524 }
525
526 if(stwclass == 4)
527 {
528/* purely spatially predicted macroblock */
529 pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0;
530 pmv[0][1][0] = pmv[0][1][1] = pmv[1][1][0] = pmv[1][1][1] = 0;
531 }
532 }
533 else
534 {
535/* mba_inc!=1: skipped macroblock */
536 mpeg3video_clearblock(slice, 0, video->blk_cnt);
537
538/* reset intra_dc predictors */
539 dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0;
540
541/* reset motion vector predictors */
542 if(video->pict_type == P_TYPE)
543 pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0;
544
545/* derive motion_type */
546 if(video->pict_struct == FRAME_PICTURE)
547 motion_type = MC_FRAME;
548 else
549 {
550 motion_type = MC_FIELD;
551/* predict from field of same parity */
552 mv_field_sel[0][0] = mv_field_sel[0][1] = (video->pict_struct == BOTTOM_FIELD);
553 }
554
555/* skipped I are spatial-only predicted, */
556/* skipped P and B are temporal-only predicted */
557 stwtype = (video->pict_type == I_TYPE) ? 8 : 0;
558
559/* clear MB_INTRA */
560 mb_type &= ~MB_INTRA;
561
562/* no block data */
563 cbp = 0;
564 }
565
566 snr_cbp = 0;
567
568/* pixel coordinates of top left corner of current macroblock */
569 bx = 16 * (macroblock_address % video->mb_width);
570 by = 16 * (macroblock_address / video->mb_width);
571
572/* motion compensation */
573 if(!(mb_type & MB_INTRA))
574 mpeg3video_reconstruct(video,
575 bx,
576 by,
577 mb_type,
578 motion_type,
579 pmv,
580 mv_field_sel,
581 dmvector,
582 stwtype);
583
584/* copy or add block data into picture */
585 for(comp = 0; comp < video->blk_cnt; comp++)
586 {
587 if((cbp | snr_cbp) & (1 << (video->blk_cnt - 1 - comp)))
588 {
589#ifdef HAVE_MMX
590 if(video->have_mmx)
591 IDCT_mmx(slice->block[comp]);
592 else
593#endif
594 mpeg3video_idct_conversion(slice->block[comp]);
595
596 mpeg3video_addblock(slice,
597 video,
598 comp,
599 bx,
600 by,
601 dct_type,
602 (mb_type & MB_INTRA) == 0);
603 }
604 }
605
606/* advance to next macroblock */
607 macroblock_address++;
608 mba_inc--;
609 }
610
611 return 0;
612}
613
614void mpeg3_slice_loop(mpeg3_slice_t *slice)
615{
616 mpeg3video_t *video = slice->video;
617 int result = 1;
618
619 while(!slice->done)
620 {
621 pthread_mutex_lock(&(slice->input_lock));
622
623 if(!slice->done)
624 {
625/* Get a buffer to decode */
626 result = 1;
627 pthread_mutex_lock(&(video->slice_lock));
628 if(slice->buffer_step > 0)
629 {
630 while(slice->current_buffer <= slice->last_buffer)
631 {
632 if(!video->slice_buffers[slice->current_buffer].done &&
633 slice->current_buffer <= slice->last_buffer)
634 {
635 result = 0;
636 break;
637 }
638 slice->current_buffer += slice->buffer_step;
639 }
640 }
641 else
642 {
643 while(slice->current_buffer >= slice->last_buffer)
644 {
645 if(!video->slice_buffers[slice->current_buffer].done &&
646 slice->current_buffer >= slice->last_buffer)
647 {
648 result = 0;
649 break;
650 }
651 slice->current_buffer += slice->buffer_step;
652 }
653 }
654
655/* Got one */
656 if(!result && slice->current_buffer >= 0 && slice->current_buffer < video->total_slice_buffers)
657 {
658 slice->slice_buffer = &(video->slice_buffers[slice->current_buffer]);
659 slice->slice_buffer->done = 1;
660 pthread_mutex_unlock(&(video->slice_lock));
661 pthread_mutex_unlock(&(slice->input_lock));
662 mpeg3_decode_slice(slice);
663 pthread_mutex_unlock(&(slice->slice_buffer->completion_lock));
664 }
665 else
666 pthread_mutex_unlock(&(video->slice_lock));
667 }
668
669 pthread_mutex_unlock(&(slice->output_lock));
670 }
671}
672
673int mpeg3_new_slice_decoder(mpeg3video_t *video, mpeg3_slice_t *slice)
674{
675 pthread_attr_t attr;
676 //struct sched_param param;
677 pthread_mutexattr_t mutex_attr;
678
679 slice->video = video;
680 slice->done = 0;
681 pthread_mutexattr_init(&mutex_attr);
682 pthread_mutex_init(&(slice->input_lock), &mutex_attr);
683 pthread_mutex_lock(&(slice->input_lock));
684 pthread_mutex_init(&(slice->output_lock), &mutex_attr);
685 pthread_mutex_lock(&(slice->output_lock));
686
687 pthread_attr_init(&attr);
688 pthread_create(&(slice->tid), &attr,
689 (void * (*)(void *))mpeg3_slice_loop, slice);
690
691 return 0;
692}
693
694int mpeg3_delete_slice_decoder(mpeg3_slice_t *slice)
695{
696 slice->done = 1;
697 pthread_mutex_unlock(&(slice->input_lock));
698 pthread_join(slice->tid, 0);
699 pthread_mutex_destroy(&(slice->input_lock));
700 pthread_mutex_destroy(&(slice->output_lock));
701 return 0;
702}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef SLICE_H
21#define SLICE_H
22
23#ifndef _WIN32
24#include <pthread.h>
25#endif
26
27/* Array of these feeds the slice decoders */
28typedef struct
29{
30 unsigned char *data; /* Buffer for holding the slice data */
31 int buffer_size; /* Size of buffer */
32 int buffer_allocation; /* Space allocated for buffer */
33 int current_position; /* Position in buffer */
34 unsigned MPEG3_INT32 bits;
35 int bits_size;
36 pthread_mutex_t completion_lock; /* Lock slice until completion */
37 int done; /* Signal for slice decoder to skip */
38} mpeg3_slice_buffer_t;
39
40/* Each slice decoder */
41typedef struct
42{
43 struct mpeg3video_rec *video;
44 mpeg3_slice_buffer_t *slice_buffer;
45
46 int thread_number; /* Number of this thread */
47 int current_buffer; /* Buffer this slice decoder is on */
48 int buffer_step; /* Number of buffers to skip */
49 int last_buffer; /* Last buffer this decoder should process */
50 int fault;
51 int done;
52 int quant_scale;
53 int pri_brk; /* slice/macroblock */
54 short block[12][64];
55 int sparse[12];
56 pthread_t tid; /* ID of thread */
57 pthread_mutex_t input_lock, output_lock;
58} mpeg3_slice_t;
59
60#define mpeg3slice_fillbits(buffer, nbits) \
61 while(((mpeg3_slice_buffer_t*)(buffer))->bits_size < (nbits)) \
62 { \
63 if(((mpeg3_slice_buffer_t*)(buffer))->current_position < ((mpeg3_slice_buffer_t*)(buffer))->buffer_size) \
64 { \
65 ((mpeg3_slice_buffer_t*)(buffer))->bits <<= 8; \
66 ((mpeg3_slice_buffer_t*)(buffer))->bits |= ((mpeg3_slice_buffer_t*)(buffer))->data[((mpeg3_slice_buffer_t*)(buffer))->current_position++]; \
67 } \
68 ((mpeg3_slice_buffer_t*)(buffer))->bits_size += 8; \
69 }
70
71#define mpeg3slice_flushbits(buffer, nbits) \
72 { \
73 mpeg3slice_fillbits((buffer), (nbits)); \
74 ((mpeg3_slice_buffer_t*)(buffer))->bits_size -= (nbits); \
75 }
76
77#define mpeg3slice_flushbit(buffer) \
78{ \
79 if(((mpeg3_slice_buffer_t*)(buffer))->bits_size) \
80 ((mpeg3_slice_buffer_t*)(buffer))->bits_size--; \
81 else \
82 if(((mpeg3_slice_buffer_t*)(buffer))->current_position < ((mpeg3_slice_buffer_t*)(buffer))->buffer_size) \
83 { \
84 ((mpeg3_slice_buffer_t*)(buffer))->bits = \
85 ((mpeg3_slice_buffer_t*)(buffer))->data[((mpeg3_slice_buffer_t*)(buffer))->current_position++]; \
86 ((mpeg3_slice_buffer_t*)(buffer))->bits_size = 7; \
87 } \
88}
89
90extern inline unsigned int mpeg3slice_getbit(mpeg3_slice_buffer_t *buffer)
91{
92 if(buffer->bits_size)
93 return (buffer->bits >> (--buffer->bits_size)) & 0x1;
94 else
95 if(buffer->current_position < buffer->buffer_size)
96 {
97 buffer->bits = buffer->data[buffer->current_position++];
98 buffer->bits_size = 7;
99 return (buffer->bits >> 7) & 0x1;
100 }
101 return 0; // WWA - stop warn
102}
103
104extern inline unsigned int mpeg3slice_getbits2(mpeg3_slice_buffer_t *buffer)
105{
106 if(buffer->bits_size >= 2)
107 return (buffer->bits >> (buffer->bits_size -= 2)) & 0x3;
108 else
109 if(buffer->current_position < buffer->buffer_size)
110 {
111 buffer->bits <<= 8;
112 buffer->bits |= buffer->data[buffer->current_position++];
113 buffer->bits_size += 6;
114 return (buffer->bits >> buffer->bits_size) & 0x3;
115 }
116 return 0; // WWA - stop warn
117}
118
119extern inline unsigned int mpeg3slice_getbyte(mpeg3_slice_buffer_t *buffer)
120{
121 if(buffer->bits_size >= 8)
122 return (buffer->bits >> (buffer->bits_size -= 8)) & 0xff;
123 else
124 if(buffer->current_position < buffer->buffer_size)
125 {
126 buffer->bits <<= 8;
127 buffer->bits |= buffer->data[buffer->current_position++];
128 return (buffer->bits >> buffer->bits_size) & 0xff;
129 }
130 return 0; // WWA - stop warn
131}
132
133
134extern inline unsigned int mpeg3slice_getbits(mpeg3_slice_buffer_t *slice_buffer, int bits)
135{
136 if(bits == 1) return mpeg3slice_getbit(slice_buffer);
137 mpeg3slice_fillbits(slice_buffer, bits);
138 return (slice_buffer->bits >> (slice_buffer->bits_size -= bits)) & (0xffffffff >> (32 - bits));
139}
140
141extern inline unsigned int mpeg3slice_showbits16(mpeg3_slice_buffer_t *buffer)
142{
143 if(buffer->bits_size >= 16)
144 return (buffer->bits >> (buffer->bits_size - 16)) & 0xffff;
145 else
146 if(buffer->current_position < buffer->buffer_size)
147 {
148 buffer->bits <<= 16;
149 buffer->bits_size += 16;
150 buffer->bits |= (unsigned int)buffer->data[buffer->current_position++] << 8;
151 buffer->bits |= buffer->data[buffer->current_position++];
152 return (buffer->bits >> (buffer->bits_size - 16)) & 0xffff;
153 }
154 return 0; // WWA - stop warn
155}
156
157extern inline unsigned int mpeg3slice_showbits9(mpeg3_slice_buffer_t *buffer)
158{
159 if(buffer->bits_size >= 9)
160 return (buffer->bits >> (buffer->bits_size - 9)) & 0x1ff;
161 else
162 if(buffer->current_position < buffer->buffer_size)
163 {
164 buffer->bits <<= 16;
165 buffer->bits_size += 16;
166 buffer->bits |= (unsigned int)buffer->data[buffer->current_position++] << 8;
167 buffer->bits |= buffer->data[buffer->current_position++];
168 return (buffer->bits >> (buffer->bits_size - 9)) & 0x1ff;
169 }
170 return 0; // WWA - stop warn
171}
172
173extern inline unsigned int mpeg3slice_showbits5(mpeg3_slice_buffer_t *buffer)
174{
175 if(buffer->bits_size >= 5)
176 return (buffer->bits >> (buffer->bits_size - 5)) & 0x1f;
177 else
178 if(buffer->current_position < buffer->buffer_size)
179 {
180 buffer->bits <<= 8;
181 buffer->bits_size += 8;
182 buffer->bits |= buffer->data[buffer->current_position++];
183 return (buffer->bits >> (buffer->bits_size - 5)) & 0x1f;
184 }
185 return 0; // WWA - stop warn
186}
187
188extern inline unsigned int mpeg3slice_showbits(mpeg3_slice_buffer_t *slice_buffer, int bits)
189{
190 mpeg3slice_fillbits(slice_buffer, bits);
191 return (slice_buffer->bits >> (slice_buffer->bits_size - bits)) & (0xffffffff >> (32 - bits));
192}
193
194#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 @@
1#include "mpeg3video.h"
2#include "vlc.h"
3
4/* variable length code tables */
5
6/* Table B-3, mb_type in P-pictures, codes 001..1xx */
7mpeg3_VLCtab_t mpeg3_PMBtab0[8] = {
8 {ERROR,0},
9 {MB_FORWARD,3},
10 {MB_PATTERN,2}, {MB_PATTERN,2},
11 {MB_FORWARD|MB_PATTERN,1}, {MB_FORWARD|MB_PATTERN,1},
12 {MB_FORWARD|MB_PATTERN,1}, {MB_FORWARD|MB_PATTERN,1}
13};
14
15/* Table B-3, mb_type in P-pictures, codes 000001..00011x */
16mpeg3_VLCtab_t mpeg3_PMBtab1[8] = {
17 {ERROR,0},
18 {MB_QUANT|MB_INTRA,6},
19 {MB_QUANT|MB_PATTERN,5}, {MB_QUANT|MB_PATTERN,5},
20 {MB_QUANT|MB_FORWARD|MB_PATTERN,5}, {MB_QUANT|MB_FORWARD|MB_PATTERN,5},
21 {MB_INTRA,5}, {MB_INTRA,5}
22};
23
24/* Table B-4, mb_type in B-pictures, codes 0010..11xx */
25mpeg3_VLCtab_t mpeg3_BMBtab0[16] = {
26 {ERROR,0}, {ERROR,0},
27 {MB_FORWARD,4},
28 {MB_FORWARD|MB_PATTERN,4},
29 {MB_BACKWARD,3}, {MB_BACKWARD,3},
30 {MB_BACKWARD|MB_PATTERN,3}, {MB_BACKWARD|MB_PATTERN,3},
31 {MB_FORWARD|MB_BACKWARD,2}, {MB_FORWARD|MB_BACKWARD,2},
32 {MB_FORWARD|MB_BACKWARD,2}, {MB_FORWARD|MB_BACKWARD,2},
33 {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2},
34 {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2},
35 {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2},
36 {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2}
37};
38
39/* Table B-4, mb_type in B-pictures, codes 000001..00011x */
40mpeg3_VLCtab_t mpeg3_BMBtab1[8] = {
41 {ERROR,0},
42 {MB_QUANT|MB_INTRA,6},
43 {MB_QUANT|MB_BACKWARD|MB_PATTERN,6},
44 {MB_QUANT|MB_FORWARD|MB_PATTERN,6},
45 {MB_QUANT|MB_FORWARD|MB_BACKWARD|MB_PATTERN,5},
46 {MB_QUANT|MB_FORWARD|MB_BACKWARD|MB_PATTERN,5},
47 {MB_INTRA,5}, {MB_INTRA,5}
48};
49
50/* Table B-5, mb_type in spat. scal. I-pictures, codes 0001..1xxx */
51mpeg3_VLCtab_t mpeg3_spIMBtab[16] = {
52 {ERROR,0},
53 {MB_CLASS4,4},
54 {MB_QUANT|MB_INTRA,4},
55 {MB_INTRA,4},
56 {MB_CLASS4|MB_QUANT|MB_PATTERN,2}, {MB_CLASS4|MB_QUANT|MB_PATTERN,2},
57 {MB_CLASS4|MB_QUANT|MB_PATTERN,2}, {MB_CLASS4|MB_QUANT|MB_PATTERN,2},
58 {MB_CLASS4|MB_PATTERN,1}, {MB_CLASS4|MB_PATTERN,1},
59 {MB_CLASS4|MB_PATTERN,1}, {MB_CLASS4|MB_PATTERN,1},
60 {MB_CLASS4|MB_PATTERN,1}, {MB_CLASS4|MB_PATTERN,1},
61 {MB_CLASS4|MB_PATTERN,1}, {MB_CLASS4|MB_PATTERN,1}
62};
63
64/* Table B-6, mb_type in spat. scal. P-pictures, codes 0010..11xx */
65mpeg3_VLCtab_t mpeg3_spPMBtab0[16] =
66{
67 {ERROR,0},{ERROR,0},
68 {MB_FORWARD,4},
69 {MB_WEIGHT|MB_FORWARD,4},
70 {MB_QUANT|MB_FORWARD|MB_PATTERN,3}, {MB_QUANT|MB_FORWARD|MB_PATTERN,3},
71 {MB_WEIGHT|MB_FORWARD|MB_PATTERN,3}, {MB_WEIGHT|MB_FORWARD|MB_PATTERN,3},
72 {MB_FORWARD|MB_PATTERN,2}, {MB_FORWARD|MB_PATTERN,2},
73 {MB_FORWARD|MB_PATTERN,2}, {MB_FORWARD|MB_PATTERN,2},
74 {MB_WEIGHT|MB_QUANT|MB_FORWARD|MB_PATTERN,2},
75 {MB_WEIGHT|MB_QUANT|MB_FORWARD|MB_PATTERN,2},
76 {MB_WEIGHT|MB_QUANT|MB_FORWARD|MB_PATTERN,2},
77 {MB_WEIGHT|MB_QUANT|MB_FORWARD|MB_PATTERN,2}
78};
79
80/* Table B-6, mb_type in spat. scal. P-pictures, codes 0000010..000111x */
81mpeg3_VLCtab_t mpeg3_spPMBtab1[16] = {
82 {ERROR,0},{ERROR,0},
83 {MB_CLASS4|MB_QUANT|MB_PATTERN,7},
84 {MB_CLASS4,7},
85 {MB_PATTERN,7},
86 {MB_CLASS4|MB_PATTERN,7},
87 {MB_QUANT|MB_INTRA,7},
88 {MB_INTRA,7},
89 {MB_QUANT|MB_PATTERN,6}, {MB_QUANT|MB_PATTERN,6},
90 {MB_WEIGHT|MB_QUANT|MB_PATTERN,6}, {MB_WEIGHT|MB_QUANT|MB_PATTERN,6},
91 {MB_WEIGHT,6}, {MB_WEIGHT,6},
92 {MB_WEIGHT|MB_PATTERN,6}, {MB_WEIGHT|MB_PATTERN,6}
93};
94
95/* Table B-7, mb_type in spat. scal. B-pictures, codes 0010..11xx */
96mpeg3_VLCtab_t mpeg3_spBMBtab0[14] = {
97 {MB_FORWARD,4},
98 {MB_FORWARD|MB_PATTERN,4},
99 {MB_BACKWARD,3}, {MB_BACKWARD,3},
100 {MB_BACKWARD|MB_PATTERN,3}, {MB_BACKWARD|MB_PATTERN,3},
101 {MB_FORWARD|MB_BACKWARD,2}, {MB_FORWARD|MB_BACKWARD,2},
102 {MB_FORWARD|MB_BACKWARD,2}, {MB_FORWARD|MB_BACKWARD,2},
103 {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2},
104 {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2},
105 {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2},
106 {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2}
107};
108
109/* Table B-7, mb_type in spat. scal. B-pictures, codes 0000100..000111x */
110mpeg3_VLCtab_t mpeg3_spBMBtab1[12] = {
111 {MB_QUANT|MB_FORWARD|MB_PATTERN,7},
112 {MB_QUANT|MB_BACKWARD|MB_PATTERN,7},
113 {MB_INTRA,7},
114 {MB_QUANT|MB_FORWARD|MB_BACKWARD|MB_PATTERN,7},
115 {MB_WEIGHT|MB_FORWARD,6}, {MB_WEIGHT|MB_FORWARD,6},
116 {MB_WEIGHT|MB_FORWARD|MB_PATTERN,6}, {MB_WEIGHT|MB_FORWARD|MB_PATTERN,6},
117 {MB_WEIGHT|MB_BACKWARD,6}, {MB_WEIGHT|MB_BACKWARD,6},
118 {MB_WEIGHT|MB_BACKWARD|MB_PATTERN,6}, {MB_WEIGHT|MB_BACKWARD|MB_PATTERN,6}
119};
120
121/* Table B-7, mb_type in spat. scal. B-pictures, codes 00000100x..000001111 */
122mpeg3_VLCtab_t mpeg3_spBMBtab2[8] = {
123 {MB_QUANT|MB_INTRA,8}, {MB_QUANT|MB_INTRA,8},
124 {MB_WEIGHT|MB_QUANT|MB_FORWARD|MB_PATTERN,8},
125 {MB_WEIGHT|MB_QUANT|MB_FORWARD|MB_PATTERN,8},
126 {MB_WEIGHT|MB_QUANT|MB_BACKWARD|MB_PATTERN,9},
127 {MB_CLASS4|MB_QUANT|MB_PATTERN,9},
128 {MB_CLASS4,9},
129 {MB_CLASS4|MB_PATTERN,9}
130};
131
132/* Table B-8, mb_type in spat. scal. B-pictures, codes 001..1xx */
133mpeg3_VLCtab_t mpeg3_SNRMBtab[8] = {
134 {ERROR,0},
135 {0,3},
136 {MB_QUANT|MB_PATTERN,2}, {MB_QUANT|MB_PATTERN,2},
137 {MB_PATTERN,1}, {MB_PATTERN,1}, {MB_PATTERN,1}, {MB_PATTERN,1}
138};
139
140/* Table B-10, motion_code, codes 0001 ... 01xx */
141mpeg3_VLCtab_t mpeg3_MVtab0[8] =
142{ {ERROR,0}, {3,3}, {2,2}, {2,2}, {1,1}, {1,1}, {1,1}, {1,1}
143};
144
145/* Table B-10, motion_code, codes 0000011 ... 000011x */
146mpeg3_VLCtab_t mpeg3_MVtab1[8] =
147{ {ERROR,0}, {ERROR,0}, {ERROR,0}, {7,6}, {6,6}, {5,6}, {4,5}, {4,5}
148};
149
150/* Table B-10, motion_code, codes 0000001100 ... 000001011x */
151mpeg3_VLCtab_t mpeg3_MVtab2[12] =
152{ {16,9}, {15,9}, {14,9}, {13,9},
153 {12,9}, {11,9}, {10,8}, {10,8},
154 {9,8}, {9,8}, {8,8}, {8,8}
155};
156
157/* Table B-9, coded_block_pattern, codes 01000 ... 111xx */
158mpeg3_VLCtab_t mpeg3_CBPtab0[32] =
159{ {ERROR,0}, {ERROR,0}, {ERROR,0}, {ERROR,0},
160 {ERROR,0}, {ERROR,0}, {ERROR,0}, {ERROR,0},
161 {62,5}, {2,5}, {61,5}, {1,5}, {56,5}, {52,5}, {44,5}, {28,5},
162 {40,5}, {20,5}, {48,5}, {12,5}, {32,4}, {32,4}, {16,4}, {16,4},
163 {8,4}, {8,4}, {4,4}, {4,4}, {60,3}, {60,3}, {60,3}, {60,3}
164};
165
166/* Table B-9, coded_block_pattern, codes 00000100 ... 001111xx */
167mpeg3_VLCtab_t mpeg3_CBPtab1[64] =
168{ {ERROR,0}, {ERROR,0}, {ERROR,0}, {ERROR,0},
169 {58,8}, {54,8}, {46,8}, {30,8},
170 {57,8}, {53,8}, {45,8}, {29,8}, {38,8}, {26,8}, {37,8}, {25,8},
171 {43,8}, {23,8}, {51,8}, {15,8}, {42,8}, {22,8}, {50,8}, {14,8},
172 {41,8}, {21,8}, {49,8}, {13,8}, {35,8}, {19,8}, {11,8}, {7,8},
173 {34,7}, {34,7}, {18,7}, {18,7}, {10,7}, {10,7}, {6,7}, {6,7},
174 {33,7}, {33,7}, {17,7}, {17,7}, {9,7}, {9,7}, {5,7}, {5,7},
175 {63,6}, {63,6}, {63,6}, {63,6}, {3,6}, {3,6}, {3,6}, {3,6},
176 {36,6}, {36,6}, {36,6}, {36,6}, {24,6}, {24,6}, {24,6}, {24,6}
177};
178
179/* Table B-9, coded_block_pattern, codes 000000001 ... 000000111 */
180mpeg3_VLCtab_t mpeg3_CBPtab2[8] =
181{ {ERROR,0}, {0,9}, {39,9}, {27,9}, {59,9}, {55,9}, {47,9}, {31,9}
182};
183
184/* Table B-1, macroblock_address_increment, codes 00010 ... 011xx */
185mpeg3_VLCtab_t mpeg3_MBAtab1[16] =
186{ {ERROR,0}, {ERROR,0}, {7,5}, {6,5}, {5,4}, {5,4}, {4,4}, {4,4},
187 {3,3}, {3,3}, {3,3}, {3,3}, {2,3}, {2,3}, {2,3}, {2,3}
188};
189
190/* Table B-1, macroblock_address_increment, codes 00000011000 ... 0000111xxxx */
191mpeg3_VLCtab_t mpeg3_MBAtab2[104] =
192{
193 {33,11}, {32,11}, {31,11}, {30,11}, {29,11}, {28,11}, {27,11}, {26,11},
194 {25,11}, {24,11}, {23,11}, {22,11}, {21,10}, {21,10}, {20,10}, {20,10},
195 {19,10}, {19,10}, {18,10}, {18,10}, {17,10}, {17,10}, {16,10}, {16,10},
196 {15,8}, {15,8}, {15,8}, {15,8}, {15,8}, {15,8}, {15,8}, {15,8},
197 {14,8}, {14,8}, {14,8}, {14,8}, {14,8}, {14,8}, {14,8}, {14,8},
198 {13,8}, {13,8}, {13,8}, {13,8}, {13,8}, {13,8}, {13,8}, {13,8},
199 {12,8}, {12,8}, {12,8}, {12,8}, {12,8}, {12,8}, {12,8}, {12,8},
200 {11,8}, {11,8}, {11,8}, {11,8}, {11,8}, {11,8}, {11,8}, {11,8},
201 {10,8}, {10,8}, {10,8}, {10,8}, {10,8}, {10,8}, {10,8}, {10,8},
202 {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7},
203 {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7},
204 {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7},
205 {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}
206};
207
208/* Table B-12, dct_dc_size_luminance, codes 00xxx ... 11110 */
209mpeg3_VLCtab_t mpeg3_DClumtab0[32] =
210{ {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2},
211 {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2},
212 {0, 3}, {0, 3}, {0, 3}, {0, 3}, {3, 3}, {3, 3}, {3, 3}, {3, 3},
213 {4, 3}, {4, 3}, {4, 3}, {4, 3}, {5, 4}, {5, 4}, {6, 5}, {ERROR, 0}
214};
215
216/* Table B-12, dct_dc_size_luminance, codes 111110xxx ... 111111111 */
217mpeg3_VLCtab_t mpeg3_DClumtab1[16] =
218{ {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6},
219 {8, 7}, {8, 7}, {8, 7}, {8, 7}, {9, 8}, {9, 8}, {10,9}, {11,9}
220};
221
222/* Table B-13, dct_dc_size_chrominance, codes 00xxx ... 11110 */
223mpeg3_VLCtab_t mpeg3_DCchromtab0[32] =
224{ {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2},
225 {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2},
226 {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2},
227 {3, 3}, {3, 3}, {3, 3}, {3, 3}, {4, 4}, {4, 4}, {5, 5}, {ERROR, 0}
228};
229
230/* Table B-13, dct_dc_size_chrominance, codes 111110xxxx ... 1111111111 */
231mpeg3_VLCtab_t mpeg3_DCchromtab1[32] =
232{ {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6},
233 {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6},
234 {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7},
235 {8, 8}, {8, 8}, {8, 8}, {8, 8}, {9, 9}, {9, 9}, {10,10}, {11,10}
236};
237
238/* Table B-14, DCT coefficients table zero,
239 * codes 0100 ... 1xxx (used for first (DC) coefficient)
240 */
241mpeg3_DCTtab_t mpeg3_DCTtabfirst[12] =
242{
243 {0,2,4}, {2,1,4}, {1,1,3}, {1,1,3},
244 {0,1,1}, {0,1,1}, {0,1,1}, {0,1,1},
245 {0,1,1}, {0,1,1}, {0,1,1}, {0,1,1}
246};
247
248/* Table B-14, DCT coefficients table zero,
249 * codes 0100 ... 1xxx (used for all other coefficients)
250 */
251mpeg3_DCTtab_t mpeg3_DCTtabnext[12] =
252{
253 {0,2,4}, {2,1,4}, {1,1,3}, {1,1,3},
254 {64,0,2}, {64,0,2}, {64,0,2}, {64,0,2}, /* EOB */
255 {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}
256};
257
258/* Table B-14, DCT coefficients table zero,
259 * codes 000001xx ... 00111xxx
260 */
261mpeg3_DCTtab_t mpeg3_DCTtab0[60] =
262{
263 {65,0,6}, {65,0,6}, {65,0,6}, {65,0,6}, /* Escape */
264 {2,2,7}, {2,2,7}, {9,1,7}, {9,1,7},
265 {0,4,7}, {0,4,7}, {8,1,7}, {8,1,7},
266 {7,1,6}, {7,1,6}, {7,1,6}, {7,1,6},
267 {6,1,6}, {6,1,6}, {6,1,6}, {6,1,6},
268 {1,2,6}, {1,2,6}, {1,2,6}, {1,2,6},
269 {5,1,6}, {5,1,6}, {5,1,6}, {5,1,6},
270 {13,1,8}, {0,6,8}, {12,1,8}, {11,1,8},
271 {3,2,8}, {1,3,8}, {0,5,8}, {10,1,8},
272 {0,3,5}, {0,3,5}, {0,3,5}, {0,3,5},
273 {0,3,5}, {0,3,5}, {0,3,5}, {0,3,5},
274 {4,1,5}, {4,1,5}, {4,1,5}, {4,1,5},
275 {4,1,5}, {4,1,5}, {4,1,5}, {4,1,5},
276 {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5},
277 {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5}
278};
279
280/* Table B-15, DCT coefficients table one,
281 * codes 000001xx ... 11111111
282*/
283mpeg3_DCTtab_t mpeg3_DCTtab0a[252] =
284{
285 {65,0,6}, {65,0,6}, {65,0,6}, {65,0,6}, /* Escape */
286 {7,1,7}, {7,1,7}, {8,1,7}, {8,1,7},
287 {6,1,7}, {6,1,7}, {2,2,7}, {2,2,7},
288 {0,7,6}, {0,7,6}, {0,7,6}, {0,7,6},
289 {0,6,6}, {0,6,6}, {0,6,6}, {0,6,6},
290 {4,1,6}, {4,1,6}, {4,1,6}, {4,1,6},
291 {5,1,6}, {5,1,6}, {5,1,6}, {5,1,6},
292 {1,5,8}, {11,1,8}, {0,11,8}, {0,10,8},
293 {13,1,8}, {12,1,8}, {3,2,8}, {1,4,8},
294 {2,1,5}, {2,1,5}, {2,1,5}, {2,1,5},
295 {2,1,5}, {2,1,5}, {2,1,5}, {2,1,5},
296 {1,2,5}, {1,2,5}, {1,2,5}, {1,2,5},
297 {1,2,5}, {1,2,5}, {1,2,5}, {1,2,5},
298 {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5},
299 {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5},
300 {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
301 {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
302 {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
303 {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
304 {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
305 {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
306 {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
307 {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
308 {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, /* EOB */
309 {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4},
310 {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4},
311 {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4},
312 {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4},
313 {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4},
314 {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4},
315 {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4},
316 {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
317 {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
318 {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
319 {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
320 {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
321 {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
322 {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
323 {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
324 {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
325 {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
326 {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
327 {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
328 {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
329 {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
330 {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
331 {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
332 {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
333 {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
334 {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
335 {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
336 {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
337 {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
338 {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
339 {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
340 {0,4,5}, {0,4,5}, {0,4,5}, {0,4,5},
341 {0,4,5}, {0,4,5}, {0,4,5}, {0,4,5},
342 {0,5,5}, {0,5,5}, {0,5,5}, {0,5,5},
343 {0,5,5}, {0,5,5}, {0,5,5}, {0,5,5},
344 {9,1,7}, {9,1,7}, {1,3,7}, {1,3,7},
345 {10,1,7}, {10,1,7}, {0,8,7}, {0,8,7},
346 {0,9,7}, {0,9,7}, {0,12,8}, {0,13,8},
347 {2,3,8}, {4,2,8}, {0,14,8}, {0,15,8}
348};
349
350/* Table B-14, DCT coefficients table zero,
351 * codes 0000001000 ... 0000001111
352 */
353mpeg3_DCTtab_t mpeg3_DCTtab1[8] =
354{
355 {16,1,10}, {5,2,10}, {0,7,10}, {2,3,10},
356 {1,4,10}, {15,1,10}, {14,1,10}, {4,2,10}
357};
358
359/* Table B-15, DCT coefficients table one,
360 * codes 000000100x ... 000000111x
361 */
362mpeg3_DCTtab_t mpeg3_DCTtab1a[8] =
363{
364 {5,2,9}, {5,2,9}, {14,1,9}, {14,1,9},
365 {2,4,10}, {16,1,10}, {15,1,9}, {15,1,9}
366};
367
368/* Table B-14/15, DCT coefficients table zero / one,
369 * codes 000000010000 ... 000000011111
370 */
371mpeg3_DCTtab_t mpeg3_DCTtab2[16] =
372{
373 {0,11,12}, {8,2,12}, {4,3,12}, {0,10,12},
374 {2,4,12}, {7,2,12}, {21,1,12}, {20,1,12},
375 {0,9,12}, {19,1,12}, {18,1,12}, {1,5,12},
376 {3,3,12}, {0,8,12}, {6,2,12}, {17,1,12}
377};
378
379/* Table B-14/15, DCT coefficients table zero / one,
380 * codes 0000000010000 ... 0000000011111
381 */
382mpeg3_DCTtab_t mpeg3_DCTtab3[16] =
383{
384 {10,2,13}, {9,2,13}, {5,3,13}, {3,4,13},
385 {2,5,13}, {1,7,13}, {1,6,13}, {0,15,13},
386 {0,14,13}, {0,13,13}, {0,12,13}, {26,1,13},
387 {25,1,13}, {24,1,13}, {23,1,13}, {22,1,13}
388};
389
390/* Table B-14/15, DCT coefficients table zero / one,
391 * codes 00000000010000 ... 00000000011111
392 */
393mpeg3_DCTtab_t mpeg3_DCTtab4[16] =
394{
395 {0,31,14}, {0,30,14}, {0,29,14}, {0,28,14},
396 {0,27,14}, {0,26,14}, {0,25,14}, {0,24,14},
397 {0,23,14}, {0,22,14}, {0,21,14}, {0,20,14},
398 {0,19,14}, {0,18,14}, {0,17,14}, {0,16,14}
399};
400
401/* Table B-14/15, DCT coefficients table zero / one,
402 * codes 000000000010000 ... 000000000011111
403 */
404mpeg3_DCTtab_t mpeg3_DCTtab5[16] =
405{
406 {0,40,15}, {0,39,15}, {0,38,15}, {0,37,15},
407 {0,36,15}, {0,35,15}, {0,34,15}, {0,33,15},
408 {0,32,15}, {1,14,15}, {1,13,15}, {1,12,15},
409 {1,11,15}, {1,10,15}, {1,9,15}, {1,8,15}
410};
411
412/* Table B-14/15, DCT coefficients table zero / one,
413 * codes 0000000000010000 ... 0000000000011111
414 */
415mpeg3_DCTtab_t mpeg3_DCTtab6[16] =
416{
417 {1,18,16}, {1,17,16}, {1,16,16}, {1,15,16},
418 {6,3,16}, {16,2,16}, {15,2,16}, {14,2,16},
419 {13,2,16}, {12,2,16}, {11,2,16}, {31,1,16},
420 {30,1,16}, {29,1,16}, {28,1,16}, {27,1,16}
421};
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef VLC_H
21#define VLC_H
22
23/* variable length code tables */
24
25typedef struct {
26 char val, len;
27} mpeg3_VLCtab_t;
28
29typedef struct {
30 char run, level, len;
31} mpeg3_DCTtab_t;
32
33/* Added 03/38/96 by Alex de Jong : avoid IRIX GNU warning */
34#ifdef ERROR
35#undef ERROR
36#define ERROR 99
37#endif
38
39/* Table B-3, mb_type in P-pictures, codes 001..1xx */
40extern mpeg3_VLCtab_t mpeg3_PMBtab0[8];
41
42/* Table B-3, mb_type in P-pictures, codes 000001..00011x */
43extern mpeg3_VLCtab_t mpeg3_PMBtab1[8];
44
45/* Table B-4, mb_type in B-pictures, codes 0010..11xx */
46extern mpeg3_VLCtab_t mpeg3_BMBtab0[16];
47
48/* Table B-4, mb_type in B-pictures, codes 000001..00011x */
49extern mpeg3_VLCtab_t mpeg3_BMBtab1[8];
50
51/* Table B-5, mb_type in spat. scal. I-pictures, codes 0001..1xxx */
52extern mpeg3_VLCtab_t mpeg3_spIMBtab[16];
53
54/* Table B-6, mb_type in spat. scal. P-pictures, codes 0010..11xx */
55extern mpeg3_VLCtab_t mpeg3_spPMBtab0[16];
56
57/* Table B-6, mb_type in spat. scal. P-pictures, codes 0000010..000111x */
58extern mpeg3_VLCtab_t mpeg3_spPMBtab1[16];
59
60/* Table B-7, mb_type in spat. scal. B-pictures, codes 0010..11xx */
61extern mpeg3_VLCtab_t mpeg3_spBMBtab0[14];
62
63/* Table B-7, mb_type in spat. scal. B-pictures, codes 0000100..000111x */
64extern mpeg3_VLCtab_t mpeg3_spBMBtab1[12];
65
66/* Table B-7, mb_type in spat. scal. B-pictures, codes 00000100x..000001111 */
67extern mpeg3_VLCtab_t mpeg3_spBMBtab2[8];
68
69/* Table B-8, mb_type in spat. scal. B-pictures, codes 001..1xx */
70extern mpeg3_VLCtab_t mpeg3_SNRMBtab[8];
71
72/* Table B-10, motion_code, codes 0001 ... 01xx */
73extern mpeg3_VLCtab_t mpeg3_MVtab0[8];
74
75/* Table B-10, motion_code, codes 0000011 ... 000011x */
76extern mpeg3_VLCtab_t mpeg3_MVtab1[8];
77
78/* Table B-10, motion_code, codes 0000001100 ... 000001011x */
79extern mpeg3_VLCtab_t mpeg3_MVtab2[12];
80
81/* Table B-9, coded_block_pattern, codes 01000 ... 111xx */
82extern mpeg3_VLCtab_t mpeg3_CBPtab0[32];
83
84/* Table B-9, coded_block_pattern, codes 00000100 ... 001111xx */
85extern mpeg3_VLCtab_t mpeg3_CBPtab1[64];
86
87/* Table B-9, coded_block_pattern, codes 000000001 ... 000000111 */
88extern mpeg3_VLCtab_t mpeg3_CBPtab2[8];
89
90/* Table B-1, macroblock_address_increment, codes 00010 ... 011xx */
91extern mpeg3_VLCtab_t mpeg3_MBAtab1[16];
92
93/* Table B-1, macroblock_address_increment, codes 00000011000 ... 0000111xxxx */
94extern mpeg3_VLCtab_t mpeg3_MBAtab2[104];
95
96/* Table B-12, dct_dc_size_luminance, codes 00xxx ... 11110 */
97extern mpeg3_VLCtab_t mpeg3_DClumtab0[32];
98
99/* Table B-12, dct_dc_size_luminance, codes 111110xxx ... 111111111 */
100extern mpeg3_VLCtab_t mpeg3_DClumtab1[16];
101
102/* Table B-13, dct_dc_size_chrominance, codes 00xxx ... 11110 */
103extern mpeg3_VLCtab_t mpeg3_DCchromtab0[32];
104
105/* Table B-13, dct_dc_size_chrominance, codes 111110xxxx ... 1111111111 */
106extern mpeg3_VLCtab_t mpeg3_DCchromtab1[32];
107
108/* Table B-14, DCT coefficients table zero,
109 * codes 0100 ... 1xxx (used for first (DC) coefficient)
110 */
111extern mpeg3_DCTtab_t mpeg3_DCTtabfirst[12];
112
113/* Table B-14, DCT coefficients table zero,
114 * codes 0100 ... 1xxx (used for all other coefficients)
115 */
116extern mpeg3_DCTtab_t mpeg3_DCTtabnext[12];
117
118/* Table B-14, DCT coefficients table zero,
119 * codes 000001xx ... 00111xxx
120 */
121extern mpeg3_DCTtab_t mpeg3_DCTtab0[60];
122
123/* Table B-15, DCT coefficients table one,
124 * codes 000001xx ... 11111111
125*/
126extern mpeg3_DCTtab_t mpeg3_DCTtab0a[252];
127
128/* Table B-14, DCT coefficients table zero,
129 * codes 0000001000 ... 0000001111
130 */
131extern mpeg3_DCTtab_t mpeg3_DCTtab1[8];
132
133/* Table B-15, DCT coefficients table one,
134 * codes 000000100x ... 000000111x
135 */
136extern mpeg3_DCTtab_t mpeg3_DCTtab1a[8];
137
138/* Table B-14/15, DCT coefficients table zero / one,
139 * codes 000000010000 ... 000000011111
140 */
141extern mpeg3_DCTtab_t mpeg3_DCTtab2[16];
142
143/* Table B-14/15, DCT coefficients table zero / one,
144 * codes 0000000010000 ... 0000000011111
145 */
146extern mpeg3_DCTtab_t mpeg3_DCTtab3[16];
147
148/* Table B-14/15, DCT coefficients table zero / one,
149 * codes 00000000010000 ... 00000000011111
150 */
151extern mpeg3_DCTtab_t mpeg3_DCTtab4[16];
152
153/* Table B-14/15, DCT coefficients table zero / one,
154 * codes 000000000010000 ... 000000000011111
155 */
156extern mpeg3_DCTtab_t mpeg3_DCTtab5[16];
157
158/* Table B-14/15, DCT coefficients table zero / one,
159 * codes 0000000000010000 ... 0000000000011111
160 */
161extern mpeg3_DCTtab_t mpeg3_DCTtab6[16];
162
163
164#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 @@
1#include <stdio.h>
2#include <stdlib.h>
3#include <time.h>
4
5
6static LONGLONG mpeg3_MMX_601_Y_COEF = 0x0000004000400040;
7
8inline void mpeg3_601_mmx(unsigned long y,
9 unsigned long *output)
10{
11asm("
12/* Output will be 0x00rrggbb */
13 movd (%0), %%mm0; /* Load y 0x00000000000000yy */
14 /*pmullw mpeg3_MMX_601_Y_COEF, %%mm0; // Scale y 0x00000000000000yy */
15 psllw $6, %%mm0; /* Shift y coeffs 0x0000yyy0yyy0yyy0 */
16 movd %%mm0, (%1); /* Store output */
17 "
18:
19: "r" (&y), "r" (output));
20}
21
22
23int main(int argc, char *argv[])
24{
25 unsigned char output[1024];
26
27 memset(output, 0, 1024);
28 mpeg3_601_mmx(1, (unsigned long*)output);
29 printf("%02x%02x\n", *(unsigned char*)&output[1], *(unsigned char*)&output[0]);
30}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#include <qpe/qpeapplication.h>
21#ifdef Q_WS_QWS
22#include <qpe/qcopenvelope_qws.h>
23#endif
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27#include <pthread.h>
28#include <errno.h>
29#include <unistd.h>
30#include "loopcontrol.h"
31#include "videowidget.h"
32#include "audiodevice.h"
33#include "mediaplayerplugininterface.h"
34#include "mediaplayerstate.h"
35
36
37extern VideoWidget *videoUI; // now only needed to tell it to play a frame
38extern MediaPlayerState *mediaPlayerState;
39
40
41//#define DecodeLoopDebug(x) qDebug x
42#define DecodeLoopDebug(x)
43
44
45 static char *audioBuffer = NULL;
46static AudioDevice *audioDevice = NULL;
47 static bool disabledSuspendScreenSaver = FALSE;
48 static bool previousSuspendMode = FALSE;
49
50
51 pthread_taudio_tid;
52pthread_attr_t audio_attr;
53bool threadOkToGo = FALSE;
54
55
56class Mutex {
57public:
58 Mutex() {
59 pthread_mutexattr_t attr;
60 pthread_mutexattr_init( &attr );
61 pthread_mutex_init( &mutex, &attr );
62 pthread_mutexattr_destroy( &attr );
63 }
64
65 ~Mutex() {
66 pthread_mutex_destroy( &mutex );
67 }
68
69 void lock() {
70 pthread_mutex_lock( &mutex );
71 }
72
73 void unlock() {
74 pthread_mutex_unlock( &mutex );
75 }
76private:
77 pthread_mutex_t mutex;
78};
79
80
81void *startAudioThread( void *ptr ) {
82 LoopControl *mpegView = (LoopControl *)ptr;
83 while ( TRUE ) {
84 if ( threadOkToGo && mpegView->moreAudio )
85 mpegView->startAudio();
86 else
87 usleep( 10000 ); // Semi-buzy-wait till we are playing again
88 }
89 return 0;
90}
91
92
93Mutex *audioMutex;
94
95
96LoopControl::LoopControl( QObject *parent, const char *name )
97 : QObject( parent, name ) {
98 isMuted = FALSE;
99 connect( qApp, SIGNAL( volumeChanged(bool) ), this, SLOT( setMute(bool) ) );
100
101 audioMutex = new Mutex;
102
103 pthread_attr_init(&audio_attr);
104#define USE_REALTIME_AUDIO_THREAD
105#ifdef USE_REALTIME_AUDIO_THREAD
106 // Attempt to set it to real-time round robin
107 if ( pthread_attr_setschedpolicy( &audio_attr, SCHED_RR ) == 0 ) {
108 sched_param params;
109 params.sched_priority = 50;
110 pthread_attr_setschedparam(&audio_attr,&params);
111 } else {
112 qDebug( "Error setting up a realtime thread, reverting to using a normal thread." );
113 pthread_attr_destroy(&audio_attr);
114 pthread_attr_init(&audio_attr);
115 }
116#endif
117 pthread_create(&audio_tid, &audio_attr, (void * (*)(void *))startAudioThread, this);
118}
119
120
121LoopControl::~LoopControl() {
122 stop();
123}
124
125
126static long prev_frame = 0;
127static int currentSample = 0;
128
129
130void LoopControl::timerEvent( QTimerEvent *te ) {
131
132 if ( te->timerId() == videoId )
133 startVideo();
134
135 if ( te->timerId() == sliderId ) {
136 if ( hasAudioChannel && !hasVideoChannel && moreAudio ) {
137 mediaPlayerState->updatePosition( audioSampleCounter );
138 } else if ( hasVideoChannel && moreVideo ) {
139 mediaPlayerState->updatePosition( current_frame );
140 }
141 }
142
143 if ( !moreVideo && !moreAudio ) {
144 mediaPlayerState->setPlaying( FALSE );
145 mediaPlayerState->setNext();
146 }
147}
148
149
150void LoopControl::setPosition( long pos ) {
151 audioMutex->lock();
152
153 if ( hasVideoChannel && hasAudioChannel ) {
154 playtime.restart();
155 playtime = playtime.addMSecs( long((double)-pos * 1000.0 / framerate) );
156 current_frame = pos + 1;
157 mediaPlayerState->curDecoder()->videoSetFrame( current_frame, stream );
158 prev_frame = current_frame - 1;
159 currentSample = (int)( (double)current_frame * freq / framerate );
160 mediaPlayerState->curDecoder()->audioSetSample( currentSample, stream );
161 audioSampleCounter = currentSample - 1;
162 } else if ( hasVideoChannel ) {
163 playtime.restart();
164 playtime = playtime.addMSecs( long((double)-pos * 1000.0 / framerate) );
165 current_frame = pos + 1;
166 mediaPlayerState->curDecoder()->videoSetFrame( current_frame, stream );
167 prev_frame = current_frame - 1;
168 } else if ( hasAudioChannel ) {
169 playtime.restart();
170 playtime = playtime.addMSecs( long((double)-pos * 1000.0 / freq) );
171 currentSample = pos + 1;
172 mediaPlayerState->curDecoder()->audioSetSample( currentSample, stream );
173 audioSampleCounter = currentSample - 1;
174 }
175
176 audioMutex->unlock();
177}
178
179
180void LoopControl::startVideo() {
181
182 if ( moreVideo ) {
183
184 if ( mediaPlayerState->curDecoder() ) {
185
186 if ( hasAudioChannel && !isMuted ) {
187
188 current_frame = long( playtime.elapsed() * framerate / 1000 );
189
190 if ( prev_frame != -1 && current_frame <= prev_frame )
191 return;
192
193 } else {
194 // Don't skip
195 current_frame++;
196 }
197
198 if ( prev_frame == -1 || current_frame > prev_frame ) {
199 if ( current_frame > prev_frame + 1 ) {
200 mediaPlayerState->curDecoder()->videoSetFrame( current_frame, stream );
201 }
202 moreVideo = videoUI->playVideo();
203 prev_frame = current_frame;
204 }
205
206 } else {
207
208 moreVideo = FALSE;
209 killTimer( videoId );
210
211 }
212
213 }
214}
215
216
217void LoopControl::startAudio() {
218
219 audioMutex->lock();
220
221 if ( moreAudio ) {
222
223 if ( !isMuted && mediaPlayerState->curDecoder() ) {
224
225 currentSample = audioSampleCounter + 1;
226
227 if ( currentSample != audioSampleCounter + 1 )
228 qDebug("out of sync with decoder %i %i", currentSample, audioSampleCounter);
229
230 long samplesRead = 0;
231 mediaPlayerState->curDecoder()->audioReadSamples( (short*)audioBuffer, channels, 1024, samplesRead, stream );
232 long sampleWeShouldBeAt = long( playtime.elapsed() ) * freq / 1000;
233 long sampleWaitTime = currentSample - sampleWeShouldBeAt;
234
235 if ( ( sampleWaitTime > 2000 ) && ( sampleWaitTime < 20000 ) ) {
236 usleep( (long)((double)sampleWaitTime * 1000000.0 / freq) );
237 } else if ( sampleWaitTime <= -5000 ) {
238 qDebug("need to catch up by: %li (%i,%li)", -sampleWaitTime, currentSample, sampleWeShouldBeAt );
239 //mediaPlayerState->curDecoder()->audioSetSample( sampleWeShouldBeAt, stream );
240 currentSample = sampleWeShouldBeAt;
241 }
242
243 audioDevice->write( audioBuffer, samplesRead * 2 * channels );
244 audioSampleCounter = currentSample + samplesRead - 1;
245
246 moreAudio = audioSampleCounter <= total_audio_samples;
247
248 } else {
249
250 moreAudio = FALSE;
251
252 }
253
254 }
255
256 audioMutex->unlock();
257}
258
259
260void LoopControl::killTimers() {
261
262 audioMutex->lock();
263
264 if ( hasVideoChannel )
265 killTimer( videoId );
266 killTimer( sliderId );
267 threadOkToGo = FALSE;
268
269 audioMutex->unlock();
270}
271
272
273void LoopControl::startTimers() {
274
275 audioMutex->lock();
276
277 moreVideo = FALSE;
278 moreAudio = FALSE;
279
280 if ( hasVideoChannel ) {
281 moreVideo = TRUE;
282 int mSecsBetweenFrames = (int)(100 / framerate); // 10% of the real value
283 videoId = startTimer( mSecsBetweenFrames );
284 }
285
286 if ( hasAudioChannel ) {
287 moreAudio = TRUE;
288 threadOkToGo = TRUE;
289 }
290
291 sliderId = startTimer( 300 ); // update slider every 1/3 second
292
293 audioMutex->unlock();
294}
295
296
297void LoopControl::setPaused( bool pause ) {
298
299 if ( !mediaPlayerState->curDecoder() || !mediaPlayerState->curDecoder()->isOpen() )
300 return;
301
302 if ( pause ) {
303 killTimers();
304 } else {
305 // Force an update of the position
306 mediaPlayerState->setPosition( mediaPlayerState->position() + 1 );
307 mediaPlayerState->setPosition( mediaPlayerState->position() - 1 );
308 // Just like we never stopped
309 startTimers();
310 }
311}
312
313
314void LoopControl::stop( bool willPlayAgainShortly ) {
315
316#if defined(Q_WS_QWS) && !defined(QT_NO_COP)
317 if ( !willPlayAgainShortly && disabledSuspendScreenSaver ) {
318 disabledSuspendScreenSaver = FALSE;
319 // Re-enable the suspend mode
320 QCopEnvelope("QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::Enable;
321 }
322#endif
323
324 if ( mediaPlayerState->curDecoder() && mediaPlayerState->curDecoder()->isOpen() ) {
325
326 killTimers();
327
328 audioMutex->lock();
329
330 mediaPlayerState->curDecoder()->close();
331
332 if ( audioDevice ) {
333 delete audioDevice;
334 delete audioBuffer;
335 audioDevice = 0;
336 audioBuffer = 0;
337 }
338
339 audioMutex->unlock();
340
341 }
342}
343
344
345bool LoopControl::init( const QString& filename ) {
346 stop();
347
348 audioMutex->lock();
349
350 fileName = filename;
351 stream = 0; // only play stream 0 for now
352 current_frame = total_video_frames = total_audio_samples = 0;
353
354 qDebug( "Using the %s decoder", mediaPlayerState->curDecoder()->pluginName() );
355
356 // ### Hack to use libmpeg3plugin to get the number of audio samples if we are using the libmad plugin
357 if ( mediaPlayerState->curDecoder()->pluginName() == QString("LibMadPlugin") ) {
358 if ( mediaPlayerState->libMpeg3Decoder() && mediaPlayerState->libMpeg3Decoder()->open( filename ) ) {
359 total_audio_samples = mediaPlayerState->libMpeg3Decoder()->audioSamples( 0 );
360 mediaPlayerState->libMpeg3Decoder()->close();
361 }
362 }
363
364 if ( !mediaPlayerState->curDecoder()|| !mediaPlayerState->curDecoder()->open( filename ) ) {
365 audioMutex->unlock();
366 return FALSE;
367 }
368
369 hasAudioChannel = mediaPlayerState->curDecoder()->audioStreams() > 0;
370 hasVideoChannel = mediaPlayerState->curDecoder()->videoStreams() > 0;
371
372 if ( hasAudioChannel ) {
373 int astream = 0;
374
375 channels = mediaPlayerState->curDecoder()->audioChannels( astream );
376 DecodeLoopDebug(( "channels = %d\n", channels ));
377
378 if ( !total_audio_samples )
379 total_audio_samples = mediaPlayerState->curDecoder()->audioSamples( astream );
380
381 total_audio_samples += 1000;
382
383 mediaPlayerState->setLength( total_audio_samples );
384
385 freq = mediaPlayerState->curDecoder()->audioFrequency( astream );
386 DecodeLoopDebug(( "frequency = %d\n", freq ));
387
388 audioSampleCounter = 0;
389
390 static const int bytes_per_sample = 2; //16 bit
391
392 audioDevice = new AudioDevice( freq, channels, bytes_per_sample );
393 audioBuffer = new char[ audioDevice->bufferSize() ];
394 channels = audioDevice->channels();
395
396 //### must check which frequency is actually used.
397 static const int size = 1;
398 short int buf[size];
399 long samplesRead = 0;
400 mediaPlayerState->curDecoder()->audioReadSamples( buf, channels, size, samplesRead, stream );
401 }
402
403 if ( hasVideoChannel ) {
404 total_video_frames = mediaPlayerState->curDecoder()->videoFrames( stream );
405
406 mediaPlayerState->setLength( total_video_frames );
407
408 framerate = mediaPlayerState->curDecoder()->videoFrameRate( stream );
409 DecodeLoopDebug(( "Frame rate %g total %ld", framerate, total_video_frames ));
410
411 if ( framerate <= 1.0 ) {
412 DecodeLoopDebug(( "Crazy frame rate, resetting to sensible" ));
413 framerate = 25;
414 }
415
416 if ( total_video_frames == 1 ) {
417 DecodeLoopDebug(( "Cannot seek to frame" ));
418 }
419
420 }
421
422 current_frame = 0;
423 prev_frame = -1;
424
425 connect( mediaPlayerState, SIGNAL( positionChanged( long ) ), this, SLOT( setPosition( long ) ) );
426 connect( mediaPlayerState, SIGNAL( pausedToggled( bool ) ), this, SLOT( setPaused( bool ) ) );
427
428 audioMutex->unlock();
429
430 return TRUE;
431}
432
433
434void LoopControl::play() {
435
436#if defined(Q_WS_QWS) && !defined(QT_NO_COP)
437 if ( !disabledSuspendScreenSaver || previousSuspendMode != hasVideoChannel ) {
438 disabledSuspendScreenSaver = TRUE;
439 previousSuspendMode = hasVideoChannel;
440 // Stop the screen from blanking and power saving state
441 QCopEnvelope("QPE/System", "setScreenSaverMode(int)" )
442 << ( hasVideoChannel ? QPEApplication::Disable : QPEApplication::DisableSuspend );
443 }
444#endif
445
446 playtime.start();
447 startTimers();
448}
449
450
451void LoopControl::setMute( bool on ) {
452 if ( on != isMuted ) {
453 isMuted = on;
454 if ( !on ) {
455 // Force an update of the position
456 mediaPlayerState->setPosition( mediaPlayerState->position() + 1 );
457 mediaPlayerState->setPosition( mediaPlayerState->position() - 1 );
458 // Resume playing audio
459 moreAudio = TRUE;
460 }
461 }
462}
463
464
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef MPEGVIEW_H
21#define MPEGVIEW_H
22
23
24#include <qwidget.h>
25#include <qdatetime.h>
26
27
28class LoopControl : public QObject {
29 Q_OBJECT
30public:
31 LoopControl( QObject *parent, const char *name );
32 ~LoopControl();
33
34 bool init( const QString& filename );
35
36 bool hasVideo() const { return hasVideoChannel; }
37 bool hasAudio() const { return hasAudioChannel; }
38
39 long totalPlaytime() { return (long)(hasVideoChannel ? total_video_frames / framerate : total_audio_samples / freq); }
40
41 // These are public to run them from global functions needed to start threads
42 // Otherwise they would be private
43 void startAudio();
44 void startVideo();
45 bool moreAudio;
46 bool moreVideo;
47public slots:
48 void play();
49 void stop( bool willPlayAgainShortly = FALSE );
50
51 void setMute( bool );
52 void setPaused( bool );
53 void setPosition( long );
54
55signals:
56 void positionChanged( long, long );
57
58protected:
59 void timerEvent(QTimerEvent*);
60
61private:
62 void startTimers();
63 void killTimers();
64
65 QTime playtime;
66 int videoId;
67 int sliderId;
68
69 int audioSampleCounter;
70 long current_frame;
71 long total_video_frames;
72 long total_audio_samples;
73
74 float framerate;
75 int freq;
76 int stream;
77 int framecount;
78 int channels;
79
80 bool hasVideoChannel;
81 bool hasAudioChannel;
82 bool isMuted;
83 QString fileName;
84};
85
86
87#endif
88
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#define _REENTRANT
22
23#include <qpe/qpeapplication.h>
24#include <qimage.h>
25#include <qpainter.h>
26#ifdef Q_WS_QWS
27#include <qpe/qcopenvelope_qws.h>
28#endif
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
32#include <time.h>
33#include <unistd.h>
34#include <pthread.h>
35#include "loopcontrol.h"
36#include "audiodevice.h"
37#include "videowidget.h"
38#include "audiowidget.h"
39#include "mediaplayerplugininterface.h"
40#include "mediaplayerstate.h"
41
42
43#if defined(QT_QWS_CUSTOM) || defined(QT_QWS_IPAQ)
44#define USE_REALTIME_AUDIO_THREAD
45#endif
46
47
48extern VideoWidget *videoUI; // now only needed to tell it to play a frame
49extern MediaPlayerState *mediaPlayerState;
50
51
52#define DecodeLoopDebug(x) qDebug x
53//#define DecodeLoopDebug(x)
54
55
56 static char *audioBuffer = NULL;
57static AudioDevice *audioDevice = NULL;
58 static bool disabledSuspendScreenSaver = FALSE;
59
60
61 pthread_tvideo_tid;
62pthread_attr_t video_attr;
63 pthread_taudio_tid;
64pthread_attr_t audio_attr;
65
66
67bool emitPlayFinished = FALSE;
68bool emitChangePos = FALSE;
69
70
71class Mutex {
72public:
73 Mutex() {
74 pthread_mutexattr_t attr;
75 pthread_mutexattr_init( &attr );
76 pthread_mutex_init( &mutex, &attr );
77 pthread_mutexattr_destroy( &attr );
78 }
79
80 ~Mutex() {
81 pthread_mutex_destroy( &mutex );
82 }
83
84 void lock() {
85 pthread_mutex_lock( &mutex );
86 }
87
88 void unlock() {
89 pthread_mutex_unlock( &mutex );
90 }
91/*
92 bool locked() {
93 switch ( pthread_mutex_trylock( &mutex ) ) {
94 case EBUSY:
95 return TRUE;
96 case 0:
97 pthread_mutex_unlock( &mutex );
98 default:
99 return FALSE;
100 }
101 }
102*/
103private:
104 pthread_mutex_t mutex;
105};
106
107
108class currentFrameObj {
109public:
110 currentFrameObj() : value( 0 ) { }
111 void set( long f ) {
112 mutex.lock();
113 value = f;
114 mediaPlayerState->curDecoder()->videoSetFrame( f, 0 );
115 mutex.unlock();
116 }
117 long get() {
118 return value;
119 }
120private:
121 long value;
122 Mutex mutex;
123};
124
125
126Mutex *videoMutex;
127Mutex *audioMutex;
128Mutex *globalMutex;
129
130
131 clock_tbegin;
132
133
134LoopControl::LoopControl( QObject *parent, const char *name )
135 : QObject( parent, name ) {
136 isMuted = FALSE;
137 connect( qApp, SIGNAL( volumeChanged(bool) ), this, SLOT( setMute(bool) ) );
138 timerid = startTimer( 200 );
139 videoMutex = new Mutex;
140 audioMutex = new Mutex;
141 globalMutex = new Mutex;
142 //begin = clock();
143}
144
145
146LoopControl::~LoopControl() {
147 stop();
148 killTimer( timerid );
149}
150
151
152static bool sendingNewPos = FALSE;
153static long prev_frame = 0;
154static int currentSample = 0;
155
156
157void LoopControl::timerEvent( QTimerEvent* ) {
158 // We need to emit playFinished from the main thread, not one of the
159 // decoding threads else we'll have all kinds of yucky things happen (reentrance).
160 // playFinished will eventually call stop() which stops these threads.
161 if ( emitPlayFinished ) {
162 emitPlayFinished = FALSE;
163 mediaPlayerState->setPlaying( FALSE );
164 }
165
166 if ( emitChangePos ) {
167
168 emitChangePos = FALSE;
169
170 if ( hasVideoChannel && hasAudioChannel ) {
171 sendingNewPos = TRUE;
172 mediaPlayerState->setPosition( current_frame );
173 } else if ( hasVideoChannel ) {
174 sendingNewPos = TRUE;
175 mediaPlayerState->setPosition( current_frame );
176 } else if ( hasAudioChannel ) {
177 sendingNewPos = TRUE;
178 mediaPlayerState->setPosition( audioSampleCounter );
179 }
180
181 }
182}
183
184
185
186
187void LoopControl::setPosition( long pos ) {
188 if ( sendingNewPos ) {
189 sendingNewPos = FALSE;
190 return;
191 }
192
193 if ( hasVideoChannel && hasAudioChannel ) {
194 videoMutex->lock();
195 audioMutex->lock();
196qDebug("setting position");
197 playtime.restart();
198 playtime = playtime.addMSecs( -pos * 1000 / framerate );
199 //begin = clock() - (double)pos * CLOCKS_PER_SEC / framerate;
200 current_frame = pos + 1;
201 mediaPlayerState->curDecoder()->videoSetFrame( current_frame, stream );
202 prev_frame = current_frame - 1;
203 currentSample = (int)( current_frame * freq / framerate );
204 mediaPlayerState->curDecoder()->audioSetSample( currentSample, stream );
205 audioSampleCounter = currentSample - 1;
206 audioMutex->unlock();
207 videoMutex->unlock();
208 } else if ( hasVideoChannel ) {
209 videoMutex->lock();
210 playtime.restart();
211 playtime = playtime.addMSecs( -pos * 1000 / framerate );
212 //begin = clock() - (double)pos * CLOCKS_PER_SEC / framerate;
213 current_frame = pos + 1;
214 mediaPlayerState->curDecoder()->videoSetFrame( current_frame, stream );
215 videoMutex->unlock();
216 prev_frame = current_frame - 1;
217 } else if ( hasAudioChannel ) {
218 audioMutex->lock();
219 playtime.restart();
220 playtime = playtime.addMSecs( -pos * 1000 / freq );
221 //begin = clock() - (double)pos * CLOCKS_PER_SEC / freq;
222 currentSample = pos + 1; // (int)( current_frame * freq / framerate );
223 mediaPlayerState->curDecoder()->audioSetSample( currentSample, stream );
224 audioSampleCounter = currentSample - 1;
225 audioMutex->unlock();
226 }
227}
228
229
230void *startVideoThread( void *ptr ) {
231 LoopControl *mpegView = (LoopControl *)ptr;
232 mpegView->startVideo();
233 return 0;
234}
235
236void *startAudioThread( void *ptr ) {
237 LoopControl *mpegView = (LoopControl *)ptr;
238 mpegView->startAudio();
239 return 0;
240}
241
242void LoopControl::startVideo() {
243 moreVideo = TRUE;
244
245 while ( moreVideo ) {
246
247 if ( mediaPlayerState->curDecoder() && hasVideoChannel ) {
248
249 if ( hasAudioChannel && !isMuted ) {
250
251 bool done = FALSE;
252
253 do {
254
255
256/*
257 videoMutex->lock();
258 current_frame = int( (double)playtime.elapsed() * (double)framerate / 1000.0 );
259 //current_frame = ( clock() - begin ) * (double)framerate / CLOCKS_PER_SEC;
260
261 // Sync to Audio
262 // current_frame = (long)((double)(audioSampleCounter - 1000) * framerate / (double)freq);
263
264 long mSecsToNextFrame = 0;
265
266 if ( current_frame == prev_frame ) {
267 int nf = current_frame + 1;
268 if ( nf > 0 && nf != total_video_frames )
269 // mSecsToNextFrame = long(double(nf * CLOCKS_PER_SEC) / framerate) - ( clock() - begin );
270 mSecsToNextFrame = long(double(nf * 1000) / framerate) - ( playtime.elapsed() );
271 }
272 videoMutex->unlock();
273
274 if ( mSecsToNextFrame ) {
275 usleep( mSecsToNextFrame ); // wait a bit
276
277 videoMutex->lock();
278 // This should now be the next frame
279 current_frame = int( (double)playtime.elapsed() * (double)framerate / 1000.0 );
280 //current_frame = ( clock() - begin ) * (double)framerate / CLOCKS_PER_SEC;
281 videoMutex->unlock();
282 }
283
284 videoMutex->lock();
285 done = current_frame >= prev_frame;
286 videoMutex->unlock();
287*/
288 videoMutex->lock();
289 current_frame = int( (double)playtime.elapsed() * (double)framerate / 1000.0 );
290 done = current_frame >= prev_frame;
291 videoMutex->unlock();
292 if ( !done )
293 usleep( 1000 ); // wait a bit
294
295 } while ( !done );
296
297 // qDebug("elapsed: %i %i (%f)", int( playtime.elapsed() ), current_frame, framerate );
298
299 } else {
300 videoMutex->lock();
301 current_frame++;
302 videoMutex->unlock();
303 }
304
305 videoMutex->lock();
306 bool check = current_frame && current_frame > prev_frame;
307 videoMutex->unlock();
308
309 if ( check ) {
310 videoMutex->lock();
311 if ( current_frame > prev_frame + 1 ) {
312 qDebug("skipped a frame");
313 mediaPlayerState->curDecoder()->videoSetFrame( current_frame, stream );
314 }
315 prev_frame = current_frame;
316 if ( moreVideo = videoUI->playVideo() )
317 emitChangePos = TRUE;
318 videoMutex->unlock();
319 }
320
321 } else
322 moreVideo = FALSE;
323
324 }
325
326 if ( !moreVideo && !moreAudio )
327 emitPlayFinished = TRUE;
328
329 pthread_exit(NULL);
330}
331
332void LoopControl::startAudio() {
333 moreAudio = TRUE;
334
335 while ( moreAudio ) {
336
337 if ( !isMuted && mediaPlayerState->curDecoder() && hasAudioChannel ) {
338
339 audioMutex->lock();
340 currentSample = mediaPlayerState->curDecoder()->audioGetSample( stream );
341
342 if ( currentSample == 0 )
343 currentSample = audioSampleCounter + 1;
344
345 if ( currentSample != audioSampleCounter + 1 )
346 qDebug("out of sync with decoder %i %i", currentSample, audioSampleCounter);
347 audioMutex->unlock();
348
349/*
350 int sampleWeShouldBeAt = int( playtime.elapsed() ) * freq / 1000;
351
352 if ( sampleWeShouldBeAt - currentSample > 20000 ) {
353 mediaPlayerState->curDecoder()->audioSetSample( sampleWeShouldBeAt, stream );
354 currentSample = sampleWeShouldBeAt;
355 }
356*/
357 long samplesRead = 0;
358
359 const long samples = 1024;
360
361 moreAudio = !mediaPlayerState->curDecoder()->audioReadSamples( (short*)audioBuffer, channels, samples, samplesRead, stream );
362
363 audioMutex->lock();
364 long sampleWeShouldBeAt = long( playtime.elapsed() ) * freq / 1000;
365 //long sampleWeShouldBeAt = long( clock() - begin ) * (double) freq / CLOCKS_PER_SEC;
366 long sampleWaitTime = currentSample - sampleWeShouldBeAt;
367 audioMutex->unlock();
368
369 if ( sampleWaitTime >= 0 && sampleWaitTime <= 2000 ) {
370 //qDebug("sampleWaitTime: %i", sampleWaitTime);
371 usleep( ( sampleWaitTime * 1000000 ) / ( freq ) );
372 } else {
373 audioMutex->lock();
374 if ( sampleWaitTime <= -2000 ) {
375 qDebug("need to catch up by: %li (%i,%li)", -sampleWaitTime, currentSample, sampleWeShouldBeAt );
376 mediaPlayerState->curDecoder()->audioSetSample( sampleWeShouldBeAt, stream );
377 currentSample = sampleWeShouldBeAt;
378 }
379 audioMutex->unlock();
380 }
381
382 audioDevice->write( audioBuffer, samplesRead * 2 * channels );
383
384 audioMutex->lock();
385 // audioSampleCounter += samplesRead;
386 audioSampleCounter = currentSample + samplesRead - 1;
387 audioMutex->unlock();
388
389 if ( !hasVideoChannel )
390 emitChangePos = TRUE;
391
392 //qDebug("currentSample: %i audioSampleCounter: %i total_audio_samples: %i", currentSample, audioSampleCounter, total_audio_samples);
393 // qDebug("current: %i counter: %i total: %i", currentSample, audioSampleCounter, (int)total_audio_samples);
394 moreAudio = audioSampleCounter <= total_audio_samples;
395
396 } else {
397
398 if ( mediaPlayerState->curDecoder() && hasAudioChannel )
399 usleep( 100000 ); // Check every 1/10 sec to see if mute is off
400 else
401 moreAudio = FALSE;
402
403 }
404 }
405
406 qDebug( "End of file" );
407
408 if ( !moreVideo && !moreAudio )
409 emitPlayFinished = TRUE;
410
411 pthread_exit(NULL);
412}
413
414void LoopControl::killTimers() {
415 if ( hasVideoChannel ) {
416 if ( pthread_self() != video_tid ) {
417 if ( pthread_cancel(video_tid) == 0 ) {
418 void *thread_result = 0;
419 if ( pthread_join(video_tid,&thread_result) != 0 )
420 qDebug("thread join error 1");
421 pthread_attr_destroy(&video_attr);
422 }
423 }
424 }
425 if ( hasAudioChannel ) {
426 if ( pthread_self() != audio_tid ) {
427 if ( pthread_cancel(audio_tid) == 0 ) {
428 void *thread_result = 0;
429 if ( pthread_join(audio_tid,&thread_result) != 0 )
430 qDebug("thread join error 2");
431 pthread_attr_destroy(&audio_attr);
432 }
433 }
434 }
435}
436
437void LoopControl::startTimers() {
438 moreVideo = FALSE;
439 moreAudio = FALSE;
440
441 if ( hasVideoChannel ) {
442 moreVideo = TRUE;
443 pthread_attr_init(&video_attr);
444 pthread_create(&video_tid, &video_attr, (void * (*)(void *))startVideoThread, this);
445 }
446
447 if ( hasAudioChannel ) {
448 moreAudio = TRUE;
449 pthread_attr_init(&audio_attr);
450#ifdef USE_REALTIME_AUDIO_THREAD
451 pthread_attr_setschedpolicy(&audio_attr,SCHED_RR); // Real-time round robin
452 //qDebug("min: %i, max: %i", sched_get_priority_min( SCHED_RR ), sched_get_priority_max( SCHED_RR ) );
453 sched_param params;
454 params.sched_priority = 50;
455 pthread_attr_setschedparam(&audio_attr,&params);
456#endif
457 pthread_create(&audio_tid, &audio_attr, (void * (*)(void *))startAudioThread, this);
458 }
459}
460
461
462
463
464void LoopControl::setPaused( bool pause ) {
465 static int whenPaused = 0;
466
467 if ( !mediaPlayerState->curDecoder() || !mediaPlayerState->curDecoder()->isOpen() )
468 return;
469
470 if ( pause ) {
471 // Remember where we are
472 whenPaused = playtime.elapsed();
473 killTimers();
474 } else {
475 // Just like we never stopped
476 playtime.restart();
477 playtime = playtime.addMSecs( -whenPaused );
478 whenPaused = 0;
479 startTimers();
480 }
481}
482
483
484void LoopControl::stop( bool willPlayAgainShortly ) {
485
486#if defined(Q_WS_QWS) && !defined(QT_NO_COP)
487 if ( !willPlayAgainShortly && disabledSuspendScreenSaver ) {
488 disabledSuspendScreenSaver = FALSE;
489 // Re-enable the suspend mode
490 QCopEnvelope("QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::Enable;
491 }
492#endif
493
494 if ( mediaPlayerState->curDecoder() && mediaPlayerState->curDecoder()->isOpen() ) {
495
496 killTimers();
497
498 mediaPlayerState->curDecoder()->close();
499
500 if ( audioDevice ) {
501 delete audioDevice;
502 delete audioBuffer;
503 audioDevice = 0;
504 audioBuffer = 0;
505 }
506
507 }
508}
509
510
511bool LoopControl::init( const QString& filename ) {
512 stop();
513 fileName = filename;
514 stream = 0; // only play stream 0 for now
515 current_frame = total_video_frames = total_audio_samples = 0;
516
517 qDebug( "Using the %s decoder", mediaPlayerState->curDecoder()->pluginName() );
518
519 // ### Hack to use libmpeg3plugin to get the number of audio samples if we are using the libmad plugin
520 if ( mediaPlayerState->curDecoder()->pluginName() == QString("LibMadPlugin") ) {
521 if ( mediaPlayerState->libMpeg3Decoder() && mediaPlayerState->libMpeg3Decoder()->open( filename ) ) {
522 total_audio_samples = mediaPlayerState->libMpeg3Decoder()->audioSamples( 0 );
523 mediaPlayerState->libMpeg3Decoder()->close();
524 }
525 }
526
527 if ( !mediaPlayerState->curDecoder()|| !mediaPlayerState->curDecoder()->open( filename ) )
528 return FALSE;
529
530 hasAudioChannel = mediaPlayerState->curDecoder()->audioStreams() > 0;
531 hasVideoChannel = mediaPlayerState->curDecoder()->videoStreams() > 0;
532
533 if ( hasAudioChannel ) {
534 int astream = 0;
535
536 channels = mediaPlayerState->curDecoder()->audioChannels( astream );
537 DecodeLoopDebug(( "channels = %d\n", channels ));
538
539 if ( !total_audio_samples )
540 total_audio_samples = mediaPlayerState->curDecoder()->audioSamples( astream );
541
542 mediaPlayerState->setLength( total_audio_samples );
543
544 freq = mediaPlayerState->curDecoder()->audioFrequency( astream );
545 DecodeLoopDebug(( "frequency = %d\n", freq ));
546
547 audioSampleCounter = 0;
548
549 static const int bytes_per_sample = 2; //16 bit
550
551 audioDevice = new AudioDevice( freq, channels, bytes_per_sample );
552 audioBuffer = new char[ audioDevice->bufferSize() ];
553 channels = audioDevice->channels();
554
555 //### must check which frequency is actually used.
556 static const int size = 1;
557 short int buf[size];
558 long samplesRead = 0;
559 mediaPlayerState->curDecoder()->audioReadSamples( buf, channels, size, samplesRead, stream );
560 }
561
562 if ( hasVideoChannel ) {
563 total_video_frames = mediaPlayerState->curDecoder()->videoFrames( stream );
564
565 mediaPlayerState->setLength( total_video_frames );
566
567 framerate = mediaPlayerState->curDecoder()->videoFrameRate( stream );
568 DecodeLoopDebug(( "Frame rate %g total %ld", framerate, total_video_frames ));
569
570 if ( framerate <= 1.0 ) {
571 DecodeLoopDebug(( "Crazy frame rate, resetting to sensible" ));
572 framerate = 25;
573 }
574
575 if ( total_video_frames == 1 ) {
576 DecodeLoopDebug(( "Cannot seek to frame" ));
577 }
578
579 }
580
581 videoMutex->lock();
582 current_frame = 0;
583 prev_frame = -1;
584 videoMutex->unlock();
585
586 connect( mediaPlayerState, SIGNAL( positionChanged( long ) ), this, SLOT( setPosition( long ) ) );
587 connect( mediaPlayerState, SIGNAL( pausedToggled( bool ) ), this, SLOT( setPaused( bool ) ) );
588
589 //setBackgroundColor( black );
590 return TRUE;
591}
592
593
594void LoopControl::play() {
595
596#if defined(Q_WS_QWS) && !defined(QT_NO_COP)
597 if ( !disabledSuspendScreenSaver ) {
598 disabledSuspendScreenSaver = TRUE;
599 // Stop the screen from blanking and power saving state
600 QCopEnvelope("QPE/System", "setScreenSaverMode(int)" )
601 << ( hasVideoChannel ? QPEApplication::Disable : QPEApplication::DisableSuspend );
602 }
603#endif
604
605 //begin = clock();
606 playtime.start();
607 startTimers();
608 //updateGeometry();
609}
610
611
612void LoopControl::setMute( bool on ) {
613 if ( isMuted != on ) {
614 isMuted = on;
615 if ( isMuted ) {
616 } else {
617 int frame = current_frame; // mediaPlayerState->curDecoder()->videoGetFrame( stream );
618 playtime.restart();
619 playtime = playtime.addMSecs( -frame * 1000 / framerate );
620 //begin = clock() - (double)frame * CLOCKS_PER_SEC / framerate;
621 mediaPlayerState->curDecoder()->audioSetSample( frame*freq/framerate, stream );
622 }
623 }
624}
625
626
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef MPEGVIEW_H
21#define MPEGVIEW_H
22
23
24#include <qwidget.h>
25#include <qdatetime.h>
26
27
28class LoopControl : public QObject {
29 Q_OBJECT
30public:
31 LoopControl( QObject *parent, const char *name );
32 ~LoopControl();
33
34 bool init( const QString& filename );
35
36 bool hasVideo() const { return hasVideoChannel; }
37 bool hasAudio() const { return hasAudioChannel; }
38
39 long totalPlaytime() { return (long)(hasVideoChannel ? total_video_frames / framerate : total_audio_samples / freq); }
40
41 // These are public to run them from global functions needed to start threads
42 // Otherwise they would be private
43 void startAudio();
44 void startVideo();
45public slots:
46 void play();
47 void stop( bool willPlayAgainShortly = FALSE );
48
49 void setMute( bool );
50 void setPaused( bool );
51 void setPosition( long );
52
53signals:
54 void positionChanged( long, long );
55 void playFinished();
56
57protected:
58 void timerEvent(QTimerEvent*);
59
60private:
61 void startTimers();
62 void killTimers();
63
64
65 QTime playtime;
66 int timerid;
67 int audioSampleCounter;
68 long current_frame;
69 long total_video_frames;
70 long total_audio_samples;
71
72 float framerate;
73 int freq;
74 int stream;
75 int framecount;
76 int channels;
77
78 bool moreAudio;
79 bool moreVideo;
80
81 bool hasVideoChannel;
82 bool hasAudioChannel;
83 bool isMuted;
84 QString fileName;
85};
86
87
88#endif
89
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#include <qpe/qpeapplication.h>
21#include "mediaplayerstate.h"
22#include "playlistwidget.h"
23#include "audiowidget.h"
24#include "videowidget.h"
25#include "loopcontrol.h"
26#include "mediaplayer.h"
27
28
29MediaPlayerState *mediaPlayerState;
30PlayListWidget *playList;
31AudioWidget *audioUI;
32VideoWidget *videoUI;
33LoopControl *loopControl;
34
35
36int main(int argc, char **argv) {
37 QPEApplication a(argc,argv);
38
39 MediaPlayerState st( 0, "mediaPlayerState" );
40 mediaPlayerState = &st;
41 PlayListWidget pl( 0, "playList" );
42 playList = &pl;
43 AudioWidget aw( 0, "audioUI" );
44 audioUI = &aw;
45 VideoWidget vw( 0, "videoUI" );
46 videoUI = &vw;
47 LoopControl lc( 0, "loopControl" );
48 loopControl = &lc;
49 MediaPlayer mp( 0, "mediaPlayer" );
50
51 pl.setCaption( MediaPlayer::tr("Media Player") );
52 a.showMainDocumentWidget(&pl);
53
54 return a.exec();
55}
56
57
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#include <qpe/qpeapplication.h>
21#include <qpe/qlibrary.h>
22#include <qpe/resource.h>
23#include <qpe/config.h>
24
25#include <qmainwindow.h>
26#include <qmessagebox.h>
27#include <qwidgetstack.h>
28#include <qfile.h>
29
30#include "mediaplayer.h"
31#include "playlistwidget.h"
32#include "audiowidget.h"
33#include "loopcontrol.h"
34#include "audiodevice.h"
35
36#include "mediaplayerstate.h"
37
38
39extern AudioWidget *audioUI;
40extern PlayListWidget *playList;
41extern LoopControl *loopControl;
42extern MediaPlayerState *mediaPlayerState;
43
44
45MediaPlayer::MediaPlayer( QObject *parent, const char *name )
46 : QObject( parent, name ), volumeDirection( 0 ), currentFile( NULL ) {
47
48 connect( mediaPlayerState, SIGNAL( playingToggled( bool ) ), this, SLOT( setPlaying( bool ) ) );
49 connect( mediaPlayerState, SIGNAL( pausedToggled( bool ) ), this, SLOT( pauseCheck( bool ) ) );
50 connect( mediaPlayerState, SIGNAL( next() ), this, SLOT( next() ) );
51 connect( mediaPlayerState, SIGNAL( prev() ), this, SLOT( prev() ) );
52
53 connect( audioUI, SIGNAL( moreClicked() ), this, SLOT( startIncreasingVolume() ) );
54 connect( audioUI, SIGNAL( lessClicked() ), this, SLOT( startDecreasingVolume() ) );
55 connect( audioUI, SIGNAL( moreReleased() ), this, SLOT( stopChangingVolume() ) );
56 connect( audioUI, SIGNAL( lessReleased() ), this, SLOT( stopChangingVolume() ) );
57}
58
59
60MediaPlayer::~MediaPlayer() {
61}
62
63
64void MediaPlayer::pauseCheck( bool b ) {
65 // Only pause if playing
66 if ( b && !mediaPlayerState->playing() )
67 mediaPlayerState->setPaused( FALSE );
68}
69
70
71void MediaPlayer::play() {
72 mediaPlayerState->setPlaying( FALSE );
73 mediaPlayerState->setPlaying( TRUE );
74}
75
76
77void MediaPlayer::setPlaying( bool play ) {
78
79 if ( !play ) {
80 mediaPlayerState->setPaused( FALSE );
81 loopControl->stop( FALSE );
82 return;
83 }
84
85 if ( mediaPlayerState->paused() ) {
86 mediaPlayerState->setPaused( FALSE );
87 return;
88 }
89
90 const DocLnk *playListCurrent = playList->current();
91
92 if ( playListCurrent != NULL ) {
93 loopControl->stop( TRUE );
94 currentFile = playListCurrent;
95 }
96
97 if ( currentFile == NULL ) {
98 QMessageBox::critical( 0, tr( "No file"), tr( "Error: There is no file selected" ) );
99 mediaPlayerState->setPlaying( FALSE );
100 return;
101 }
102
103 if ( !QFile::exists( currentFile->file() ) ) {
104 QMessageBox::critical( 0, tr( "File not found"), tr( "The following file was not found: <i>" ) + currentFile->file() + "</i>" );
105 mediaPlayerState->setPlaying( FALSE );
106 return;
107 }
108
109 if ( !mediaPlayerState->newDecoder( currentFile->file() ) ) {
110 QMessageBox::critical( 0, tr( "No decoder found"), tr( "Sorry, no appropriate decoders found for this file: <i>" ) + currentFile->file() + "</i>" );
111 mediaPlayerState->setPlaying( FALSE );
112 return;
113 }
114
115 if ( !loopControl->init( currentFile->file() ) ) {
116 QMessageBox::critical( 0, tr( "Error opening file"), tr( "Sorry, an error occured trying to play the file: <i>" ) + currentFile->file() + "</i>" );
117 mediaPlayerState->setPlaying( FALSE );
118 return;
119 }
120
121 long seconds = loopControl->totalPlaytime();
122 QString time; time.sprintf("%li:%02i", seconds/60, (int)seconds%60 );
123 QString tickerText = tr( " File: " ) + currentFile->name() + tr(", Length: ") + time;
124 QString fileInfo = mediaPlayerState->curDecoder()->fileInfo();
125 if ( !fileInfo.isEmpty() )
126 tickerText += ", " + fileInfo;
127 audioUI->setTickerText( tickerText + "." );
128
129 loopControl->play();
130
131 mediaPlayerState->setView( loopControl->hasVideo() ? 'v' : 'a' );
132}
133
134
135void MediaPlayer::prev() {
136 if ( playList->prev() )
137 play();
138 else if ( mediaPlayerState->looping() ) {
139 if ( playList->last() )
140 play();
141 } else
142 mediaPlayerState->setList();
143}
144
145
146void MediaPlayer::next() {
147 if ( playList->next() )
148 play();
149 else if ( mediaPlayerState->looping() ) {
150 if ( playList->first() )
151 play();
152 } else
153 mediaPlayerState->setList();
154}
155
156
157void MediaPlayer::startDecreasingVolume() {
158 volumeDirection = -1;
159 startTimer( 100 );
160 AudioDevice::decreaseVolume();
161}
162
163
164void MediaPlayer::startIncreasingVolume() {
165 volumeDirection = +1;
166 startTimer( 100 );
167 AudioDevice::increaseVolume();
168}
169
170
171void MediaPlayer::stopChangingVolume() {
172 killTimers();
173}
174
175
176void MediaPlayer::timerEvent( QTimerEvent * ) {
177 if ( volumeDirection == +1 )
178 AudioDevice::increaseVolume();
179 else if ( volumeDirection == -1 )
180 AudioDevice::decreaseVolume();
181}
182
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef MEDIA_PLAYER_H
21#define MEDIA_PLAYER_H
22
23
24#include <qmainwindow.h>
25#include <qframe.h>
26#include <qpe/qlibrary.h>
27#include "mediaplayerplugininterface.h"
28
29
30class DocLnk;
31
32
33class MediaPlayer : public QObject {
34 Q_OBJECT
35public:
36 MediaPlayer( QObject *parent, const char *name );
37 ~MediaPlayer();
38
39private slots:
40 void setPlaying( bool );
41 void pauseCheck( bool );
42 void play();
43 void next();
44 void prev();
45 void startIncreasingVolume();
46 void startDecreasingVolume();
47 void stopChangingVolume();
48
49protected:
50 void timerEvent( QTimerEvent *e );
51
52private:
53 int volumeDirection;
54 const DocLnk*currentFile;
55};
56
57
58#endif // MEDIA_PLAYER_H
59
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef MEDIA_PLAYER_PLUGIN_INTERFACE_H
21#define MEDIA_PLAYER_PLUGIN_INTERFACE_H
22
23#include <qpe/qcom.h>
24
25#ifndef QT_NO_COMPONENT
26// {c0093632-b44c-4cf7-a279-d82fe8a8890c}
27# ifndef IID_MediaPlayerPlugin
28# define IID_MediaPlayerPlugin QUuid( 0xc0093632, 0xb44c, 0x4cf7, 0xa2, 0x79, 0xd8, 0x2f, 0xe8, 0xa8, 0x89, 0x0c )
29# endif
30#endif
31
32
33enum ColorFormat {
34 RGB565,
35 BGR565,
36 RGBA8888,
37 BGRA8888
38};
39
40
41class MediaPlayerDecoder {
42
43public:
44 virtual ~MediaPlayerDecoder() { };
45
46 // About Plugin
47 virtual const char *pluginName() = 0;
48 virtual const char *pluginComment() = 0;
49 virtual double pluginVersion() = 0;
50
51 virtual bool isFileSupported( const QString& file ) = 0;
52 virtual bool open( const QString& file ) = 0;
53 virtual bool close() = 0;
54 virtual bool isOpen() = 0;
55 virtual const QString &fileInfo() = 0;
56
57 // If decoder doesn't support audio then return 0 here
58 virtual int audioStreams() = 0;
59 virtual int audioChannels( int stream ) = 0;
60 virtual int audioFrequency( int stream ) = 0;
61 virtual int audioSamples( int stream ) = 0;
62 virtual bool audioSetSample( long sample, int stream ) = 0;
63 virtual long audioGetSample( int stream ) = 0;
64// virtual bool audioReadMonoSamples( short *samples, long samples, long& samplesRead, int stream ) = 0;
65// virtual bool audioReadStereoSamples( short *samples, long samples, long& samplesRead, int stream ) = 0;
66 virtual bool audioReadSamples( short *samples, int channels, long samples, long& samplesRead, int stream ) = 0;
67 // Libmpeg3 functions, perhaps good for reading an audio file with 5 channels or something!
68// virtual bool audioReadSamples( short *samples, int channel, long samples, int stream ) = 0;
69// virtual bool audioReReadSamples( short *samples, int channel, long samples, int stream ) = 0;
70
71 // If decoder doesn't support video then return 0 here
72 virtual int videoStreams() = 0;
73 virtual int videoWidth( int stream ) = 0;
74 virtual int videoHeight( int stream ) = 0;
75 virtual double videoFrameRate( int stream ) = 0; // frames per second (this may change to frames/1000secs)
76 virtual int videoFrames( int stream ) = 0;
77 virtual bool videoSetFrame( long sample, int stream ) = 0;
78 virtual long videoGetFrame( int stream ) = 0;
79 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;
80 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;
81 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;
82
83 // Profiling
84 virtual double getTime() = 0;
85
86 // Ignore if these aren't supported
87 virtual bool setSMP( int cpus ) = 0;
88 virtual bool setMMX( bool useMMX ) = 0;
89
90 // Capabilities
91 virtual bool supportsAudio() = 0;
92 virtual bool supportsVideo() = 0;
93 virtual bool supportsYUV() = 0;
94 virtual bool supportsMMX() = 0;
95 virtual bool supportsSMP() = 0;
96 virtual bool supportsStereo() = 0;
97 virtual bool supportsScaling() = 0;
98
99};
100
101
102class MediaPlayerEncoder;
103
104
105struct MediaPlayerPluginInterface : public QUnknownInterface
106{
107 virtual MediaPlayerDecoder *decoder() = 0;
108 virtual MediaPlayerEncoder *encoder() = 0;
109};
110
111
112#endif
113
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#include <qpe/qpeapplication.h>
21#include <qpe/qlibrary.h>
22#include <qpe/config.h>
23#include <qvaluelist.h>
24#include <qobject.h>
25#include <qdir.h>
26#include "mediaplayerplugininterface.h"
27#include "mediaplayerstate.h"
28
29#ifdef QT_NO_COMPONENT
30// Plugins which are compiled in when no plugin architecture available
31#include "libmad/libmadpluginimpl.h"
32#include "libmpeg3/libmpeg3pluginimpl.h"
33#include "wavplugin/wavpluginimpl.h"
34#endif
35
36
37 //#define MediaPlayerDebug(x)qDebug x
38#define MediaPlayerDebug(x)
39
40
41MediaPlayerState::MediaPlayerState( QObject *parent, const char *name )
42 : QObject( parent, name ), decoder( NULL ), libmpeg3decoder( NULL ) {
43 Config cfg( "MediaPlayer" );
44 readConfig( cfg );
45 loadPlugins();
46}
47
48
49MediaPlayerState::~MediaPlayerState() {
50 Config cfg( "MediaPlayer" );
51 writeConfig( cfg );
52}
53
54
55void MediaPlayerState::readConfig( Config& cfg ) {
56 cfg.setGroup("Options");
57 isFullscreen = cfg.readBoolEntry( "FullScreen" );
58 isScaled = cfg.readBoolEntry( "Scaling" );
59 isLooping = cfg.readBoolEntry( "Looping" );
60 isShuffled = cfg.readBoolEntry( "Shuffle" );
61 usePlaylist = cfg.readBoolEntry( "UsePlayList" );
62 isPlaying = FALSE;
63 isPaused = FALSE;
64 curPosition = 0;
65 curLength = 0;
66 curView = 'l';
67}
68
69
70void MediaPlayerState::writeConfig( Config& cfg ) const {
71 cfg.setGroup("Options");
72 cfg.writeEntry("FullScreen", isFullscreen );
73 cfg.writeEntry("Scaling", isScaled );
74 cfg.writeEntry("Looping", isLooping );
75 cfg.writeEntry("Shuffle", isShuffled );
76 cfg.writeEntry("UsePlayList", usePlaylist );
77}
78
79
80struct MediaPlayerPlugin {
81#ifndef QT_NO_COMPONENT
82 QLibrary *library;
83#endif
84 MediaPlayerPluginInterface *iface;
85 MediaPlayerDecoder *decoder;
86 MediaPlayerEncoder *encoder;
87};
88
89
90static QValueList<MediaPlayerPlugin> pluginList;
91
92
93// Find the first decoder which supports this type of file
94MediaPlayerDecoder *MediaPlayerState::newDecoder( const QString& file ) {
95 MediaPlayerDecoder *tmpDecoder = NULL;
96 QValueList<MediaPlayerPlugin>::Iterator it;
97 for ( it = pluginList.begin(); it != pluginList.end(); ++it ) {
98 if ( (*it).decoder->isFileSupported( file ) ) {
99 tmpDecoder = (*it).decoder;
100 break;
101 }
102 }
103 return decoder = tmpDecoder;
104}
105
106
107MediaPlayerDecoder *MediaPlayerState::curDecoder() {
108 return decoder;
109}
110
111
112// ### hack to get true sample count
113MediaPlayerDecoder *MediaPlayerState::libMpeg3Decoder() {
114 return libmpeg3decoder;
115}
116
117
118void MediaPlayerState::loadPlugins() {
119
120#ifndef QT_NO_COMPONENT
121 QValueList<MediaPlayerPlugin>::Iterator mit;
122 for ( mit = pluginList.begin(); mit != pluginList.end(); ++mit ) {
123 (*mit).iface->release();
124 (*mit).library->unload();
125 delete (*mit).library;
126 }
127 pluginList.clear();
128
129 QString path = QPEApplication::qpeDir() + "/plugins/codecs";
130 QDir dir( path, "lib*.so" );
131 QStringList list = dir.entryList();
132 QStringList::Iterator it;
133 for ( it = list.begin(); it != list.end(); ++it ) {
134 MediaPlayerPluginInterface *iface = 0;
135 QLibrary *lib = new QLibrary( path + "/" + *it );
136
137 MediaPlayerDebug(( "querying: %s", QString( path + "/" + *it ).latin1() ));
138
139 if ( lib->queryInterface( IID_MediaPlayerPlugin, (QUnknownInterface**)&iface ) == QS_OK ) {
140
141 MediaPlayerDebug(( "loading: %s", QString( path + "/" + *it ).latin1() ));
142
143 MediaPlayerPlugin plugin;
144 plugin.library = lib;
145 plugin.iface = iface;
146 plugin.decoder = plugin.iface->decoder();
147 plugin.encoder = plugin.iface->encoder();
148 pluginList.append( plugin );
149
150 // ### hack to get true sample count
151 if ( plugin.decoder->pluginName() == QString("LibMpeg3Plugin") )
152 libmpeg3decoder = plugin.decoder;
153
154 } else {
155 delete lib;
156 }
157 }
158#else
159 pluginList.clear();
160
161 MediaPlayerPlugin plugin0;
162 plugin0.iface = new LibMpeg3PluginImpl;
163 plugin0.decoder = plugin0.iface->decoder();
164 plugin0.encoder = plugin0.iface->encoder();
165 pluginList.append( plugin0 );
166
167 MediaPlayerPlugin plugin1;
168 plugin1.iface = new LibMadPluginImpl;
169 plugin1.decoder = plugin1.iface->decoder();
170 plugin1.encoder = plugin1.iface->encoder();
171 pluginList.append( plugin1 );
172
173 MediaPlayerPlugin plugin2;
174 plugin2.iface = new WavPluginImpl;
175 plugin2.decoder = plugin2.iface->decoder();
176 plugin2.encoder = plugin2.iface->encoder();
177 pluginList.append( plugin2 );
178#endif
179
180 if ( pluginList.count() )
181 MediaPlayerDebug(( "%i decoders found", pluginList.count() ));
182 else
183 MediaPlayerDebug(( "No decoders found" ));
184}
185
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef MEDIA_PLAYER_STATE_H
21#define MEDIA_PLAYER_STATE_H
22
23
24#include <qobject.h>
25
26
27class MediaPlayerDecoder;
28class Config;
29
30
31class MediaPlayerState : public QObject {
32Q_OBJECT
33public:
34 MediaPlayerState( QObject *parent, const char *name );
35 ~MediaPlayerState();
36
37 bool fullscreen() { return isFullscreen; }
38 bool scaled() { return isScaled; }
39 bool looping() { return isLooping; }
40 bool shuffled() { return isShuffled; }
41 bool playlist() { return usePlaylist; }
42 bool paused() { return isPaused; }
43 bool playing() { return isPlaying; }
44 long position() { return curPosition; }
45 long length() { return curLength; }
46 char view() { return curView; }
47
48 MediaPlayerDecoder *newDecoder( const QString& file );
49 MediaPlayerDecoder *curDecoder();
50 MediaPlayerDecoder *libMpeg3Decoder(); // ### Yucky hack needed to use libmpeg3plugin to get the
51 // number of audio samples if we are using the libmad plugin
52public slots:
53 void setFullscreen( bool b ) { if ( isFullscreen == b ) return; isFullscreen = b; emit fullscreenToggled(b); }
54 void setScaled( bool b ) { if ( isScaled == b ) return; isScaled = b; emit scaledToggled(b); }
55 void setLooping( bool b ) { if ( isLooping == b ) return; isLooping = b; emit loopingToggled(b); }
56 void setShuffled( bool b ) { if ( isShuffled == b ) return; isShuffled = b; emit shuffledToggled(b); }
57 void setPlaylist( bool b ) { if ( usePlaylist == b ) return; usePlaylist = b; emit playlistToggled(b); }
58 void setPaused( bool b ) { if ( isPaused == b ) return; isPaused = b; emit pausedToggled(b); }
59 void setPlaying( bool b ) { if ( isPlaying == b ) return; isPlaying = b; emit playingToggled(b); }
60 void setPosition( long p ) { if ( curPosition == p ) return; curPosition = p; emit positionChanged(p); }
61 void updatePosition( long p ){ if ( curPosition == p ) return; curPosition = p; emit positionUpdated(p); }
62 void setLength( long l ) { if ( curLength == l ) return; curLength = l; emit lengthChanged(l); }
63 void setView( char v ) { if ( curView == v ) return; curView = v; emit viewChanged(v); }
64
65 void setPrev() { emit prev(); }
66 void setNext() { emit next(); }
67 void setList() { setPlaying( FALSE ); setView('l'); }
68 void setVideo() { setView('v'); }
69 void setAudio() { setView('a'); }
70
71 void toggleFullscreen() { setFullscreen( !isFullscreen ); }
72 void toggleScaled() { setScaled( !isScaled); }
73 void toggleLooping() { setLooping( !isLooping); }
74 void toggleShuffled() { setShuffled( !isShuffled); }
75 void togglePlaylist() { setPlaylist( !usePlaylist); }
76 void togglePaused() { setPaused( !isPaused); }
77 void togglePlaying() { setPlaying( !isPlaying); }
78
79signals:
80 void fullscreenToggled( bool );
81 void scaledToggled( bool );
82 void loopingToggled( bool );
83 void shuffledToggled( bool );
84 void playlistToggled( bool );
85 void pausedToggled( bool );
86 void playingToggled( bool );
87 void positionChanged( long ); // When the slider is moved
88 void positionUpdated( long ); // When the media file progresses
89 void lengthChanged( long );
90 void viewChanged( char );
91
92 void prev();
93 void next();
94
95private:
96 bool isFullscreen;
97 bool isScaled;
98 bool isLooping;
99 bool isShuffled;
100 bool usePlaylist;
101 bool isPaused;
102 bool isPlaying;
103 long curPosition;
104 long curLength;
105 char curView;
106
107 MediaPlayerDecoder *decoder;
108 MediaPlayerDecoder *libmpeg3decoder;
109
110 void loadPlugins();
111 void readConfig( Config& cfg );
112 void writeConfig( Config& cfg ) const;
113};
114
115
116#endif // MEDIA_PLAYER_STATE_H
117
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 @@
1 TEMPLATE= app
2 CONFIG = qt warn_on release
3 DESTDIR = $(QPEDIR)/bin
4 HEADERS = loopcontrol.h mediaplayerplugininterface.h playlistselection.h mediaplayerstate.h \
5 videowidget.h audiowidget.h playlistwidget.h mediaplayer.h audiodevice.h
6 SOURCES = main.cpp \
7 loopcontrol.cpp playlistselection.cpp mediaplayerstate.cpp \
8 videowidget.cpp audiowidget.cpp playlistwidget.cpp mediaplayer.cpp audiodevice.cpp
9 TARGET = mpegplayer
10 INCLUDEPATH+= $(QPEDIR)/include
11 DEPENDPATH+= $(QPEDIR)/include
12LIBS += -lqpe -lpthread
13
14 # INTERFACES=
15# INCLUDEPATH += $(QPEDIR)/include
16# CONFIG+=static
17# TMAKE_CXXFLAGS += -DQPIM_STANDALONE
18 # LIBS += libmpeg3/libmpeg3.a -lpthread
19 # LIBS += $(QPEDIR)/plugins/codecs/liblibmadplugin.so
20
21TRANSLATIONS = ../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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#include <qpe/applnk.h>
21#include <qpe/resource.h>
22#include <qpainter.h>
23#include <qimage.h>
24#include <qheader.h>
25#include <qlistview.h>
26#include <qlist.h>
27#include <qpixmap.h>
28
29#include "playlistselection.h"
30
31#include <stdlib.h>
32
33
34class PlayListSelectionItem : public QListViewItem {
35public:
36 PlayListSelectionItem( QListView *parent, const DocLnk *f ) : QListViewItem( parent ), fl( f ) {
37 setText( 0, f->name() );
38 setPixmap( 0, f->pixmap() );
39 }
40
41 ~PlayListSelectionItem() {
42 };
43
44 const DocLnk *file() const { return fl; }
45
46private:
47 const DocLnk *fl;
48};
49
50
51PlayListSelection::PlayListSelection( QWidget *parent, const char *name )
52 : QListView( parent, name )
53{
54#ifdef USE_PLAYLIST_BACKGROUND
55 setStaticBackground( TRUE );
56 setBackgroundPixmap( Resource::loadPixmap( "mpegplayer/background" ) );
57#endif
58 setAllColumnsShowFocus( TRUE );
59 addColumn( tr( "Playlist Selection" ) );
60 header()->hide();
61 setSorting( -1, FALSE );
62}
63
64
65PlayListSelection::~PlayListSelection() {
66}
67
68
69#ifdef USE_PLAYLIST_BACKGROUND
70void PlayListSelection::drawBackground( QPainter *p, const QRect &r ) {
71 p->fillRect( r, QBrush( white ) );
72 QImage logo = Resource::loadImage( "mpegplayer/background" );
73 if ( !logo.isNull() )
74 p->drawImage( (width() - logo.width()) / 2, (height() - logo.height()) / 2, logo );
75}
76#endif
77
78
79void PlayListSelection::contentsMouseMoveEvent( QMouseEvent *event ) {
80 if ( event->state() == QMouseEvent::LeftButton ) {
81 QListViewItem *currentItem = selectedItem();
82 QListViewItem *itemUnder = itemAt( QPoint( event->pos().x(), event->pos().y() - contentsY() ) );
83 if ( currentItem && currentItem->itemAbove() == itemUnder )
84 moveSelectedUp();
85 else if ( currentItem && currentItem->itemBelow() == itemUnder )
86 moveSelectedDown();
87 }
88}
89
90
91const DocLnk *PlayListSelection::current() {
92 PlayListSelectionItem *item = (PlayListSelectionItem *)selectedItem();
93 if ( item )
94 return item->file();
95 return NULL;
96}
97
98
99void PlayListSelection::addToSelection( const DocLnk &lnk ) {
100 PlayListSelectionItem *item = new PlayListSelectionItem( this, new DocLnk( lnk ) );
101 QListViewItem *current = selectedItem();
102 if ( current )
103 item->moveItem( current );
104 setSelected( item, TRUE );
105 ensureItemVisible( selectedItem() );
106}
107
108
109void PlayListSelection::removeSelected() {
110 QListViewItem *item = selectedItem();
111 if ( item )
112 delete item;
113 setSelected( currentItem(), TRUE );
114 ensureItemVisible( selectedItem() );
115}
116
117
118void PlayListSelection::moveSelectedUp() {
119 QListViewItem *item = selectedItem();
120 if ( item && item->itemAbove() )
121 item->itemAbove()->moveItem( item );
122 ensureItemVisible( selectedItem() );
123}
124
125
126void PlayListSelection::moveSelectedDown() {
127 QListViewItem *item = selectedItem();
128 if ( item && item->itemBelow() )
129 item->moveItem( item->itemBelow() );
130 ensureItemVisible( selectedItem() );
131}
132
133
134bool PlayListSelection::prev() {
135 QListViewItem *item = selectedItem();
136 if ( item && item->itemAbove() )
137 setSelected( item->itemAbove(), TRUE );
138 else
139 return FALSE;
140 ensureItemVisible( selectedItem() );
141 return TRUE;
142}
143
144
145bool PlayListSelection::next() {
146 QListViewItem *item = selectedItem();
147 if ( item && item->itemBelow() )
148 setSelected( item->itemBelow(), TRUE );
149 else
150 return FALSE;
151 ensureItemVisible( selectedItem() );
152 return TRUE;
153}
154
155
156bool PlayListSelection::first() {
157 QListViewItem *item = firstChild();
158 if ( item )
159 setSelected( item, TRUE );
160 else
161 return FALSE;
162 ensureItemVisible( selectedItem() );
163 return TRUE;
164}
165
166
167bool PlayListSelection::last() {
168 QListViewItem *prevItem = NULL;
169 QListViewItem *item = firstChild();
170 while ( ( item = item->nextSibling() ) )
171 prevItem = item;
172 if ( prevItem )
173 setSelected( prevItem, TRUE );
174 else
175 return FALSE;
176 ensureItemVisible( selectedItem() );
177 return TRUE;
178}
179
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef PLAY_LIST_SELECTION_H
21#define PLAY_LIST_SELECTION_H
22
23
24#include <qlist.h>
25#include <qlistview.h>
26#include <qpe/applnk.h>
27
28
29class PlayListSelection : public QListView {
30 Q_OBJECT
31public:
32 PlayListSelection( QWidget *parent, const char *name=0 );
33 ~PlayListSelection();
34
35 const DocLnk *current(); // retrieve the current playlist entry (media file link)
36
37public slots:
38 void addToSelection( const DocLnk & ); // Add a media file to the playlist
39 void removeSelected(); // Remove a media file from the playlist
40 void moveSelectedUp(); // Move the media file up the playlist so it is played earlier
41 void moveSelectedDown(); // Move the media file down the playlist so it is played later
42 bool prev();
43 bool next();
44 bool first();
45 bool last();
46
47protected:
48 virtual void contentsMouseMoveEvent(QMouseEvent *);
49#ifdef USE_PLAYLIST_BACKGROUND
50 virtual void drawBackground( QPainter *p, const QRect &r );
51 virtual void paintEmptyArea( QPainter *p, const QRect &r ) { drawBackground( p, r ); };
52#endif
53
54private:
55 QList<DocLnk> selectedList;
56 const DocLnk *lnk;
57};
58
59
60#endif // PLAY_LIST_SELECTION_H
61
62
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#include <qpe/qpemenubar.h>
21#include <qpe/qpetoolbar.h>
22#include <qpe/fileselector.h>
23#include <qpe/applnk.h>
24#include <qpe/config.h>
25#include <qpe/global.h>
26#include <qpe/resource.h>
27#include <qaction.h>
28#include <qimage.h>
29#include <qfile.h>
30#include <qlayout.h>
31#include <qlabel.h>
32#include <qlist.h>
33#include <qlistbox.h>
34#include <qmainwindow.h>
35#include <qmessagebox.h>
36#include <qtoolbutton.h>
37
38#include "playlistselection.h"
39#include "playlistwidget.h"
40#include "mediaplayerstate.h"
41
42#include <stdlib.h>
43
44
45extern MediaPlayerState *mediaPlayerState;
46
47
48class PlayListWidgetPrivate {
49public:
50 QToolButton *tbPlay;
51 QToolButton *tbFull;
52 QToolButton *tbLoop;
53 QToolButton *tbScale;
54 QToolButton *tbShuffle;
55
56 QFrame *playListFrame;
57 FileSelector *files;
58 PlayListSelection *selectedFiles;
59 bool setDocumentUsed;
60 DocLnk *current;
61};
62
63
64class ToolButton : public QToolButton {
65public:
66 ToolButton( QWidget *parent, const char *name, const QString& icon, QObject *handler, const QString& slot, bool t = FALSE )
67 : QToolButton( parent, name ) {
68 setTextLabel( name );
69 setPixmap( Resource::loadPixmap( icon ) );
70 setAutoRaise( TRUE );
71 setFocusPolicy( QWidget::NoFocus );
72 setToggleButton( t );
73 connect( this, t ? SIGNAL( toggled(bool) ) : SIGNAL( clicked() ), handler, slot );
74 QPEMenuToolFocusManager::manager()->addWidget( this );
75 }
76};
77
78
79class MenuItem : public QAction {
80public:
81 MenuItem( QWidget *parent, const QString& text, QObject *handler, const QString& slot )
82 : QAction( text, QString::null, 0, 0 ) {
83 connect( this, SIGNAL( activated() ), handler, slot );
84 addTo( parent );
85 }
86};
87
88
89PlayListWidget::PlayListWidget( QWidget* parent, const char* name, WFlags fl )
90 : QMainWindow( parent, name, fl ) {
91
92 d = new PlayListWidgetPrivate;
93 d->setDocumentUsed = FALSE;
94 d->current = NULL;
95
96 setBackgroundMode( PaletteButton );
97
98 setCaption( tr("MediaPlayer") );
99 setIcon( Resource::loadPixmap( "MPEGPlayer" ) );
100
101 setToolBarsMovable( FALSE );
102
103 // Create Toolbar
104 QPEToolBar *toolbar = new QPEToolBar( this );
105 toolbar->setHorizontalStretchable( TRUE );
106
107 // Create Menubar
108 QPEMenuBar *menu = new QPEMenuBar( toolbar );
109 menu->setMargin( 0 );
110
111 QPEToolBar *bar = new QPEToolBar( this );
112 bar->setLabel( tr( "Play Operations" ) );
113#ifdef BUTTONS_ON_TOOLBAR
114 d->tbPlay = new ToolButton( bar, tr( "Play" ), "mpegplayer/play", mediaPlayerState, SLOT(setPlaying(bool)), TRUE );
115 d->tbShuffle = new ToolButton( bar, tr( "Randomize" ), "mpegplayer/shuffle", mediaPlayerState, SLOT(setShuffled(bool)), TRUE );
116#endif
117 d->tbLoop = new ToolButton( bar, tr( "Loop" ), "mpegplayer/loop", mediaPlayerState, SLOT(setLooping(bool)), TRUE );
118 d->tbFull = new ToolButton( bar, tr( "Fullscreen" ), "fullscreen", mediaPlayerState, SLOT(setFullscreen(bool)), TRUE );
119 d->tbScale = new ToolButton( bar, tr( "Scale" ), "mpegplayer/scale", mediaPlayerState, SLOT(setScaled(bool)), TRUE );
120
121 QPopupMenu *pmPlayList = new QPopupMenu( this );
122 menu->insertItem( tr( "PlayList" ), pmPlayList );
123 new MenuItem( pmPlayList, tr( "Toggle PlayList" ), mediaPlayerState, SLOT( togglePlaylist() ) );
124 new MenuItem( pmPlayList, tr( "Clear List" ), this, SLOT( clearList() ) );
125 new MenuItem( pmPlayList, tr( "Add all music files" ), this, SLOT( addAllMusicToList() ) );
126 new MenuItem( pmPlayList, tr( "Add all video files" ), this, SLOT( addAllVideoToList() ) );
127 new MenuItem( pmPlayList, tr( "Add all files" ), this, SLOT( addAllToList() ) );
128#ifdef CAN_SAVE_LOAD_PLAYLISTS
129 new MenuItem( pmPlayList, tr( "Save PlayList" ), this, SLOT( saveList() ) );
130 new MenuItem( pmPlayList, tr( "Load PlayList" ), this, SLOT( loadList() ) );
131#endif
132
133 QVBox *vbox5 = new QVBox( this ); vbox5->setBackgroundMode( PaletteButton );
134
135 // Add the playlist area
136 QVBox *vbox3 = new QVBox( vbox5 ); vbox3->setBackgroundMode( PaletteButton );
137 d->playListFrame = vbox3;
138
139 QLabel *plString = new QLabel( tr(" PlayList"), vbox3 );
140 plString->setBackgroundMode( QButton::PaletteButton );
141 plString->setFont( QFont( "Helvetica", 8, QFont::Bold ) );
142
143 QHBox *hbox2 = new QHBox( vbox3 ); hbox2->setBackgroundMode( PaletteButton );
144 d->selectedFiles = new PlayListSelection( hbox2 );
145 QVBox *vbox1 = new QVBox( hbox2 ); vbox1->setBackgroundMode( PaletteButton );
146
147#ifndef BUTTONS_ON_TOOLBAR
148 d->tbPlay = new ToolButton( vbox1, tr( "Play" ), "mpegplayer/play", mediaPlayerState, SLOT(setPlaying(bool)), TRUE );
149 QVBox *stretch1 = new QVBox( vbox1 ); stretch1->setBackgroundMode( PaletteButton ); // add stretch
150#endif
151 new ToolButton( vbox1, tr( "Move Up" ), "mpegplayer/up", d->selectedFiles, SLOT(moveSelectedUp()) );
152 new ToolButton( vbox1, tr( "Remove" ), "mpegplayer/cut", d->selectedFiles, SLOT(removeSelected()) );
153 new ToolButton( vbox1, tr( "Move Down" ), "mpegplayer/down", d->selectedFiles, SLOT(moveSelectedDown()) );
154 QVBox *stretch2 = new QVBox( vbox1 ); stretch2->setBackgroundMode( PaletteButton ); // add stretch
155#ifndef BUTTONS_ON_TOOLBAR
156 d->tbShuffle = new ToolButton( vbox1, tr( "Randomize" ), "mpegplayer/shuffle", mediaPlayerState, SLOT(setShuffled(bool)), TRUE );
157#endif
158
159 // add the library area
160 QVBox *vbox4 = new QVBox( vbox5 ); vbox4->setBackgroundMode( PaletteButton );
161
162 QLabel *libString = new QLabel( tr(" Media Library"), vbox4 );
163 libString->setBackgroundMode( QButton::PaletteButton );
164 libString->setFont( QFont( "Helvetica", 8, QFont::Bold ) );
165
166 QHBox *hbox6 = new QHBox( vbox4 ); hbox6->setBackgroundMode( PaletteButton );
167 d->files = new FileSelector( "video/*;audio/*", hbox6, "Find Media Files", FALSE, FALSE );
168 d->files->setBackgroundMode( PaletteButton );
169 QVBox *vbox7 = new QVBox( hbox6 ); vbox7->setBackgroundMode( PaletteButton );
170
171#ifdef SIDE_BUTTONS
172 new ToolButton( vbox7, tr( "Add to Playlist" ), "mpegplayer/add_to_playlist", d->selectedFiles, SLOT(addSelected()) );
173 new ToolButton( vbox7, tr( "Remove from Playlist" ), "mpegplayer/remove_from_playlist", d->selectedFiles, SLOT(removeSelected()) );
174 QVBox *stretch3 = new QVBox( vbox1 ); stretch3->setBackgroundMode( PaletteButton ); // add stretch
175#endif
176
177 connect( d->files, SIGNAL( fileSelected( const DocLnk & ) ), this, SLOT( addToSelection( const DocLnk & ) ) );
178 connect( mediaPlayerState, SIGNAL( playingToggled( bool ) ), d->tbPlay, SLOT( setOn( bool ) ) );
179 connect( mediaPlayerState, SIGNAL( loopingToggled( bool ) ), d->tbLoop, SLOT( setOn( bool ) ) );
180 connect( mediaPlayerState, SIGNAL( shuffledToggled( bool ) ), d->tbShuffle, SLOT( setOn( bool ) ) );
181 connect( mediaPlayerState, SIGNAL( fullscreenToggled( bool ) ), d->tbFull, SLOT( setOn( bool ) ) );
182 connect( mediaPlayerState, SIGNAL( scaledToggled( bool ) ), d->tbScale, SLOT( setOn( bool ) ) );
183 connect( mediaPlayerState, SIGNAL( fullscreenToggled( bool ) ), d->tbScale, SLOT( setEnabled( bool ) ) );
184 connect( mediaPlayerState, SIGNAL( playlistToggled( bool ) ), this, SLOT( setPlaylist( bool ) ) );
185
186 setCentralWidget( vbox5 );
187
188 Config cfg( "MediaPlayer" );
189 readConfig( cfg );
190
191 initializeStates();
192}
193
194
195PlayListWidget::~PlayListWidget() {
196 Config cfg( "MediaPlayer" );
197 writeConfig( cfg );
198
199 if ( d->current )
200 delete d->current;
201 delete d;
202}
203
204
205void PlayListWidget::initializeStates() {
206 d->tbPlay->setOn( mediaPlayerState->playing() );
207 d->tbLoop->setOn( mediaPlayerState->looping() );
208 d->tbShuffle->setOn( mediaPlayerState->shuffled() );
209 d->tbFull->setOn( mediaPlayerState->fullscreen() );
210 d->tbScale->setOn( mediaPlayerState->scaled() );
211 d->tbScale->setEnabled( mediaPlayerState->fullscreen() );
212 setPlaylist( mediaPlayerState->playlist() );
213}
214
215
216void PlayListWidget::readConfig( Config& cfg ) {
217 cfg.setGroup("PlayList");
218
219 int noOfFiles = cfg.readNumEntry("NumberOfFiles", 0 );
220
221 for ( int i = 0; i < noOfFiles; i++ ) {
222 QString entryName;
223 entryName.sprintf( "File%i", i + 1 );
224 QString linkFile = cfg.readEntry( entryName );
225 DocLnk lnk( linkFile );
226 if ( lnk.isValid() )
227 d->selectedFiles->addToSelection( lnk );
228
229 }
230}
231
232
233void PlayListWidget::writeConfig( Config& cfg ) const {
234 cfg.setGroup("PlayList");
235
236 int noOfFiles = 0;
237
238 d->selectedFiles->first();
239 do {
240 const DocLnk *lnk = d->selectedFiles->current();
241 if ( lnk ) {
242 QString entryName;
243 entryName.sprintf( "File%i", noOfFiles + 1 );
244 cfg.writeEntry( entryName, lnk->linkFile() );
245 // if this link does exist, add it so we have the file
246 // next time...
247 if ( !QFile::exists( lnk->linkFile() ) ) {
248 // the way writing lnks doesn't really check for out
249 // of disk space, but check it anyway.
250 if ( !lnk->writeLink() ) {
251 QMessageBox::critical( 0, tr("Out of space"),
252 tr( "There was a problem saving "
253 "the playlist.\n"
254 "Your playlist "
255 "may be missing some entries\n"
256 "the next time you start it." )
257 );
258 }
259 }
260 noOfFiles++;
261 }
262 } while ( d->selectedFiles->next() );
263
264 cfg.writeEntry("NumberOfFiles", noOfFiles );
265}
266
267
268void PlayListWidget::addToSelection( const DocLnk& lnk ) {
269 d->setDocumentUsed = FALSE;
270 if ( mediaPlayerState->playlist() )
271 d->selectedFiles->addToSelection( lnk );
272 else
273 mediaPlayerState->setPlaying( TRUE );
274}
275
276
277void PlayListWidget::clearList() {
278 while ( first() )
279 d->selectedFiles->removeSelected();
280}
281
282
283void PlayListWidget::addAllToList() {
284 DocLnkSet files;
285 Global::findDocuments(&files, "video/*;audio/*");
286 QListIterator<DocLnk> dit( files.children() );
287 for ( ; dit.current(); ++dit )
288 d->selectedFiles->addToSelection( **dit );
289}
290
291
292void PlayListWidget::addAllMusicToList() {
293 DocLnkSet files;
294 Global::findDocuments(&files, "audio/*");
295 QListIterator<DocLnk> dit( files.children() );
296 for ( ; dit.current(); ++dit )
297 d->selectedFiles->addToSelection( **dit );
298}
299
300
301void PlayListWidget::addAllVideoToList() {
302 DocLnkSet files;
303 Global::findDocuments(&files, "video/*");
304 QListIterator<DocLnk> dit( files.children() );
305 for ( ; dit.current(); ++dit )
306 d->selectedFiles->addToSelection( **dit );
307}
308
309
310void PlayListWidget::setDocument(const QString& fileref) {
311 if ( fileref.isNull() ) {
312 QMessageBox::critical( 0, tr( "Invalid File" ), tr( "There was a problem in getting the file." ) );
313 return;
314 }
315 if ( mediaPlayerState->playlist() )
316 addToSelection( DocLnk( fileref ) );
317 else {
318 d->setDocumentUsed = TRUE;
319 if ( d->current )
320 delete d->current;
321 d->current = new DocLnk( fileref );
322 }
323 mediaPlayerState->setPlaying( FALSE );
324 mediaPlayerState->setPlaying( TRUE );
325}
326
327
328void PlayListWidget::setActiveWindow() {
329 // When we get raised we need to ensure that it switches views
330 char origView = mediaPlayerState->view();
331 mediaPlayerState->setView( 'l' ); // invalidate
332 mediaPlayerState->setView( origView ); // now switch back
333}
334
335
336void PlayListWidget::useSelectedDocument() {
337 d->setDocumentUsed = FALSE;
338}
339
340
341const DocLnk *PlayListWidget::current() {
342 if ( mediaPlayerState->playlist() )
343 return d->selectedFiles->current();
344 else if ( d->setDocumentUsed && d->current ) {
345 return d->current;
346 } else
347 return d->files->selected();
348}
349
350
351bool PlayListWidget::prev() {
352 if ( mediaPlayerState->playlist() ) {
353 if ( mediaPlayerState->shuffled() ) {
354 const DocLnk *cur = current();
355 int j = 1 + (int)(97.0 * rand() / (RAND_MAX + 1.0));
356 for ( int i = 0; i < j; i++ ) {
357 if ( !d->selectedFiles->next() )
358 d->selectedFiles->first();
359 }
360 if ( cur == current() )
361 if ( !d->selectedFiles->next() )
362 d->selectedFiles->first();
363 return TRUE;
364 } else {
365 if ( !d->selectedFiles->prev() ) {
366 if ( mediaPlayerState->looping() ) {
367 return d->selectedFiles->last();
368 } else {
369 return FALSE;
370 }
371 }
372 return TRUE;
373 }
374 } else {
375 return mediaPlayerState->looping();
376 }
377}
378
379
380bool PlayListWidget::next() {
381 if ( mediaPlayerState->playlist() ) {
382 if ( mediaPlayerState->shuffled() ) {
383 return prev();
384 } else {
385 if ( !d->selectedFiles->next() ) {
386 if ( mediaPlayerState->looping() ) {
387 return d->selectedFiles->first();
388 } else {
389 return FALSE;
390 }
391 }
392 return TRUE;
393 }
394 } else {
395 return mediaPlayerState->looping();
396 }
397}
398
399
400bool PlayListWidget::first() {
401 if ( mediaPlayerState->playlist() )
402 return d->selectedFiles->first();
403 else
404 return mediaPlayerState->looping();
405}
406
407
408bool PlayListWidget::last() {
409 if ( mediaPlayerState->playlist() )
410 return d->selectedFiles->last();
411 else
412 return mediaPlayerState->looping();
413}
414
415
416void PlayListWidget::saveList() {
417 QString filename;
418// pseudo code
419// filename = QLineEdit->getText();
420 Config cfg( filename + ".playlist" );
421 writeConfig( cfg );
422}
423
424
425void PlayListWidget::loadList() {
426 QString filename;
427// pseudo code
428// filename = FileSelector->openFile( "*.playlist" );
429 Config cfg( filename + ".playlist" );
430 readConfig( cfg );
431}
432
433
434void PlayListWidget::setPlaylist( bool shown ) {
435 if ( shown )
436 d->playListFrame->show();
437 else
438 d->playListFrame->hide();
439}
440
441
442void PlayListWidget::setView( char view ) {
443 if ( view == 'l' )
444 showMaximized();
445 else
446 hide();
447}
448
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef PLAY_LIST_WIDGET_H
21#define PLAY_LIST_WIDGET_H
22
23
24#include <qmainwindow.h>
25#include <qpe/applnk.h>
26
27
28class PlayListWidgetPrivate;
29class Config;
30
31
32class PlayListWidget : public QMainWindow {
33 Q_OBJECT
34public:
35 PlayListWidget( QWidget* parent=0, const char* name=0, WFlags fl=0 );
36 ~PlayListWidget();
37
38 // retrieve the current playlist entry (media file link)
39 const DocLnk *current();
40 void useSelectedDocument();
41
42public slots:
43 void setDocument( const QString& fileref );
44 void addToSelection( const DocLnk& ); // Add a media file to the playlist
45 void setActiveWindow(); // need to handle this to show the right view
46 void setPlaylist( bool ); // Show/Hide the playlist
47 void setView( char );
48 void clearList();
49 void addAllToList();
50 void addAllMusicToList();
51 void addAllVideoToList();
52 void saveList(); // Save the playlist
53 void loadList(); // Load a playlist
54 bool first();
55 bool last();
56 bool next();
57 bool prev();
58
59private:
60 void initializeStates();
61 void readConfig( Config& cfg );
62 void writeConfig( Config& cfg ) const;
63 PlayListWidgetPrivate *d; // Private implementation data
64};
65
66
67#endif // PLAY_LIST_WIDGET_H
68
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 @@
1Files: 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
2Priority: optional
3Section: qpe/applications
4Maintainer: John Ryland <jryland@trolltech.com>
5Architecture: arm
6Version: $QPE_VERSION-3
7Depends: qpe-base ($QPE_VERSION)
8Description: MPEG video/audio player
9 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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#include <qpe/resource.h>
21#include <qwidget.h>
22#include <qpainter.h>
23#include <qpixmap.h>
24#include <qslider.h>
25#include <qdrawutil.h>
26#include "videowidget.h"
27#include "mediaplayerplugininterface.h"
28#include "mediaplayerstate.h"
29
30
31#ifdef Q_WS_QWS
32# define USE_DIRECT_PAINTER
33# include <qdirectpainter_qws.h>
34# include <qgfxraster_qws.h>
35#endif
36
37
38extern MediaPlayerState *mediaPlayerState;
39
40
41static const int xo = 2; // movable x offset
42static const int yo = 0; // movable y offset
43
44
45struct MediaButton {
46 int xPos, yPos;
47 bool isToggle, isHeld, isDown;
48 int controlType;
49};
50
51
52// Layout information for the videoButtons (and if it is a toggle button or not)
53MediaButton videoButtons[] = {
54 { 5+0*32+xo, 200+yo, FALSE, FALSE, FALSE, 4 }, // previous
55 { 5+1*32+xo, 200+yo, FALSE, FALSE, FALSE, 1 }, // stop
56 { 5+2*32+xo, 200+yo, TRUE, FALSE, FALSE, 0 }, // play
57 { 5+3*32+xo, 200+yo, TRUE, FALSE, FALSE, 2 }, // pause
58 { 5+4*32+xo, 200+yo, FALSE, FALSE, FALSE, 3 }, // next
59 { 5+5*32+xo, 200+yo, FALSE, FALSE, FALSE, 8 }, // playlist
60 { 5+6*32+xo, 200+yo, TRUE, FALSE, FALSE, 9 } // fullscreen
61};
62
63
64static const int numButtons = (sizeof(videoButtons)/sizeof(MediaButton));
65
66
67VideoWidget::VideoWidget(QWidget* parent, const char* name, WFlags f) :
68 QWidget( parent, name, f ), scaledWidth( 0 ), scaledHeight( 0 ) {
69 setCaption( tr("MediaPlayer") );
70 setBackgroundPixmap( Resource::loadPixmap( "mpegplayer/metalFinish" ) );
71 pixmaps[0] = new QPixmap( Resource::loadPixmap( "mpegplayer/mediaButton0a" ) );
72 pixmaps[1] = new QPixmap( Resource::loadPixmap( "mpegplayer/mediaButton0b" ) );
73 pixmaps[2] = new QPixmap( Resource::loadPixmap( "mpegplayer/mediaControls0" ) );
74 currentFrame = new QImage( 220 + 2, 160, (QPixmap::defaultDepth() == 16) ? 16 : 32 );
75
76 slider = new QSlider( Qt::Horizontal, this );
77 slider->setMinValue( 0 );
78 slider->setMaxValue( 1 );
79 slider->setBackgroundPixmap( Resource::loadPixmap( "mpegplayer/metalFinish" ) );
80 slider->setFocusPolicy( QWidget::NoFocus );
81 slider->setGeometry( QRect( 7, 250, 220, 20 ) );
82
83 connect( slider, SIGNAL( sliderPressed() ), this, SLOT( sliderPressed() ) );
84 connect( slider, SIGNAL( sliderReleased() ), this, SLOT( sliderReleased() ) );
85
86 connect( mediaPlayerState, SIGNAL( lengthChanged(long) ), this, SLOT( setLength(long) ) );
87 connect( mediaPlayerState, SIGNAL( positionChanged(long) ),this, SLOT( setPosition(long) ) );
88 connect( mediaPlayerState, SIGNAL( positionUpdated(long) ),this, SLOT( setPosition(long) ) );
89 connect( mediaPlayerState, SIGNAL( viewChanged(char) ), this, SLOT( setView(char) ) );
90 connect( mediaPlayerState, SIGNAL( pausedToggled(bool) ), this, SLOT( setPaused(bool) ) );
91 connect( mediaPlayerState, SIGNAL( playingToggled(bool) ), this, SLOT( setPlaying(bool) ) );
92
93 // Intialise state
94 setLength( mediaPlayerState->length() );
95 setPosition( mediaPlayerState->position() );
96 setFullscreen( mediaPlayerState->fullscreen() );
97 setPaused( mediaPlayerState->paused() );
98 setPlaying( mediaPlayerState->playing() );
99}
100
101
102VideoWidget::~VideoWidget() {
103 for ( int i = 0; i < 3; i++ )
104 delete pixmaps[i];
105 delete currentFrame;
106}
107
108
109static bool videoSliderBeingMoved = FALSE;
110
111
112void VideoWidget::sliderPressed() {
113 videoSliderBeingMoved = TRUE;
114}
115
116
117void VideoWidget::sliderReleased() {
118 videoSliderBeingMoved = FALSE;
119 if ( slider->width() == 0 )
120 return;
121 long val = long((double)slider->value() * mediaPlayerState->length() / slider->width());
122 mediaPlayerState->setPosition( val );
123}
124
125
126void VideoWidget::setPosition( long i ) {
127 updateSlider( i, mediaPlayerState->length() );
128}
129
130
131void VideoWidget::setLength( long max ) {
132 updateSlider( mediaPlayerState->position(), max );
133}
134
135
136void VideoWidget::setView( char view ) {
137 if ( view == 'v' ) {
138 makeVisible();
139 } else {
140 // Effectively blank the view next time we show it so it looks nicer
141 scaledWidth = 0;
142 scaledHeight = 0;
143 hide();
144 }
145}
146
147
148void VideoWidget::updateSlider( long i, long max ) {
149 // Will flicker too much if we don't do this
150 if ( max == 0 )
151 return;
152 int width = slider->width();
153 int val = int((double)i * width / max);
154 if ( !mediaPlayerState->fullscreen() && !videoSliderBeingMoved ) {
155 if ( slider->value() != val )
156 slider->setValue( val );
157 if ( slider->maxValue() != width )
158 slider->setMaxValue( width );
159 }
160}
161
162
163void VideoWidget::setToggleButton( int i, bool down ) {
164 if ( down != videoButtons[i].isDown )
165 toggleButton( i );
166}
167
168
169void VideoWidget::toggleButton( int i ) {
170 videoButtons[i].isDown = !videoButtons[i].isDown;
171 QPainter p(this);
172 paintButton ( &p, i );
173}
174
175
176void VideoWidget::paintButton( QPainter *p, int i ) {
177 int x = videoButtons[i].xPos;
178 int y = videoButtons[i].yPos;
179 int offset = 10 + videoButtons[i].isDown;
180 p->drawPixmap( x, y, *pixmaps[videoButtons[i].isDown] );
181 p->drawPixmap( x + 1 + offset, y + offset, *pixmaps[2], 9 * videoButtons[i].controlType, 0, 9, 9 );
182}
183
184
185void VideoWidget::mouseMoveEvent( QMouseEvent *event ) {
186 for ( int i = 0; i < numButtons; i++ ) {
187 int x = videoButtons[i].xPos;
188 int y = videoButtons[i].yPos;
189 if ( event->state() == QMouseEvent::LeftButton ) {
190 // The test to see if the mouse click is inside the circular button or not
191 // (compared with the radius squared to avoid a square-root of our distance)
192 int radius = 16;
193 QPoint center = QPoint( x + radius, y + radius );
194 QPoint dXY = center - event->pos();
195 int dist = dXY.x() * dXY.x() + dXY.y() * dXY.y();
196 bool isOnButton = dist <= (radius * radius);
197 if ( isOnButton != videoButtons[i].isHeld ) {
198 videoButtons[i].isHeld = isOnButton;
199 toggleButton(i);
200 }
201 } else {
202 if ( videoButtons[i].isHeld ) {
203 videoButtons[i].isHeld = FALSE;
204 if ( !videoButtons[i].isToggle )
205 setToggleButton( i, FALSE );
206 switch (i) {
207 case VideoPlay: mediaPlayerState->setPlaying(videoButtons[i].isDown); return;
208 case VideoStop: mediaPlayerState->setPlaying(FALSE); return;
209 case VideoPause: mediaPlayerState->setPaused(videoButtons[i].isDown); return;
210 case VideoNext: mediaPlayerState->setNext(); return;
211 case VideoPrevious: mediaPlayerState->setPrev(); return;
212 case VideoPlayList: mediaPlayerState->setList(); return;
213 case VideoFullscreen: mediaPlayerState->setFullscreen( TRUE ); makeVisible(); return;
214 }
215 }
216 }
217 }
218}
219
220
221void VideoWidget::mousePressEvent( QMouseEvent *event ) {
222 mouseMoveEvent( event );
223}
224
225
226void VideoWidget::mouseReleaseEvent( QMouseEvent *event ) {
227 if ( mediaPlayerState->fullscreen() ) {
228 mediaPlayerState->setFullscreen( FALSE );
229 makeVisible();
230 } else {
231 mouseMoveEvent( event );
232 }
233}
234
235
236void VideoWidget::makeVisible() {
237 if ( mediaPlayerState->fullscreen() ) {
238 setBackgroundMode( QWidget::NoBackground );
239 showFullScreen();
240 resize( qApp->desktop()->size() );
241 slider->hide();
242 } else {
243 setBackgroundPixmap( Resource::loadPixmap( "mpegplayer/metalFinish" ) );
244 showNormal();
245 showMaximized();
246 slider->show();
247 }
248}
249
250
251void VideoWidget::paintEvent( QPaintEvent * ) {
252 QPainter p( this );
253
254 if ( mediaPlayerState->fullscreen() ) {
255 // Clear the background
256 p.setBrush( QBrush( Qt::black ) );
257 p.drawRect( rect() );
258
259 // Draw the current frame
260 //p.drawImage( ); // If using directpainter we won't have a copy except whats on the screen
261 } else {
262 // draw border
263 qDrawShadePanel( &p, 4, 15, 230, 170, colorGroup(), TRUE, 5, NULL );
264
265 // Clear the movie screen first
266 p.setBrush( QBrush( Qt::black ) );
267 p.drawRect( 9, 20, 220, 160 );
268
269 // draw current frame (centrally positioned from scaling to maintain aspect ratio)
270 p.drawImage( 9 + (220 - scaledWidth) / 2, 20 + (160 - scaledHeight) / 2, *currentFrame, 0, 0, scaledWidth, scaledHeight );
271
272 // draw the buttons
273 for ( int i = 0; i < numButtons; i++ )
274 paintButton( &p, i );
275
276 // draw the slider
277 slider->repaint( TRUE );
278 }
279}
280
281
282void VideoWidget::closeEvent( QCloseEvent* ) {
283 mediaPlayerState->setList();
284}
285
286
287bool VideoWidget::playVideo() {
288 bool result = FALSE;
289
290 int stream = 0;
291
292 int sw = mediaPlayerState->curDecoder()->videoWidth( stream );
293 int sh = mediaPlayerState->curDecoder()->videoHeight( stream );
294 int dd = QPixmap::defaultDepth();
295 int w = height();
296 int h = width();
297
298 ColorFormat format = (dd == 16) ? RGB565 : BGRA8888;
299
300 if ( mediaPlayerState->fullscreen() ) {
301#ifdef USE_DIRECT_PAINTER
302 QDirectPainter p(this);
303
304 if ( ( qt_screen->transformOrientation() == 3 ) &&
305 ( ( dd == 16 ) || ( dd == 32 ) ) && ( p.numRects() == 1 ) ) {
306
307 w = 320;
308 h = 240;
309
310 if ( mediaPlayerState->scaled() ) {
311 // maintain aspect ratio
312 if ( w * sh > sw * h )
313 w = sw * h / sh;
314 else
315 h = sh * w / sw;
316 } else {
317 w = sw;
318 h = sh;
319 }
320
321 w--; // we can't allow libmpeg to overwrite.
322 QPoint roff = qt_screen->mapToDevice( p.offset(), QSize( qt_screen->width(), qt_screen->height() ) );
323
324 int ox = roff.x() - height() + 2 + (height() - w) / 2;
325 int oy = roff.y() + (width() - h) / 2;
326 int sx = 0, sy = 0;
327
328 uchar* fp = p.frameBuffer() + p.lineStep() * oy;
329 fp += dd * ox / 8;
330 uchar **jt = new uchar*[h];
331 for ( int i = h; i; i-- ) {
332 jt[h - i] = fp;
333 fp += p.lineStep();
334 }
335
336 result = mediaPlayerState->curDecoder()->videoReadScaledFrame( jt, sx, sy, sw, sh, w, h, format, 0) == 0;
337
338 delete [] jt;
339 } else {
340#endif
341 QPainter p(this);
342
343 w = 320;
344 h = 240;
345
346 if ( mediaPlayerState->scaled() ) {
347 // maintain aspect ratio
348 if ( w * sh > sw * h )
349 w = sw * h / sh;
350 else
351 h = sh * w / sw;
352 } else {
353 w = sw;
354 h = sh;
355 }
356
357 int bytes = ( dd == 16 ) ? 2 : 4;
358 QImage tempFrame( w, h, bytes << 3 );
359 result = mediaPlayerState->curDecoder()->videoReadScaledFrame( tempFrame.jumpTable(),
360 0, 0, sw, sh, w, h, format, 0) == 0;
361 if ( result && mediaPlayerState->fullscreen() ) {
362
363 int rw = h, rh = w;
364 QImage rotatedFrame( rw, rh, bytes << 3 );
365
366 ushort* in = (ushort*)tempFrame.bits();
367 ushort* out = (ushort*)rotatedFrame.bits();
368 int spl = rotatedFrame.bytesPerLine() / bytes;
369 for (int x=0; x<h; x++) {
370 if ( bytes == 2 ) {
371 ushort* lout = out++ + (w - 1)*spl;
372 for (int y=0; y<w; y++) {
373 *lout=*in++;
374 lout-=spl;
375 }
376 } else {
377 ulong* lout = ((ulong *)out)++ + (w - 1)*spl;
378 for (int y=0; y<w; y++) {
379 *lout=*((ulong*)in)++;
380 lout-=spl;
381 }
382 }
383 }
384
385 p.drawImage( (240 - rw) / 2, (320 - rh) / 2, rotatedFrame, 0, 0, rw, rh );
386 }
387#ifdef USE_DIRECT_PAINTER
388 }
389#endif
390 } else {
391
392 w = 220;
393 h = 160;
394
395 // maintain aspect ratio
396 if ( w * sh > sw * h )
397 w = sw * h / sh;
398 else
399 h = sh * w / sw;
400
401 result = mediaPlayerState->curDecoder()->videoReadScaledFrame( currentFrame->jumpTable(), 0, 0, sw, sh, w, h, format, 0) == 0;
402
403 QPainter p( this );
404
405 // Image changed size, therefore need to blank the possibly unpainted regions first
406 if ( scaledWidth != w || scaledHeight != h ) {
407 p.setBrush( QBrush( Qt::black ) );
408 p.drawRect( 9, 20, 220, 160 );
409 }
410
411 scaledWidth = w;
412 scaledHeight = h;
413
414 if ( result ) {
415 p.drawImage( 9 + (220 - scaledWidth) / 2, 20 + (160 - scaledHeight) / 2, *currentFrame, 0, 0, scaledWidth, scaledHeight );
416 }
417
418 }
419
420 return result;
421}
422
423
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef VIDEO_WIDGET_H
21#define VIDEO_WIDGET_H
22
23
24#include <qwidget.h>
25
26
27class QPixmap;
28class QSlider;
29
30
31enum VideoButtons {
32 VideoPrevious,
33 VideoStop,
34 VideoPlay,
35 VideoPause,
36 VideoNext,
37 VideoPlayList,
38 VideoFullscreen
39};
40
41
42class VideoWidget : public QWidget {
43 Q_OBJECT
44public:
45 VideoWidget( QWidget* parent=0, const char* name=0, WFlags f=0 );
46 ~VideoWidget();
47
48 bool playVideo();
49
50public slots:
51 void updateSlider( long, long );
52 void sliderPressed( );
53 void sliderReleased( );
54 void setPaused( bool b) { setToggleButton( VideoPause, b ); }
55 void setPlaying( bool b) { setToggleButton( VideoPlay, b ); }
56 void setFullscreen( bool b ) { setToggleButton( VideoFullscreen, b ); }
57 void makeVisible();
58 void setPosition( long );
59 void setLength( long );
60 void setView( char );
61
62signals:
63 void sliderMoved( long );
64
65protected:
66 void paintEvent( QPaintEvent *pe );
67 void mouseMoveEvent( QMouseEvent *event );
68 void mousePressEvent( QMouseEvent *event );
69 void mouseReleaseEvent( QMouseEvent *event );
70 void closeEvent( QCloseEvent *event );
71
72private:
73 void paintButton( QPainter *p, int i );
74 void toggleButton( int );
75 void setToggleButton( int, bool );
76
77 QSlider *slider;
78 QPixmap *pixmaps[3];
79 QImage *currentFrame;
80 intscaledWidth;
81 int scaledHeight;
82};
83
84
85#endif // VIDEO_WIDGET_H
86
87
88
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 @@
1moc_*
2Makefile
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 @@
1#############################################################################
2
3####### Compiler, tools and options
4
5 CXX =$(SYSCONF_CXX) $(QT_CXX_MT)
6 CXXFLAGS=$(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS) $(SYSCONF_CXXFLAGS_LIB) -DQCONFIG=\"qpe\"
7 CC =$(SYSCONF_CC) $(QT_C_MT)
8 CFLAGS =$(SYSCONF_CFLAGS) $(SYSCONF_CFLAGS_LIB) -DQCONFIG=\"qpe\"
9 INCPATH =-I$(QPEDIR)/include -I..
10 LFLAGS =$(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
11 LIBS =$(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS_QTAPP)
12 MOC =$(SYSCONF_MOC)
13 UIC =$(SYSCONF_UIC)
14
15####### Target
16
17DESTDIR = ../../plugins/codecs/
18VER_MAJ = 1
19VER_MIN = 0
20VER_PATCH = 0
21 TARGET= wavplugin
22TARGET1 = lib$(TARGET).so.$(VER_MAJ)
23
24####### Files
25
26 HEADERS =wavplugin.h \
27 wavpluginimpl.h
28 SOURCES =wavplugin.cpp \
29 wavpluginimpl.cpp
30 OBJECTS =wavplugin.o \
31 wavpluginimpl.o
32INTERFACES =
33UICDECLS =
34UICIMPLS =
35 SRCMOC =
36 OBJMOC =
37
38
39####### Implicit rules
40
41.SUFFIXES: .cpp .cxx .cc .C .c
42
43.cpp.o:
44 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
45
46.cxx.o:
47 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
48
49.cc.o:
50 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
51
52.C.o:
53 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
54
55.c.o:
56 $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
57
58####### Build rules
59
60
61all: $(DESTDIR)$(SYSCONF_LINK_TARGET)
62
63$(DESTDIR)$(SYSCONF_LINK_TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
64 $(SYSCONF_LINK_LIB)
65
66moc: $(SRCMOC)
67
68tmake:
69 tmake wavplugin.pro
70
71clean:
72 -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
73 -rm -f *~ core
74 -rm -f allmoc.cpp
75
76####### Extension Modules
77
78listpromodules:
79 @echo
80
81listallmodules:
82 @echo
83
84listaddonpromodules:
85 @echo
86
87listaddonentmodules:
88 @echo
89
90
91REQUIRES=
92
93####### Sub-libraries
94
95
96###### Combined headers
97
98
99
100####### Compile
101
102wavplugin.o: wavplugin.cpp \
103 wavplugin.h \
104 ../mediaplayerplugininterface.h
105
106wavpluginimpl.o: wavpluginimpl.cpp \
107 wavplugin.h \
108 ../mediaplayerplugininterface.h \
109 wavpluginimpl.h \
110 ../mediaplayerplugininterface.h
111
112
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 @@
1Files: plugins/codecs/libwavplugin.so.1.0.0 plugins/codecs/libwavplugin.so.1.0 plugins/codecs/libwavplugin.so.1 plugins/codecs/libwavplugin.so
2Priority: optional
3Section: qpe/plugins
4Maintainer: John Ryland <jryland@trolltech.com>
5Architecture: arm
6Version: $QPE_VERSION-3
7Depends: qpe-base ($QPE_VERSION)
8Description: WAV file plugin
9 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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#include <stdio.h>
21#include <stdarg.h>
22#include <stdlib.h>
23#include <errno.h>
24#include <unistd.h>
25#include <qfile.h>
26#include "wavplugin.h"
27
28
29 //#define debugMsg(a) qDebug(a)
30#define debugMsg(a)
31
32
33struct RiffChunk {
34 char id[4];
35 Q_UINT32 size;
36 char data[4];
37};
38
39
40struct ChunkData {
41 Q_INT16 formatTag;
42 Q_INT16 channels;
43 Q_INT32 samplesPerSec;
44 Q_INT32 avgBytesPerSec;
45 Q_INT16 blockAlign;
46 Q_INT16 wBitsPerSample;
47};
48
49
50const int sound_buffer_size = 4096;
51
52
53class WavPluginData {
54public:
55 QFile *input;
56
57 int wavedata_remaining;
58 ChunkData chunkdata;
59 RiffChunk chunk;
60 uchar data[sound_buffer_size+32]; // +32 to handle badly aligned input data
61 int out,max;
62 int samples_due;
63 int samples;
64
65 WavPluginData() {
66 max = out = sound_buffer_size;
67 wavedata_remaining = 0;
68 samples_due = 0;
69 samples = -1;
70 }
71
72 // expands out samples to the frequency of 44kHz
73 bool add( short *output, long count, long& done, bool stereo )
74 {
75 done = 0;
76
77 if ( input == 0 ) {
78 qDebug("no input");
79 return FALSE;
80 }
81
82 while ( count ) {
83 int l,r;
84 if ( getSample(l, r) == FALSE ) {
85 qDebug("didn't get sample");
86 return FALSE;
87 }
88 samples_due += 44100;
89 while ( count && (samples_due > chunkdata.samplesPerSec) ) {
90 *output++ = l;
91 if ( stereo )
92 *output++ = r;
93 samples_due -= chunkdata.samplesPerSec;
94 count--;
95 done++;
96 }
97 }
98
99 return TRUE;
100 }
101
102 bool initialise() {
103 if ( input == 0 )
104 return FALSE;
105
106 wavedata_remaining = -1;
107
108 while ( wavedata_remaining == -1 ) {
109 // Keep reading chunks...
110 const int n = sizeof(chunk) - sizeof(chunk.data);
111 int t = input->readBlock( (char*)&chunk, n );
112 if ( t != n ) {
113 if ( t == -1 )
114 return FALSE;
115 return TRUE;
116 }
117 if ( qstrncmp(chunk.id,"data",4) == 0 ) {
118 samples = wavedata_remaining = chunk.size;
119 } else if ( qstrncmp(chunk.id,"RIFF",4) == 0 ) {
120 char d[4];
121 if ( input->readBlock(d,4) != 4 ) {
122 return FALSE;
123 }
124 if ( qstrncmp(d,"WAVE",4) != 0 ) {
125 // skip
126 if ( chunk.size > 1000000000 || !input->at(input->at()+chunk.size-4) ) {
127 return FALSE;
128 }
129 }
130 } else if ( qstrncmp(chunk.id,"fmt ",4) == 0 ) {
131 if ( input->readBlock((char*)&chunkdata,sizeof(chunkdata)) != sizeof(chunkdata) ) {
132 return FALSE;
133 }
134#define WAVE_FORMAT_PCM 1
135 if ( chunkdata.formatTag != WAVE_FORMAT_PCM ) {
136 qDebug("WAV file: UNSUPPORTED FORMAT %d",chunkdata.formatTag);
137 return FALSE;
138 }
139 } else {
140 // ignored chunk
141 if ( chunk.size > 1000000000 || !input->at(input->at()+chunk.size) ) {
142 return FALSE;
143 }
144 }
145 } // while
146
147 return TRUE;
148 }
149
150
151 // gets a sample from the file
152 bool getSample(int& l, int& r)
153 {
154 l = r = 0;
155
156 if ( input == 0 )
157 return FALSE;
158
159 if ( (wavedata_remaining < 0) || !max )
160 return FALSE;
161
162 if ( out >= max ) {
163 max = input->readBlock( (char*)data, (uint)QMIN(sound_buffer_size,wavedata_remaining) );
164
165 wavedata_remaining -= max;
166
167 out = 0;
168 if ( max <= 0 ) {
169 max = 0;
170 return TRUE;
171 }
172 }
173 if ( chunkdata.wBitsPerSample == 8 ) {
174 l = (data[out++] - 128) * 128;
175 } else {
176 l = ((short*)data)[out/2];
177 out += 2;
178 }
179 if ( chunkdata.channels == 1 ) {
180 r = l;
181 } else {
182 if ( chunkdata.wBitsPerSample == 8 ) {
183 r = (data[out++] - 128) * 128;
184 } else {
185 r = ((short*)data)[out/2];
186 out += 2;
187 }
188 }
189 return TRUE;
190 } // getSample
191
192};
193
194
195WavPlugin::WavPlugin() {
196 d = new WavPluginData;
197 d->input = 0;
198}
199
200
201WavPlugin::~WavPlugin() {
202 close();
203 delete d;
204}
205
206
207bool WavPlugin::isFileSupported( const QString& path ) {
208 debugMsg( "WavPlugin::isFileSupported" );
209
210 char *ext = strrchr( path.latin1(), '.' );
211
212 // Test file extension
213 if ( ext ) {
214 if ( strncasecmp(ext, ".raw", 4) == 0 )
215 return TRUE;
216 if ( strncasecmp(ext, ".wav", 4) == 0 )
217 return TRUE;
218 if ( strncasecmp(ext, ".wave", 4) == 0 )
219 return TRUE;
220 }
221
222 return FALSE;
223}
224
225
226bool WavPlugin::open( const QString& path ) {
227 debugMsg( "WavPlugin::open" );
228
229 d->max = d->out = sound_buffer_size;
230 d->wavedata_remaining = 0;
231 d->samples_due = 0;
232
233 d->input = new QFile( path );
234 if ( d->input->open(IO_ReadOnly) == FALSE ) {
235 qDebug("couldn't open file");
236 delete d->input;
237 d->input = 0;
238 return FALSE;
239 }
240
241 d->initialise();
242
243 return TRUE;
244}
245
246
247bool WavPlugin::close() {
248 debugMsg( "WavPlugin::close" );
249
250 d->input->close();
251 delete d->input;
252 d->input = 0;
253 return TRUE;
254}
255
256
257bool WavPlugin::isOpen() {
258 debugMsg( "WavPlugin::isOpen" );
259 return ( d->input != 0 );
260}
261
262
263int WavPlugin::audioStreams() {
264 debugMsg( "WavPlugin::audioStreams" );
265 return 1;
266}
267
268
269int WavPlugin::audioChannels( int ) {
270 debugMsg( "WavPlugin::audioChannels" );
271 return 2; // ### Always scale audio to stereo samples
272}
273
274
275int WavPlugin::audioFrequency( int ) {
276 debugMsg( "WavPlugin::audioFrequency" );
277 return 44100; // ### Always scale to frequency of 44100
278}
279
280
281int WavPlugin::audioSamples( int ) {
282 debugMsg( "WavPlugin::audioSamples" );
283 return d->samples * 2 / d->chunkdata.channels; // ### Scaled samples will be made stereo,
284 // Therefore if source is mono we will double the number of samples
285}
286
287
288bool WavPlugin::audioSetSample( long, int ) {
289 debugMsg( "WavPlugin::audioSetSample" );
290 return FALSE;
291}
292
293
294long WavPlugin::audioGetSample( int ) {
295 debugMsg( "WavPlugin::audioGetSample" );
296 return 0;
297}
298
299/*
300bool WavPlugin::audioReadSamples( short *, int, long, int ) {
301 debugMsg( "WavPlugin::audioReadSamples" );
302 return FALSE;
303}
304
305
306bool WavPlugin::audioReReadSamples( short *, int, long, int ) {
307 debugMsg( "WavPlugin::audioReReadSamples" );
308 return FALSE;
309}
310
311
312bool WavPlugin::audioReadMonoSamples( short *output, long samples, long& samplesMade, int ) {
313 debugMsg( "WavPlugin::audioReadMonoSamples" );
314 return !d->add( output, samples, samplesMade, FALSE );
315}
316
317
318bool WavPlugin::audioReadStereoSamples( short *output, long samples, long& samplesMade, int ) {
319 debugMsg( "WavPlugin::audioReadStereoSamples" );
320 return !d->add( output, samples, samplesMade, TRUE );
321}
322*/
323
324bool WavPlugin::audioReadSamples( short *output, int channels, long samples, long& samplesMade, int ) {
325 debugMsg( "WavPlugin::audioReadSamples" );
326 return !d->add( output, samples, samplesMade, channels != 1 );
327}
328
329double WavPlugin::getTime() {
330 debugMsg( "WavPlugin::getTime" );
331 return 0.0;
332}
333
334
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef WAV_PLUGIN_H
21#define WAV_PLUGIN_H
22
23
24#include <qstring.h>
25#include <qapplication.h>
26#include "mediaplayerplugininterface.h"
27
28
29class WavPluginData;
30
31
32class WavPlugin : public MediaPlayerDecoder {
33
34public:
35 WavPlugin();
36 ~WavPlugin();
37
38 const char *pluginName() { return "WavPlugin"; }
39 const char *pluginComment() { return "This is a simple plugin for playing wav files"; }
40 double pluginVersion() { return 1.0; }
41
42 bool isFileSupported( const QString& );
43 bool open( const QString& );
44 bool close();
45 bool isOpen();
46 //const QString &fileInfo() { return strInfo = qApp->translate( "MediaPlayer", "No Information Available", "media plugin text" ); }
47 const QString &fileInfo() { return strInfo = QString(""); }
48
49 // If decoder doesn't support audio then return 0 here
50 int audioStreams();
51 int audioChannels( int stream );
52 int audioFrequency( int stream );
53 int audioSamples( int stream );
54 bool audioSetSample( long sample, int stream );
55 long audioGetSample( int stream );
56 //bool audioReadMonoSamples( short *output, long samples, long& samplesRead, int stream );
57 //bool audioReadStereoSamples( short *output, long samples, long& samplesRead, int stream );
58 bool audioReadSamples( short *output, int channels, long samples, long& samplesRead, int stream );
59 //bool audioReadSamples( short *output, int channel, long samples, int stream );
60 //bool audioReReadSamples( short *output, int channel, long samples, int stream );
61
62 // If decoder doesn't support video then return 0 here
63 int videoStreams() { return 0; }
64 int videoWidth( int ) { return 0; }
65 int videoHeight( int ) { return 0; }
66 double videoFrameRate( int ) { return 0.0; }
67 int videoFrames( int ) { return 0; }
68 bool videoSetFrame( long, int ) { return FALSE; }
69 long videoGetFrame( int ) { return 0; }
70 bool videoReadFrame( unsigned char **, int, int, int, int, ColorFormat, int ) { return FALSE; }
71 bool videoReadScaledFrame( unsigned char **, int, int, int, int, int, int, ColorFormat, int ) { return FALSE; }
72 bool videoReadYUVFrame( char *, char *, char *, int, int, int, int, int ) { return FALSE; }
73
74 // Profiling
75 double getTime();
76
77 // Ignore if these aren't supported
78 bool setSMP( int ) { return FALSE; }
79 bool setMMX( bool ) { return FALSE; }
80
81 // Capabilities
82 bool supportsAudio() { return TRUE; }
83 bool supportsVideo() { return FALSE; }
84 bool supportsYUV() { return FALSE; }
85 bool supportsMMX() { return TRUE; }
86 bool supportsSMP() { return FALSE; }
87 bool supportsStereo() { return TRUE; }
88 bool supportsScaling() { return FALSE; }
89
90private:
91 WavPluginData *d;
92 QString strInfo;
93
94};
95
96
97#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 @@
1 TEMPLATE= lib
2 CONFIG += qt warn_on release
3 HEADERS = wavplugin.h wavpluginimpl.h
4 SOURCES = wavplugin.cpp wavpluginimpl.cpp
5 TARGET = wavplugin
6 DESTDIR = ../../plugins/codecs
7INCLUDEPATH += $(QPEDIR)/include ..
8DEPENDPATH += ../$(QPEDIR)/include ..
9LIBS += -lqpe
10 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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#include "wavplugin.h"
21#include "wavpluginimpl.h"
22
23
24WavPluginImpl::WavPluginImpl()
25 : libmadplugin(0), ref(0)
26{
27}
28
29
30WavPluginImpl::~WavPluginImpl()
31{
32 if ( libmadplugin )
33 delete libmadplugin;
34}
35
36
37MediaPlayerDecoder *WavPluginImpl::decoder()
38{
39 if ( !libmadplugin )
40 libmadplugin = new WavPlugin;
41 return libmadplugin;
42}
43
44
45MediaPlayerEncoder *WavPluginImpl::encoder()
46{
47 return NULL;
48}
49
50
51#ifndef QT_NO_COMPONENT
52
53
54QRESULT WavPluginImpl::queryInterface( const QUuid &uuid, QUnknownInterface **iface )
55{
56 *iface = 0;
57 if ( ( uuid == IID_QUnknown ) || ( uuid == IID_MediaPlayerPlugin ) )
58 *iface = this, (*iface)->addRef();
59 return QS_OK;
60}
61
62
63Q_EXPORT_INTERFACE()
64{
65 Q_CREATE_INSTANCE( WavPluginImpl )
66}
67
68
69#endif
70
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef WAV_PLUGIN_IMPL_H
21#define WAV_PLUGIN_IMPL_H
22
23
24#include "../mediaplayerplugininterface.h"
25
26
27class WavPlugin;
28
29
30class WavPluginImpl : public MediaPlayerPluginInterface
31{
32public:
33 WavPluginImpl();
34 virtual ~WavPluginImpl();
35
36#ifndef QT_NO_COMPONENT
37
38 QRESULT queryInterface( const QUuid&, QUnknownInterface** );
39 Q_REFCOUNT
40
41#endif
42
43 virtual MediaPlayerDecoder *decoder();
44 virtual MediaPlayerEncoder *encoder();
45
46private:
47 WavPlugin *libmadplugin;
48 ulong ref;
49};
50
51
52#endif
53
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 @@
1moc_*
2*.moc
3Makefile
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 @@
1
2Welcome to LISA System's
3
4 QDM - the Login-Dialog for QPE
5
6
7WHAT'S THIS:
8
9This small add-on for the Qtopia Environment (QPE - see
10http://qpe.sourceforge.net for further details) allows You to use your
11handheld computer running QPE and Linux with the typical Un*x user
12handling, i.e. just log in on a graphical environment, as e.g. KDM or
13XDM. This way your personal data can be easily protected against
14unwanted access from others in case you loose your machine.
15
16
17STATUS:
18
19Still in development, but should be useable.
20
21
22REQUIREMENTS:
23
24- QDM needs Linux-PAM (Pluggable Authentication Modules for Linux) for
25 proper user validation.
26
27- the /dev/fb0 device has to writeable to everyone ;-(
28
29
30INSTALLATION:
31
32Per default this little add-on is not enabled. You have to do so
33yourself for now, by setting a compile option variable called
34QT_QWS_LOGIN . Furthermore there have to be made some changes in
35taskbar/taskbar.pro :
36
37At the section HEADERS insert a line:
38 ../login/qdmdialogimpl.h \
39
40At the section SOURCES insert a line:
41 ../login/qdmdialogimpl.cpp \
42
43 furthermore serte these lines:
44
45 INCLUDEPATH+= ../login
46 DEPENDPATH+= ../login
47
48 INTERFACES= ../login/qdmdialog.ui
49
50For unix-login make folloing changes to a line:
51 LIBS = -lqpe -lcrypt
52
53For PAM use the following:
54 LIBS = -lqpe -ldl -lpam
55
56
57
58CONFIGURATION:
59
60Configuration of the 'Look' of QDM is done via Qt Designer. Just open
61the .ui file and edit the look of the dialog as you like. You can, for
62instance, change the logo pixmap. QDM should also be ready for i18n so
63far.
64
65Other configuration stuff, eg welcome string in the upper right, and
66user list can be changed in the qdm_config.h file.
67
68
69USAGE:
70
71The QDM comes up, when the QPE is started, and if the QPE is started
72as 'root'. Being started as any other user, the uid couldn't be
73changed and the login dialog wouldn't be ofg much use.
74
75
76CONTACT:
77
78http://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 @@
1//-- -*- c++ -*-
2
3#ifndef _QDM_CONFIG_H
4#define _QDM_CONFIG_H
5
6/*
7 * Config file for QDM
8 */
9
10
11/** define this to enable the qdm login dialog for qpe */
12#define QT_QWS_LOGIN
13
14/** define this to let qdm use Linux-PAM */
15//define QT_QWS_LOGIN_USEPAM
16
17/** this is the list of users shown in the input-list */
18#define QDM_SHOWNUSERS static char *Shown_Users[] = { "guest", "root", "lisa", 0 };
19
20/** which command to execute when going to sleep mode */
21 #define QDM_CMD_SLEEP "/sbin/shutdow","-z","now"
22
23/** which command to execute when shutting down */
24 #define QDM_CMD_SHUTDOWN"/sbin/shutdow","-z","now"
25
26/** Welcome string on dialog */
27 #define QDM_WELCOME_STRING"Welcome to\nmLinux [iPAQ]"
28
29
30#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 @@
1<!DOCTYPE UI><UI>
2<class>QDMDialog</class>
3<widget>
4 <class>QDialog</class>
5 <property stdset="1">
6 <name>name</name>
7 <cstring>QDMDialog</cstring>
8 </property>
9 <property stdset="1">
10 <name>geometry</name>
11 <rect>
12 <x>0</x>
13 <y>7</y>
14 <width>240</width>
15 <height>320</height>
16 </rect>
17 </property>
18 <property stdset="1">
19 <name>sizePolicy</name>
20 <sizepolicy>
21 <hsizetype>0</hsizetype>
22 <vsizetype>1</vsizetype>
23 </sizepolicy>
24 </property>
25 <property stdset="1">
26 <name>minimumSize</name>
27 <size>
28 <width>240</width>
29 <height>240</height>
30 </size>
31 </property>
32 <property stdset="1">
33 <name>maximumSize</name>
34 <size>
35 <width>240</width>
36 <height>320</height>
37 </size>
38 </property>
39 <property stdset="1">
40 <name>palette</name>
41 <palette>
42 <active>
43 <color>
44 <red>0</red>
45 <green>0</green>
46 <blue>0</blue>
47 </color>
48 <color>
49 <red>228</red>
50 <green>228</green>
51 <blue>228</blue>
52 </color>
53 <color>
54 <red>255</red>
55 <green>255</green>
56 <blue>255</blue>
57 </color>
58 <color>
59 <red>242</red>
60 <green>242</green>
61 <blue>242</blue>
62 </color>
63 <color>
64 <red>78</red>
65 <green>78</green>
66 <blue>78</blue>
67 </color>
68 <color>
69 <red>183</red>
70 <green>183</green>
71 <blue>183</blue>
72 </color>
73 <color>
74 <red>0</red>
75 <green>0</green>
76 <blue>0</blue>
77 </color>
78 <color>
79 <red>255</red>
80 <green>255</green>
81 <blue>255</blue>
82 </color>
83 <color>
84 <red>0</red>
85 <green>0</green>
86 <blue>0</blue>
87 </color>
88 <color>
89 <red>255</red>
90 <green>255</green>
91 <blue>255</blue>
92 </color>
93 <color>
94 <red>220</red>
95 <green>220</green>
96 <blue>220</blue>
97 </color>
98 <color>
99 <red>0</red>
100 <green>0</green>
101 <blue>0</blue>
102 </color>
103 <color>
104 <red>10</red>
105 <green>95</green>
106 <blue>137</blue>
107 </color>
108 <color>
109 <red>255</red>
110 <green>255</green>
111 <blue>255</blue>
112 </color>
113 </active>
114 <disabled>
115 <color>
116 <red>0</red>
117 <green>0</green>
118 <blue>0</blue>
119 </color>
120 <color>
121 <red>228</red>
122 <green>228</green>
123 <blue>228</blue>
124 </color>
125 <color>
126 <red>255</red>
127 <green>255</green>
128 <blue>255</blue>
129 </color>
130 <color>
131 <red>242</red>
132 <green>242</green>
133 <blue>242</blue>
134 </color>
135 <color>
136 <red>78</red>
137 <green>78</green>
138 <blue>78</blue>
139 </color>
140 <color>
141 <red>183</red>
142 <green>183</green>
143 <blue>183</blue>
144 </color>
145 <color>
146 <red>183</red>
147 <green>183</green>
148 <blue>183</blue>
149 </color>
150 <color>
151 <red>255</red>
152 <green>255</green>
153 <blue>255</blue>
154 </color>
155 <color>
156 <red>0</red>
157 <green>0</green>
158 <blue>0</blue>
159 </color>
160 <color>
161 <red>255</red>
162 <green>255</green>
163 <blue>255</blue>
164 </color>
165 <color>
166 <red>220</red>
167 <green>220</green>
168 <blue>220</blue>
169 </color>
170 <color>
171 <red>0</red>
172 <green>0</green>
173 <blue>0</blue>
174 </color>
175 <color>
176 <red>0</red>
177 <green>0</green>
178 <blue>128</blue>
179 </color>
180 <color>
181 <red>255</red>
182 <green>255</green>
183 <blue>255</blue>
184 </color>
185 </disabled>
186 <inactive>
187 <color>
188 <red>0</red>
189 <green>0</green>
190 <blue>0</blue>
191 </color>
192 <color>
193 <red>228</red>
194 <green>228</green>
195 <blue>228</blue>
196 </color>
197 <color>
198 <red>255</red>
199 <green>255</green>
200 <blue>255</blue>
201 </color>
202 <color>
203 <red>242</red>
204 <green>242</green>
205 <blue>242</blue>
206 </color>
207 <color>
208 <red>78</red>
209 <green>78</green>
210 <blue>78</blue>
211 </color>
212 <color>
213 <red>183</red>
214 <green>183</green>
215 <blue>183</blue>
216 </color>
217 <color>
218 <red>0</red>
219 <green>0</green>
220 <blue>0</blue>
221 </color>
222 <color>
223 <red>255</red>
224 <green>255</green>
225 <blue>255</blue>
226 </color>
227 <color>
228 <red>0</red>
229 <green>0</green>
230 <blue>0</blue>
231 </color>
232 <color>
233 <red>255</red>
234 <green>255</green>
235 <blue>255</blue>
236 </color>
237 <color>
238 <red>220</red>
239 <green>220</green>
240 <blue>220</blue>
241 </color>
242 <color>
243 <red>0</red>
244 <green>0</green>
245 <blue>0</blue>
246 </color>
247 <color>
248 <red>10</red>
249 <green>95</green>
250 <blue>137</blue>
251 </color>
252 <color>
253 <red>255</red>
254 <green>255</green>
255 <blue>255</blue>
256 </color>
257 </inactive>
258 </palette>
259 </property>
260 <property stdset="1">
261 <name>caption</name>
262 <string>QDM</string>
263 </property>
264 <widget>
265 <class>QLabel</class>
266 <property stdset="1">
267 <name>name</name>
268 <cstring>label_logo</cstring>
269 </property>
270 <property stdset="1">
271 <name>geometry</name>
272 <rect>
273 <x>10</x>
274 <y>10</y>
275 <width>100</width>
276 <height>33</height>
277 </rect>
278 </property>
279 <property stdset="1">
280 <name>palette</name>
281 <palette>
282 <active>
283 <color>
284 <red>0</red>
285 <green>0</green>
286 <blue>0</blue>
287 </color>
288 <color>
289 <red>220</red>
290 <green>220</green>
291 <blue>220</blue>
292 </color>
293 <color>
294 <red>255</red>
295 <green>255</green>
296 <blue>255</blue>
297 </color>
298 <color>
299 <red>237</red>
300 <green>237</green>
301 <blue>237</blue>
302 </color>
303 <color>
304 <red>110</red>
305 <green>110</green>
306 <blue>110</blue>
307 </color>
308 <color>
309 <red>146</red>
310 <green>146</green>
311 <blue>146</blue>
312 </color>
313 <color>
314 <red>0</red>
315 <green>0</green>
316 <blue>0</blue>
317 </color>
318 <color>
319 <red>255</red>
320 <green>255</green>
321 <blue>255</blue>
322 </color>
323 <color>
324 <red>0</red>
325 <green>0</green>
326 <blue>0</blue>
327 </color>
328 <color>
329 <red>255</red>
330 <green>255</green>
331 <blue>255</blue>
332 </color>
333 <color>
334 <red>255</red>
335 <green>255</green>
336 <blue>255</blue>
337 </color>
338 <color>
339 <red>0</red>
340 <green>0</green>
341 <blue>0</blue>
342 </color>
343 <color>
344 <red>84</red>
345 <green>112</green>
346 <blue>152</blue>
347 </color>
348 <color>
349 <red>255</red>
350 <green>255</green>
351 <blue>255</blue>
352 </color>
353 </active>
354 <disabled>
355 <color>
356 <red>128</red>
357 <green>128</green>
358 <blue>128</blue>
359 </color>
360 <color>
361 <red>220</red>
362 <green>220</green>
363 <blue>220</blue>
364 </color>
365 <color>
366 <red>255</red>
367 <green>255</green>
368 <blue>255</blue>
369 </color>
370 <color>
371 <red>253</red>
372 <green>253</green>
373 <blue>253</blue>
374 </color>
375 <color>
376 <red>110</red>
377 <green>110</green>
378 <blue>110</blue>
379 </color>
380 <color>
381 <red>146</red>
382 <green>146</green>
383 <blue>146</blue>
384 </color>
385 <color>
386 <red>0</red>
387 <green>0</green>
388 <blue>0</blue>
389 </color>
390 <color>
391 <red>255</red>
392 <green>255</green>
393 <blue>255</blue>
394 </color>
395 <color>
396 <red>128</red>
397 <green>128</green>
398 <blue>128</blue>
399 </color>
400 <color>
401 <red>255</red>
402 <green>255</green>
403 <blue>255</blue>
404 </color>
405 <color>
406 <red>255</red>
407 <green>255</green>
408 <blue>255</blue>
409 </color>
410 <color>
411 <red>0</red>
412 <green>0</green>
413 <blue>0</blue>
414 </color>
415 <color>
416 <red>84</red>
417 <green>112</green>
418 <blue>152</blue>
419 </color>
420 <color>
421 <red>255</red>
422 <green>255</green>
423 <blue>255</blue>
424 </color>
425 </disabled>
426 <inactive>
427 <color>
428 <red>0</red>
429 <green>0</green>
430 <blue>0</blue>
431 </color>
432 <color>
433 <red>220</red>
434 <green>220</green>
435 <blue>220</blue>
436 </color>
437 <color>
438 <red>255</red>
439 <green>255</green>
440 <blue>255</blue>
441 </color>
442 <color>
443 <red>253</red>
444 <green>253</green>
445 <blue>253</blue>
446 </color>
447 <color>
448 <red>110</red>
449 <green>110</green>
450 <blue>110</blue>
451 </color>
452 <color>
453 <red>146</red>
454 <green>146</green>
455 <blue>146</blue>
456 </color>
457 <color>
458 <red>0</red>
459 <green>0</green>
460 <blue>0</blue>
461 </color>
462 <color>
463 <red>255</red>
464 <green>255</green>
465 <blue>255</blue>
466 </color>
467 <color>
468 <red>0</red>
469 <green>0</green>
470 <blue>0</blue>
471 </color>
472 <color>
473 <red>255</red>
474 <green>255</green>
475 <blue>255</blue>
476 </color>
477 <color>
478 <red>255</red>
479 <green>255</green>
480 <blue>255</blue>
481 </color>
482 <color>
483 <red>0</red>
484 <green>0</green>
485 <blue>0</blue>
486 </color>
487 <color>
488 <red>84</red>
489 <green>112</green>
490 <blue>152</blue>
491 </color>
492 <color>
493 <red>255</red>
494 <green>255</green>
495 <blue>255</blue>
496 </color>
497 </inactive>
498 </palette>
499 </property>
500 <property stdset="1">
501 <name>frameShape</name>
502 <enum>Panel</enum>
503 </property>
504 <property stdset="1">
505 <name>frameShadow</name>
506 <enum>Sunken</enum>
507 </property>
508 <property stdset="1">
509 <name>margin</name>
510 <number>2</number>
511 </property>
512 <property stdset="1">
513 <name>pixmap</name>
514 <pixmap>image0</pixmap>
515 </property>
516 <property stdset="1">
517 <name>scaledContents</name>
518 <bool>true</bool>
519 </property>
520 </widget>
521 <widget>
522 <class>QLabel</class>
523 <property stdset="1">
524 <name>name</name>
525 <cstring>label_welcome</cstring>
526 </property>
527 <property stdset="1">
528 <name>geometry</name>
529 <rect>
530 <x>120</x>
531 <y>10</y>
532 <width>110</width>
533 <height>40</height>
534 </rect>
535 </property>
536 <property stdset="1">
537 <name>font</name>
538 <font>
539 <pointsize>14</pointsize>
540 <bold>1</bold>
541 </font>
542 </property>
543 <property stdset="1">
544 <name>text</name>
545 <string>Welcome to
546mLinux [iPAQ]</string>
547 </property>
548 <property stdset="1">
549 <name>alignment</name>
550 <set>AlignCenter</set>
551 </property>
552 <property>
553 <name>hAlign</name>
554 </property>
555 </widget>
556 <widget>
557 <class>QLabel</class>
558 <property stdset="1">
559 <name>name</name>
560 <cstring>label_time</cstring>
561 </property>
562 <property stdset="1">
563 <name>geometry</name>
564 <rect>
565 <x>180</x>
566 <y>50</y>
567 <width>50</width>
568 <height>16</height>
569 </rect>
570 </property>
571 <property stdset="1">
572 <name>text</name>
573 <string>12:30:88</string>
574 </property>
575 </widget>
576 <widget>
577 <class>QLabel</class>
578 <property stdset="1">
579 <name>name</name>
580 <cstring>label_date</cstring>
581 </property>
582 <property stdset="1">
583 <name>geometry</name>
584 <rect>
585 <x>70</x>
586 <y>50</y>
587 <width>100</width>
588 <height>16</height>
589 </rect>
590 </property>
591 <property stdset="1">
592 <name>text</name>
593 <string>Wed Feb 12 2001</string>
594 </property>
595 </widget>
596 <widget>
597 <class>QLabel</class>
598 <property stdset="1">
599 <name>name</name>
600 <cstring>TextLabel5</cstring>
601 </property>
602 <property stdset="1">
603 <name>geometry</name>
604 <rect>
605 <x>20</x>
606 <y>50</y>
607 <width>50</width>
608 <height>16</height>
609 </rect>
610 </property>
611 <property stdset="1">
612 <name>text</name>
613 <string>Today:</string>
614 </property>
615 </widget>
616 <widget>
617 <class>QGroupBox</class>
618 <property stdset="1">
619 <name>name</name>
620 <cstring>GroupBox3</cstring>
621 </property>
622 <property stdset="1">
623 <name>geometry</name>
624 <rect>
625 <x>10</x>
626 <y>80</y>
627 <width>220</width>
628 <height>120</height>
629 </rect>
630 </property>
631 <property stdset="1">
632 <name>backgroundOrigin</name>
633 <enum>WidgetOrigin</enum>
634 </property>
635 <property stdset="1">
636 <name>title</name>
637 <string>Login</string>
638 </property>
639 <widget>
640 <class>QPushButton</class>
641 <property stdset="1">
642 <name>name</name>
643 <cstring>PushButton3</cstring>
644 </property>
645 <property stdset="1">
646 <name>geometry</name>
647 <rect>
648 <x>160</x>
649 <y>60</y>
650 <width>50</width>
651 <height>21</height>
652 </rect>
653 </property>
654 <property stdset="1">
655 <name>text</name>
656 <string>Clear</string>
657 </property>
658 </widget>
659 <widget>
660 <class>QLineEdit</class>
661 <property stdset="1">
662 <name>name</name>
663 <cstring>input_password</cstring>
664 </property>
665 <property stdset="1">
666 <name>geometry</name>
667 <rect>
668 <x>80</x>
669 <y>60</y>
670 <width>70</width>
671 <height>22</height>
672 </rect>
673 </property>
674 <property stdset="1">
675 <name>echoMode</name>
676 <enum>Password</enum>
677 </property>
678 </widget>
679 <widget>
680 <class>QComboBox</class>
681 <property stdset="1">
682 <name>name</name>
683 <cstring>input_user</cstring>
684 </property>
685 <property stdset="1">
686 <name>geometry</name>
687 <rect>
688 <x>80</x>
689 <y>30</y>
690 <width>120</width>
691 <height>21</height>
692 </rect>
693 </property>
694 <property stdset="1">
695 <name>editable</name>
696 <bool>true</bool>
697 </property>
698 </widget>
699 <widget>
700 <class>QLabel</class>
701 <property stdset="1">
702 <name>name</name>
703 <cstring>label_user</cstring>
704 </property>
705 <property stdset="1">
706 <name>geometry</name>
707 <rect>
708 <x>10</x>
709 <y>30</y>
710 <width>60</width>
711 <height>21</height>
712 </rect>
713 </property>
714 <property stdset="1">
715 <name>text</name>
716 <string>User</string>
717 </property>
718 </widget>
719 <widget>
720 <class>QLabel</class>
721 <property stdset="1">
722 <name>name</name>
723 <cstring>label_password</cstring>
724 </property>
725 <property stdset="1">
726 <name>geometry</name>
727 <rect>
728 <x>10</x>
729 <y>60</y>
730 <width>60</width>
731 <height>21</height>
732 </rect>
733 </property>
734 <property stdset="1">
735 <name>text</name>
736 <string>Password</string>
737 </property>
738 </widget>
739 <widget>
740 <class>QPushButton</class>
741 <property stdset="1">
742 <name>name</name>
743 <cstring>button_shutdown</cstring>
744 </property>
745 <property stdset="1">
746 <name>geometry</name>
747 <rect>
748 <x>150</x>
749 <y>90</y>
750 <width>61</width>
751 <height>20</height>
752 </rect>
753 </property>
754 <property stdset="1">
755 <name>text</name>
756 <string>Shutdown</string>
757 </property>
758 </widget>
759 <widget>
760 <class>QPushButton</class>
761 <property stdset="1">
762 <name>name</name>
763 <cstring>button_login</cstring>
764 </property>
765 <property stdset="1">
766 <name>geometry</name>
767 <rect>
768 <x>10</x>
769 <y>90</y>
770 <width>60</width>
771 <height>20</height>
772 </rect>
773 </property>
774 <property stdset="1">
775 <name>text</name>
776 <string>Login</string>
777 </property>
778 </widget>
779 <widget>
780 <class>QPushButton</class>
781 <property stdset="1">
782 <name>name</name>
783 <cstring>button_sleep</cstring>
784 </property>
785 <property stdset="1">
786 <name>geometry</name>
787 <rect>
788 <x>90</x>
789 <y>90</y>
790 <width>60</width>
791 <height>20</height>
792 </rect>
793 </property>
794 <property stdset="1">
795 <name>text</name>
796 <string>Sleep</string>
797 </property>
798 </widget>
799 </widget>
800</widget>
801<images>
802 <image>
803 <name>image0</name>
804 <data format="XPM.GZ" length="4080">789ced97db72e2461086effd149475e74a69413258d4d65ef880c7c022cbd8eb35a472a123c8465a09640ebb9577cffc3d033a986c2a38a9ca45bacb653ecd34bf7aba67843e9cd49eac41ede4c3d122b3b3d0adb9537b5e3bf15ea368f3eb6f9f7e1c1db78d9adea8358d5ae3f897a3e3b8e6d6943a19302234e04005d8a8c3811ea10107da40ad01073e123a70e01d502703ce086d38f00bf0b401075e13da70e03760b30e070e086d38d001b6c8804be059130e4c091d3850071aa770a04fe8c2817d609b0ca801e92e68b24be8c18109d0d1e1c021a10f07f6806e130e3409c98016d03b8303c784011c3802fa677020230ce0c00c180486236a3495e8d7697228b0ad891a2d24b6448d3a126d8d4637123d8d6227026d4dd7806b894d51a3ae44e39462eb12bd535ad82b8981a8d1ad40476b52facf129b4d4abf21d168d1d27d97e8b668f446627046a35f05ba4d83bef95262dba01a9d4b740c2aca834457543010e8e96d2aca85c49628e8ab44dba6d1cf123d87eef945a0df10057d92d87269ade612db2e15e55ea2e7d13aaf24061e65a40a84112ab6eda87bcdb56dcf7f7335984c4361cf2f7bc3669ee7450526152f8ebfed5749f8505ab9369f2cb29d2d16af7bee4d89e3385abe4765b5ceb2e9e6fbf9457079d509b3cefc6dd435d788638fbd43e5669a65dd95848bcd9e25eb7971348b62a5ff0e950d5fa6cffb674b1bc4b16df2c0d92e99bfafd2c9b2f0fc6722a68d1887af9a7bb8ca33af79e7767f6fed52b154247377b8ca4af4d6e6ea72bf125219f0ff335effe1c12aeafd3adc7671f781bd097178dd4d84f276fe72b88aaabedc4c3a62cf848b6a428c7ff98c3e3cc6b1d27b870ab7d5ebd76e678a849eca0383288eae53d82c4fe6501552bac1d2754bd746d8f6b945e377abf0038dcb2c56c52bbe1247b9c5b1f30fa8acaa2aa3bb387eb4c6c212de6ddef8309555a110975c655d4d253fc3f9ce11c96c55664369bdbf529984f5877bfa346ff0460b8ba70df555dedc431efd382ea8283bb37eae82c332ec7436ddee063db6b9280e6acab612c2f8ce8cd2ad4ab12f9471316ca8545556b761b87db84c17f5f2b9cf0b1115ef52930f0052d1d3dcfaa530b65c2e476ac59ece9fd793ce66520f569591beae27a5707e41dfe6f2afdbff2aff61959ee627f96e1ca2977b79439baeef0e775b2d11b64546c472a4e042a3b1c4d7127ab970993ada3da35553676a2f3f26923e53597e245896e5f0bf1d02ac9d8a95a64c1debf9ce64a9a53293de6892f2132fe98fd3fc8ad6af3e0f8bbbbbaae2f3347d96cf182db7270c73fda55f3cbfb4e24ee4292ffdd25e2bab9456ccf2d5d44d8a33cc7e2a5e4048332d9c2c56f5a731f387052aab9426f2486bc9d4caaf6eaa8b6f614159696e6eaec9573a35ff54a5b262951963de378c5e01ccc42f97861597cfc268f9a02e4eadf458af32830d355feb1dfffef1e80f6ca1ac19</data>
805 </image>
806</images>
807<connections>
808 <connection>
809 <sender>button_shutdown</sender>
810 <signal>clicked()</signal>
811 <receiver>QDMDialog</receiver>
812 <slot>slot_shutdown()</slot>
813 </connection>
814 <connection>
815 <sender>button_login</sender>
816 <signal>clicked()</signal>
817 <receiver>QDMDialog</receiver>
818 <slot>slot_login()</slot>
819 </connection>
820 <connection>
821 <sender>input_password</sender>
822 <signal>returnPressed()</signal>
823 <receiver>button_login</receiver>
824 <slot>setFocus()</slot>
825 </connection>
826 <connection>
827 <sender>input_user</sender>
828 <signal>highlighted(const QString&amp;)</signal>
829 <receiver>input_password</receiver>
830 <slot>setFocus()</slot>
831 </connection>
832 <connection>
833 <sender>PushButton3</sender>
834 <signal>clicked()</signal>
835 <receiver>input_password</receiver>
836 <slot>clear()</slot>
837 </connection>
838 <connection>
839 <sender>button_sleep</sender>
840 <signal>clicked()</signal>
841 <receiver>QDMDialog</receiver>
842 <slot>slot_sleepmode()</slot>
843 </connection>
844 <slot access="public">slot_sleepmode()</slot>
845 <slot access="public">slot_login()</slot>
846 <slot access="public">slot_shutdown()</slot>
847</connections>
848<tabstops>
849 <tabstop>input_user</tabstop>
850 <tabstop>input_password</tabstop>
851 <tabstop>button_login</tabstop>
852 <tabstop>PushButton3</tabstop>
853 <tabstop>button_sleep</tabstop>
854 <tabstop>button_shutdown</tabstop>
855</tabstops>
856</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 @@
1/**********************************************************************
2** Copyright (C) 2001 LISA Systems
3**
4** This file is an additional part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** For further information contact info@lisa.de
15**
16**********************************************************************/
17
18/*
19 * AUTHOR: Christian Rahn
20 * EMAIL: cdr@lisa.de
21 *
22 * $Id$
23 */
24
25#include "qdm_config.h"
26
27#ifdef QT_QWS_LOGIN
28
29#include <pwd.h>
30#include <unistd.h>
31#include <stdlib.h>
32#include <iostream.h>
33#include <assert.h>
34
35#include <qlabel.h>
36#include <qregexp.h>
37#include <qdatetime.h>
38#include <qmessagebox.h>
39#include <qcombobox.h>
40#include <qlineedit.h>
41#include <qtranslator.h>
42#include <qpeapplication.h>
43
44#include <qwsdisplay_qws.h>
45
46#include <string.h>
47#include <stdio.h>
48#include <errno.h>
49#include <unistd.h>
50
51#include <sys/types.h>
52#include <sys/stat.h>
53#include <sys/sem.h>
54#include <sys/shm.h>
55#include <sys/ipc.h>
56
57#include <global.h>
58
59#if defined(QT_QWS_LOGIN_USEPAM)
60extern "C" {
61#include <security/pam_appl.h>
62}
63#else
64#define _XOPEN_SOURCE
65#include <unistd.h>
66#include <crypt.h>
67#endif
68
69
70#include "qdmdialogimpl.h"
71#include "../taskbar/inputmethods.h"
72
73
74//----------------------------------------------------------------------------
75
76//-- taken from semctl man page
77#if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
78//-- union semun is defined by including <sys/sem.h>
79#else
80//-- according to X/OPEN we have to define it ourselves
81union semun {
82 int val; // value for SETVAL
83 struct semid_ds *buf; // buffer for IPC_STAT, IPC_SET
84 unsigned short int *array; // array for GETALL, SETALL
85 struct seminfo *__buf; // buffer for IPC_INFO
86};
87#endif
88
89//----------------------------------------------------------------------------
90
91static const int ShowClockFreq = 1;
92
93QDM_SHOWNUSERS;
94
95#ifdef QT_QWS_LOGIN_USEPAM
96
97static const char *_PAM_SERVICE = "xdm";
98static const char *PAM_password;
99
100typedef const struct pam_message pam_message_type;
101
102static int PAM_conv( int, pam_message_type **, struct pam_response **, void * );
103
104static struct pam_conv PAM_conversation = {
105 &PAM_conv,
106 NULL
107};
108
109//----------------------------------------------------------------------------
110
111static char *COPY_STRING( const char * s ) {
112 return (s) ? strdup(s) : (char *)NULL;
113}
114
115#define GET_MEM if (reply) realloc(reply, size);\
116 else reply = (struct pam_response *)malloc(size); \
117 if (!reply) return PAM_CONV_ERR; \
118 size += sizeof(struct pam_response)
119
120
121static int PAM_conv( int num_msg, pam_message_type **msg,
122 struct pam_response **resp, void *)
123{
124 int count = 0, replies = 0;
125 struct pam_response *reply = NULL;
126 int size = sizeof(struct pam_response);
127
128 for( count = 0; count < num_msg; count++ ) {
129 switch (msg[count]->msg_style) {
130 case PAM_PROMPT_ECHO_ON:
131 /* user name given to PAM already */
132 return PAM_CONV_ERR;
133
134 case PAM_PROMPT_ECHO_OFF:
135 /* wants password */
136 GET_MEM;
137 reply[replies].resp_retcode = PAM_SUCCESS;
138 reply[replies].resp = COPY_STRING(PAM_password);
139 replies++;
140 /* PAM frees resp */
141 break;
142 case PAM_TEXT_INFO:
143 break;
144 default:
145 /* unknown or PAM_ERROR_MSG */
146 if (reply) free (reply);
147 return PAM_CONV_ERR;
148 }
149 }
150 if (reply) *resp = reply;
151 return PAM_SUCCESS;
152}
153
154#endif
155
156
157//----------------------------------------------------------------------------
158
159QDMDialogImpl::QDMDialogImpl( QWidget* parent, const char* name, bool modal, WFlags f )
160 : QDMDialog( parent, name, modal, f )
161{
162 showTime();
163 clockTimer = startTimer( ShowClockFreq * 1000 );//-- call timer evry min.
164 setActiveWindow();
165 setFocus();
166
167 input = new InputMethods( this );
168 input->resize( input->sizeHint() );
169 input->move( 0, height() - input->height() );
170
171 for( int i=0; Shown_Users[i]; ++i ) {
172 input_user->insertItem( Shown_Users[i] );
173 }
174 input_user->clearEdit();
175
176 label_welcome->setText( QDM_WELCOME_STRING );
177
178};
179
180
181
182QDMDialogImpl::~QDMDialogImpl()
183{
184 input->lower();
185 input->close( false );
186 input->hide();
187 delete input;
188 input = 0;
189 if( parent() ) {
190 ((QWidget*)parent())->repaint(true);
191 }
192};
193
194
195void QDMDialogImpl::accept () { };
196void QDMDialogImpl::reject () { };
197
198
199void QDMDialogImpl::showTime( void )
200{
201 label_date->setText( QDate::currentDate().toString() );
202 label_time->setText( QTime::currentTime().toString() );
203}
204
205
206void QDMDialogImpl::timerEvent( QTimerEvent * e )
207{
208 if( e->timerId() == clockTimer )
209 showTime();
210}
211
212
213//----------------------------------------------------------------------------
214
215void QDMDialogImpl::slot_sleepmode()
216{
217 const int button = QMessageBox::warning( this, "Shutdown", tr( "Do you really want to go\nto sleep mode now?" ),
218 QString::null, tr( "Cancel" ), QString::null,0,1 );
219 switch( button ) {
220 case 0:
221 done( Rejected );
222 // Global::execute( cmd_shutdown );
223 if( vfork() == 0 ) {
224 execl( QDM_CMD_SLEEP, 0 );
225 cerr << "Sleepmode: " << strerror( errno ) << endl;
226 }
227 break;
228
229 default:
230 break;
231 }
232}
233
234
235//----------------------------------------------------------------------------
236
237void QDMDialogImpl::slot_shutdown()
238{
239 const int button = QMessageBox::warning( this, "Shutdown", tr("Do you really want to shut\nthe system down now?"),
240 QString::null, tr("Cancel"), QString::null,0,1 );
241 switch( button ) {
242 case 0:
243 done( Rejected );
244 // Global::execute( cmd_shutdown );
245 if( vfork() == 0 ) {
246 execl( QDM_CMD_SHUTDOWN, 0 );
247 cerr << "Shutdown: " << strerror( errno ) << endl;
248 }
249 break;
250
251 default:
252 break;
253 }
254}
255
256
257
258
259//----------------------------------------------------------------------------
260
261void QDMDialogImpl::informBadPassword()
262{
263 QMessageBox::warning( this, tr("Password wrong"),
264 tr("The given password is incorrect") );
265}
266
267
268//----------------------------------------------------------------------------
269
270#if defined(QT_QWS_LOGIN_USEPAM)
271
272static bool pwcheck_PAM( const char *user, const char *password )
273{
274 bool pw_correct = false;
275 int pam_error;
276 int pam_return = 0;
277 pam_handle_t *pamh = 0;
278 PAM_password = password.latin1();
279
280 pam_error = pam_start( _PAM_SERVICE, user, &PAM_conversation, &pamh );
281 if( pam_error == PAM_SUCCESS ) {
282 pam_error = pam_authenticate( pamh, 0 );
283 if( pam_error == PAM_SUCCESS ) {
284 //-- password correct
285 pw_correct = true;
286 pam_return = PAM_SUCCESS;
287 } else {
288 pam_return = pam_error;
289 }
290 } else {
291 // cerr << "PAM error: " << pam_strerror( pamh, pam_error ) << endl;
292 }
293 pam_end( pamh, pam_return );
294 return pw_correct;
295}
296
297#else
298
299//----------------------------------------------------------------------------
300
301static bool pwcheck_Unix( const char *user, const char *password )
302{
303 struct passwd * pword = getpwnam( user );
304 if( pword ) {
305 if( strcmp( crypt(password, password), pword->pw_passwd) == 0 ) {
306 return true;
307 }
308 }
309 return false;
310}
311
312#endif
313
314
315
316//----------------------------------------------------------------------------
317
318void QDMDialogImpl::slot_login()
319{
320 bool pw_correct = false;
321 const char *username = input_user->currentText().latin1();
322 const char *password = input_password->text().latin1();
323
324 assert( username );
325
326#if defined(QT_QWS_LOGIN_USEPAM)
327 pw_correct = pwcheck_PAM( username, password );
328#else
329 pw_correct = pwcheck_Unix( username, password );
330#endif
331
332 if( pw_correct ) {
333 if( changePersona( username ) ) {
334 // cerr << "Password correct" << endl;
335 done( Accepted );
336 return;
337 }
338 } else {
339 // cerr << "Password incorrect" << endl;
340 }
341 informBadPassword();
342}
343
344
345//----------------------------------------------------------------------------
346
347bool QDMDialogImpl::changePersona( const char *username )
348{
349 int err;
350
351 //-- get some info on user <username>
352 struct passwd * pword;
353 pword = getpwnam( username );
354
355 if( pword == 0 )
356 return false;
357
358 gid_t gid = pword->pw_gid;
359 uid_t uid = pword->pw_uid;
360
361 //-- some very dirty hacks following
362 // extern int qws_display_id;
363 extern QString qws_qtePipeFilename();
364 extern QString qws_dataDir();
365
366
367 const QString QTEdataDir = qws_dataDir();
368 QString QTEdataDirNew = QTEdataDir;
369 QTEdataDirNew.replace( QRegExp("root"), username );
370
371 const char *qws_display_str = getenv("QWS_DISPLAY");
372
373 //-- get name of semaphore and lock
374 QString pipe = qws_qtePipeFilename();
375
376 //-- change owner of semaphore
377 key_t semkey = ftok( pipe.latin1(), 'd' );
378 int semid = semget( semkey, 0, 0 );
379 if( semid < 0 )
380 cerr << "error: semget, " << strerror( errno ) << endl;
381
382 struct shmid_ds shminfo;
383 semun arg;
384 semid_ds semidds;
385 arg.buf = & semidds;
386
387 if( semctl( semid, 0, IPC_STAT, arg ) < 0 )
388 cerr << "error: semctl stat, " << strerror( errno ) << endl;
389
390 arg.buf->sem_perm.uid = uid;
391 arg.buf->sem_perm.gid = gid;
392
393 if( semctl( semid, 0, IPC_SET, arg ) < 0 )
394 cerr << "error: semctl set, " << strerror( errno ) << endl;
395
396 //-- change owner of shared memory
397 key_t memkey = ftok( pipe.latin1(), 'm' );
398 int ramid = shmget( memkey, 0, 0 );
399 if( ramid < 0 ) cerr << "error: shmget, " << strerror( errno ) << endl;
400
401 if( shmctl( ramid, IPC_STAT, &shminfo ) < 0 )
402 cerr << "error: shmctl stat, " << strerror( errno ) << endl;
403
404 shminfo.shm_perm.uid = uid;
405 shminfo.shm_perm.gid = gid;
406
407 if( shmctl( ramid, IPC_SET, &shminfo ) < 0 )
408 cerr << "error: shmctl set, " << strerror( errno ) << endl;
409
410 //-- change owner of region manager
411 memkey = ftok( pipe.latin1(), 'r' );
412 int regionid = shmget( memkey, 0, 0 );
413 if( regionid < 0 )
414 cerr << "error: shmget, " << strerror( errno ) << endl;
415
416 if( shmctl( regionid, IPC_STAT, &shminfo ) < 0 )
417 cerr << "error: shmctl stat, " << strerror( errno ) << endl;
418
419 shminfo.shm_perm.uid = uid;
420 shminfo.shm_perm.gid = gid;
421
422 if( shmctl( regionid, IPC_SET, &shminfo ) < 0 )
423 cerr << "error: shmctl set, " << strerror( errno ) << endl;
424
425 // cerr << "ungrabbing qws display: " << qws_display_id << " on lock " << pipe << endl;
426 // QWSDisplay::ungrab();
427
428 //-- presenting socket-file to new user
429 chown( pipe.latin1(), uid, gid );
430 chown( QTEdataDir.latin1(), uid, gid );
431
432
433 //-- another dirty hack - force framebuffer to be writeable...
434 struct stat devstat;
435 if( ! stat( "/dev/fb0", &devstat ) ) {
436 if( chmod( "/dev/fb0", devstat.st_mode |S_IWOTH |S_IWUSR |S_IWGRP ) ) {
437 cerr << "chmod error: " << strerror( errno ) << endl;
438 }
439 }
440
441 err = rename( QTEdataDir, QTEdataDirNew ) ;
442 if( err < 0 ) cerr << "error: rename " << strerror(errno)
443 << " , " << QTEdataDir << " -> " << QTEdataDirNew << endl;
444
445 //
446 //-- actually change uid and gid
447 //
448 // cerr << "changing persona, uid: " << uid << " gid: " << gid << endl;
449
450 err = setgid( gid );
451 if( err != 0 ) cerr << "error: gid changePersona " << err << endl;
452
453 err = setuid( uid );
454 if( err != 0 ) cerr << "error: uid changePersona " << err << endl;
455
456
457 //-- set some environment
458 setenv( "QWS_DISPLAY", qws_display_str, true );
459 setenv( "LOGNAME", username, true );
460 setenv( "USER", username, true );
461 setenv( "HOME", pword->pw_dir, true );
462
463 // cout << "QTE data dir: " << qws_dataDir() << endl;
464
465 //-- I am reborn
466
467 return true;
468}
469
470
471
472//----------------------------------------------------------------------------
473
474bool QDMDialogImpl::login( QWidget *parent )
475{
476 //-- only when called as 'root' do login-box
477 if( getuid() != 0 )
478 return true;
479
480
481 //-- are we coming from a 'restart' ?
482 if( getenv("QDM_STARTED") )
483 return true;
484 else
485 unsetenv("QDM_STARTED");
486
487
488#ifndef QT_NO_TRANSLATION
489 QString lang = getenv( "LANG" );
490
491 QTranslator * trans = new QTranslator(qApp);
492 QString tfn = QPEApplication::qpeDir()+"/i18n/"+lang+"/login.qm";
493 if ( trans->load( tfn ))
494 qApp->installTranslator( trans );
495 else {
496 delete trans;
497 trans = 0;
498 }
499#endif
500
501 if( parent ) parent->erase();
502
503 QDMDialog *dialog = new QDMDialogImpl( parent, "Login", true //);
504 ,WStyle_NoBorder | WStyle_Customize );
505
506#if QT_VERSION >= 300
507 Q_CHECK_PTR( dialog );
508#else
509 CHECK_PTR( dialog );
510#endif
511 int result = dialog->exec();
512 delete dialog;
513
514 if( parent ) parent->erase();
515
516#ifndef QT_NO_TRANSLATION
517 if( trans ) {
518 qApp->removeTranslator( trans );
519 delete trans;
520 trans = 0;
521 }
522#endif
523
524 setenv( "QDM_STARTED", "", true );
525
526 // if( parent ) parent->erase();
527
528 //-- get all configs going
529 Global::restart();
530
531 return result;
532}
533
534
535#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 @@
1//-- -*- c++ -*-
2/**********************************************************************
3** Copyright (C) 2001 LISA Systems
4**
5** This file is an additional part of Qtopia Environment.
6**
7** This file may be distributed and/or modified under the terms of the
8** GNU General Public License version 2 as published by the Free Software
9** Foundation and appearing in the file LICENSE.GPL included in the
10** packaging of this file.
11**
12** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
13** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
14**
15** For further information contact info@lisa.de
16**
17**********************************************************************/
18
19/*
20 * AUTHOR: Christian Rahn
21 * EMAIL: cdr@lisa.de
22 *
23 * $Id$
24 */
25
26#ifndef _QDM_IMPL_H
27#define _QDM_IMPL_H
28
29#include "qdm_config.h"
30
31#if defined(QT_QWS_LOGIN)
32
33#include "qdmdialog.h"
34
35class InputMethods;
36
37class QDMDialogImpl : public QDMDialog
38{
39 Q_OBJECT
40
41 public:
42 /** Pop up login dialog and do all stuff */
43 static bool login( QWidget * parent = 0 );
44
45 protected:
46 /** a protected constructor */
47 QDMDialogImpl( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags f = 0 );
48 ~QDMDialogImpl();
49
50 /** Timer for clock display */
51 void timerEvent( QTimerEvent * );
52
53 /** The Timer for the clock */
54 int clockTimer;
55
56 /** Conersation function for PAM */
57 // int PAM_conv (int num_msg, pam_message_type **msg, struct pam_response **resp, void *);
58
59 /** Just become (i.e. log in as) user <name> */
60 bool changePersona( const char *name );
61
62 /** Inform about an incorrect given password */
63 void informBadPassword();
64
65private:
66 InputMethods *input;
67
68 protected slots:
69 /** These got to be overridden so that the login dialog can't be circumvented */
70 virtual void accept ();
71 virtual void reject ();
72
73public slots:
74 /** Display the atual time and date */
75 void showTime( void );
76
77 /** login button pressed */
78 virtual void slot_login();
79
80 /** Shutdown button pressed */
81 virtual void slot_shutdown();
82
83 /** Sleep button pressed */
84 virtual void slot_sleepmode();
85};
86
87#endif //-- QT_QWS_LOGIN
88
89#endif //-- _QDM_IMPL_H
90
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 @@
1moc_*
2Makefile
3abeditorbase.h
4abaddress.h
5abcompanybase.h
6abnamebase.h
7abeditorbase.cpp
8abaddress.cpp
9abcompanybase.cpp
10abnamebase.cpp
11abeditorpage2base.ui
12abeditorpage2base.h
13abeditorpage2base.cpp
14addresssettingsbase.h
15addresssettingsbase.cpp
16
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 @@
1#############################################################################
2
3####### Compiler, tools and options
4
5 CXX =$(SYSCONF_CXX) $(QT_CXX_MT)
6 CXXFLAGS=$(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
7 CC =$(SYSCONF_CC) $(QT_C_MT)
8 CFLAGS =$(SYSCONF_CFLAGS)
9 INCPATH =-I$(QPEDIR)/include
10 LFLAGS =$(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
11 LIBS =$(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
12 MOC =$(SYSCONF_MOC)
13 UIC =$(SYSCONF_UIC)
14
15####### Target
16
17DESTDIR = $(QPEDIR)/bin/
18VER_MAJ = 1
19VER_MIN = 0
20VER_PATCH = 0
21 TARGET= addressbook
22TARGET1 = lib$(TARGET).so.$(VER_MAJ)
23
24####### Files
25
26 HEADERS =addressbook.h \
27 abeditor.h \
28 ablabel.h \
29 abtable.h \
30 addresssettings.h
31 SOURCES =main.cpp \
32 addressbook.cpp \
33 abeditor.cpp \
34 ablabel.cpp \
35 abtable.cpp \
36 addresssettings.cpp
37 OBJECTS =main.o \
38 addressbook.o \
39 abeditor.o \
40 ablabel.o \
41 abtable.o \
42 addresssettings.o \
43 addresssettingsbase.o
44INTERFACES = addresssettingsbase.ui
45UICDECLS = addresssettingsbase.h
46UICIMPLS = addresssettingsbase.cpp
47 SRCMOC =moc_addressbook.cpp \
48 moc_abeditor.cpp \
49 moc_ablabel.cpp \
50 moc_abtable.cpp \
51 moc_addresssettings.cpp \
52 moc_addresssettingsbase.cpp
53 OBJMOC =moc_addressbook.o \
54 moc_abeditor.o \
55 moc_ablabel.o \
56 moc_abtable.o \
57 moc_addresssettings.o \
58 moc_addresssettingsbase.o
59
60
61####### Implicit rules
62
63.SUFFIXES: .cpp .cxx .cc .C .c
64
65.cpp.o:
66 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
67
68.cxx.o:
69 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
70
71.cc.o:
72 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
73
74.C.o:
75 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
76
77.c.o:
78 $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
79
80####### Build rules
81
82
83all: $(DESTDIR)$(TARGET)
84
85$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
86 $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
87
88moc: $(SRCMOC)
89
90tmake:
91 tmake p4addressbook.pro
92
93clean:
94 -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
95 -rm -f *~ core
96 -rm -f allmoc.cpp
97
98####### Extension Modules
99
100listpromodules:
101 @echo
102
103listallmodules:
104 @echo
105
106listaddonpromodules:
107 @echo
108
109listaddonentmodules:
110 @echo
111
112
113REQUIRES=
114
115####### Sub-libraries
116
117
118###### Combined headers
119
120
121
122####### Compile
123
124main.o: main.cpp \
125 addressbook.h \
126 $(QPEDIR)/include/qpe/qpeapplication.h \
127 $(QPEDIR)/include/qpe/qcopenvelope_qws.h
128
129addressbook.o: addressbook.cpp \
130 abeditor.h \
131 $(QPEDIR)/include/qpe/contact.h \
132 $(QPEDIR)/include/qpe/palmtoprecord.h \
133 $(QPEDIR)/include/qpe/recordfields.h \
134 ablabel.h \
135 abtable.h \
136 $(QPEDIR)/include/qpe/categories.h \
137 addresssettings.h \
138 addresssettingsbase.h \
139 addressbook.h \
140 $(QPEDIR)/include/qpe/qpeapplication.h \
141 $(QPEDIR)/include/qpe/config.h \
142 $(QPEDIR)/include/qpe/finddialog.h \
143 $(QPEDIR)/include/qpe/global.h \
144 $(QPEDIR)/include/qpe/resource.h \
145 $(QPEDIR)/include/qpe/ir.h \
146 $(QPEDIR)/include/qpe/qpemessagebox.h \
147 $(QPEDIR)/include/qpe/qcopenvelope_qws.h \
148 $(QPEDIR)/include/qpe/qpemenubar.h \
149 $(QPEDIR)/include/qpe/qpetoolbar.h
150
151abeditor.o: abeditor.cpp \
152 abeditor.h \
153 $(QPEDIR)/include/qpe/contact.h \
154 $(QPEDIR)/include/qpe/palmtoprecord.h \
155 $(QPEDIR)/include/qpe/recordfields.h \
156 addresspicker.h \
157 $(QPEDIR)/include/qpe/categoryselect.h \
158 $(QPEDIR)/include/qpe/qpeapplication.h \
159 $(QPEDIR)/include/qpe/qpedialog.h
160
161ablabel.o: ablabel.cpp \
162 ablabel.h \
163 $(QPEDIR)/include/qpe/contact.h \
164 $(QPEDIR)/include/qpe/palmtoprecord.h \
165 $(QPEDIR)/include/qpe/recordfields.h \
166 $(QPEDIR)/include/qpe/stringutil.h
167
168abtable.o: abtable.cpp \
169 $(QPEDIR)/include/qpe/categoryselect.h \
170 $(QPEDIR)/include/qpe/config.h \
171 $(QPEDIR)/include/qpe/stringutil.h \
172 $(QPEDIR)/include/qpe/qcopenvelope_qws.h \
173 abtable.h \
174 $(QPEDIR)/include/qpe/categories.h \
175 $(QPEDIR)/include/qpe/contact.h \
176 $(QPEDIR)/include/qpe/palmtoprecord.h \
177 $(QPEDIR)/include/qpe/recordfields.h
178
179addresssettings.o: addresssettings.cpp \
180 addresssettings.h \
181 addresssettingsbase.h \
182 $(QPEDIR)/include/qpe/config.h \
183 $(QPEDIR)/include/qpe/contact.h \
184 $(QPEDIR)/include/qpe/palmtoprecord.h \
185 $(QPEDIR)/include/qpe/recordfields.h
186
187addresssettingsbase.h: addresssettingsbase.ui
188 $(UIC) addresssettingsbase.ui -o $(INTERFACE_DECL_PATH)/addresssettingsbase.h
189
190addresssettingsbase.cpp: addresssettingsbase.ui
191 $(UIC) addresssettingsbase.ui -i addresssettingsbase.h -o addresssettingsbase.cpp
192
193addresssettingsbase.o: addresssettingsbase.cpp \
194 addresssettingsbase.h \
195 addresssettingsbase.ui
196
197moc_addressbook.o: moc_addressbook.cpp \
198 addressbook.h
199
200moc_abeditor.o: moc_abeditor.cpp \
201 abeditor.h \
202 $(QPEDIR)/include/qpe/contact.h \
203 $(QPEDIR)/include/qpe/palmtoprecord.h \
204 $(QPEDIR)/include/qpe/recordfields.h
205
206moc_ablabel.o: moc_ablabel.cpp \
207 ablabel.h \
208 $(QPEDIR)/include/qpe/contact.h \
209 $(QPEDIR)/include/qpe/palmtoprecord.h \
210 $(QPEDIR)/include/qpe/recordfields.h
211
212moc_abtable.o: moc_abtable.cpp \
213 abtable.h \
214 $(QPEDIR)/include/qpe/categories.h \
215 $(QPEDIR)/include/qpe/contact.h \
216 $(QPEDIR)/include/qpe/palmtoprecord.h \
217 $(QPEDIR)/include/qpe/recordfields.h
218
219moc_addresssettings.o: moc_addresssettings.cpp \
220 addresssettings.h \
221 addresssettingsbase.h
222
223moc_addresssettingsbase.o: moc_addresssettingsbase.cpp \
224 addresssettingsbase.h
225
226moc_addressbook.cpp: addressbook.h
227 $(MOC) addressbook.h -o moc_addressbook.cpp
228
229moc_abeditor.cpp: abeditor.h
230 $(MOC) abeditor.h -o moc_abeditor.cpp
231
232moc_ablabel.cpp: ablabel.h
233 $(MOC) ablabel.h -o moc_ablabel.cpp
234
235moc_abtable.cpp: abtable.h
236 $(MOC) abtable.h -o moc_abtable.cpp
237
238moc_addresssettings.cpp: addresssettings.h
239 $(MOC) addresssettings.h -o moc_addresssettings.cpp
240
241moc_addresssettingsbase.cpp: addresssettingsbase.h
242 $(MOC) addresssettingsbase.h -o moc_addresssettingsbase.cpp
243
244
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qt Palmtop Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "abeditor.h"
22#include "addresspicker.h"
23
24#include <qpe/categoryselect.h>
25#include <qpe/qpeapplication.h>
26#include <qpe/qpedialog.h>
27
28#include <qcombobox.h>
29#include <qlabel.h>
30#include <qlayout.h>
31#include <qlineedit.h>
32#include <qmultilineedit.h>
33#include <qscrollview.h>
34#include <qtoolbutton.h>
35#include <qpushbutton.h>
36#include <qmainwindow.h>
37
38
39static inline bool containsAlphaNum( const QString &str );
40static inline bool constainsWhiteSpace( const QString &str );
41
42
43// helper functions, convert our comma delimited list to proper
44// file format...
45void parseEmailFrom( const QString &txt, QString &strDefaultEmail,
46 QString &strAll );
47
48// helper convert from file format to comma delimited...
49void parseEmailTo( const QString &strDefaultEmail,
50 const QString &strOtherEmail, QString &strBack );
51
52
53
54AbEditor::AbEditor( const Contact &entry, const QValueList<int> *newOrdered,
55 QStringList *slNewOrdered,
56 QWidget *parent = 0, const char *name = 0, WFlags fl = 0 )
57 : QDialog( parent, name, TRUE, fl ),
58 orderedValues( newOrdered ),
59 slOrdered( slNewOrdered )
60{
61 init();
62 initMap();
63 setEntry( entry );
64}
65
66AbEditor::~AbEditor()
67{
68}
69
70void AbEditor::init()
71{
72 middleEdit = 0;
73 QVBoxLayout *vb = new QVBoxLayout( this );
74 svPage = new QScrollView( this );
75 svPage->setHScrollBarMode( QScrollView::AlwaysOff );
76 vb->addWidget( svPage );
77 svPage->setResizePolicy( QScrollView::AutoOneFit );
78 svPage->setFrameStyle( QFrame::NoFrame );
79
80 QWidget *container = new QWidget( svPage->viewport() );
81 svPage->addChild( container );
82
83 QGridLayout *gl = new QGridLayout( container, 20, 2, 4, 2 );
84
85 QLabel *l = new QLabel( tr("First Name"), container );
86 gl->addWidget( l, 0, 0 );
87 firstEdit = new QLineEdit( container );
88 gl->addWidget( firstEdit, 0, 1 );
89
90 l = new QLabel( tr("Last Name"), container );
91 gl->addWidget( l, 1, 0 );
92 lastEdit = new QLineEdit( container );
93 gl->addWidget( lastEdit, 1, 1 );
94
95 l = new QLabel( tr("Categories"), container );
96 gl->addWidget( l, 2, 0 );
97
98 cmbCat = new CategorySelect( container );
99 gl->addWidget( cmbCat, 2, 1 );
100
101 int i;
102 bool foundGender,
103 foundNotes;
104 foundGender = foundNotes = false;
105 QStringList::ConstIterator it = slOrdered->begin();
106 for ( i = 0; it != slOrdered->end(); i++, ++it ) {
107 if ( !foundGender && *it == tr("Gender") ) {
108 foundGender = true;
109 } else if ( !foundNotes && *it == tr("Notes") ) {
110 foundNotes = true;
111 } else {
112 l = new QLabel( *it, container );
113 listName.append( l );
114 gl->addWidget( l, i + 3, 0 );
115 QLineEdit *e = new QLineEdit( container );
116 listValue.append( e );
117 gl->addWidget( e, i + 3, 1 );
118 if ( *it == tr( "Middle Name" ) )
119 middleEdit = e;
120 }
121 }
122 l = new QLabel( tr("Gender"), container );
123 gl->addWidget( l, slOrdered->count() + 3, 0 );
124 genderCombo = new QComboBox( container );
125 genderCombo->insertItem( "", 0 );
126 genderCombo->insertItem( tr( "Male" ), 1 );
127 genderCombo->insertItem( tr( "Female" ), 2 );
128 gl->addWidget( genderCombo, slOrdered->count() + 3, 1 );
129
130 dlgNote = new QDialog( this, "Note Dialog", TRUE );
131 dlgNote->setCaption( tr("Enter Note") );
132 QVBoxLayout *vbNote = new QVBoxLayout( dlgNote );
133 // lblNote = new QLabel( dlgNote );
134 // lblNote->setMinimumSize( lblNote->sizeHint() + QSize( 0, 4 ) );
135 // vbNote->addWidget( lblNote );
136 txtNote = new QMultiLineEdit( dlgNote );
137 vbNote->addWidget( txtNote );
138
139 QHBoxLayout *hb = new QHBoxLayout( vb );
140 hb->addStretch( 2 );
141 QPushButton *pb = new QPushButton( tr("Notes..."), this );
142 hb->addWidget( pb );
143 connect( pb, SIGNAL(clicked()), this, SLOT(slotNote()) );
144
145 new QPEDialogListener(this);
146}
147
148void AbEditor::initMap()
149{
150 /*
151 // since the fields and the XML fields exist, create a map
152 // between them...
153 Config cfg1( "AddressBook" );
154 Config cfg2( "AddressBook" );
155 QString strCfg1,
156 strCfg2;
157 int i;
158
159 // This stuff better exist...
160 cfg1.setGroup( "AddressFields" );
161 cfg2.setGroup( "XMLFields" );
162 i = 0;
163 strCfg1 = cfg1.readEntry( "Field" + QString::number(i), QString::null );
164 strCfg2 = cfg2.readEntry( "XMLField" + QString::number(i++),
165 QString::null );
166 while ( !strCfg1.isNull() && !strCfg2.isNull() ) {
167 mapField.insert( strCfg1, strCfg2 );
168 strCfg1 = cfg1.readEntry( "Field" + QString::number(i),
169 QString::null );
170 strCfg2 = cfg2.readEntry( "XMLField" + QString::number(i++),
171 QString::null );
172 }
173 */
174}
175
176void AbEditor::loadFields()
177{
178 QStringList::ConstIterator it;
179 QListIterator<QLabel> lit( listName );
180 for ( it = slOrdered->begin(); *lit; ++lit, ++it ) {
181 (*lit)->setText( *it );
182 }
183}
184
185void AbEditor::setEntry( const Contact &entry )
186{
187 ent = entry;
188 QListIterator<QLineEdit> it( listValue );
189 firstEdit->setText( ent.firstName() );
190 lastEdit->setText( ent.lastName() );
191 cmbCat->setCategories( ent.categories(), "Contacts", tr("Contacts") );
192
193 // ### Fix...
194 QValueList<int>::ConstIterator itVl;
195 for ( itVl = orderedValues->begin(); *it && itVl != orderedValues->end();
196 ++itVl, ++it ) {
197 switch( *itVl ) {
198 case Qtopia::Title:
199 (*it)->setText(ent.title());
200 break;
201 case Qtopia::MiddleName:
202 (*it)->setText( ent.middleName() );
203 break;
204 case Qtopia::Suffix:
205 (*it)->setText( ent.suffix() );
206 break;
207
208 // email
209 case Qtopia::DefaultEmail:
210 case Qtopia::Emails:
211 {
212 QString strDefEmail = ent.defaultEmail();
213 QString strAllEmail = ent.emails();
214 QString strFinal;
215 parseEmailTo( strDefEmail, strAllEmail, strFinal );
216 (*it)->setText( strFinal );
217 // make sure we see the "default"
218 (*it)->home( false );
219 break;
220 }
221
222 // home
223 case Qtopia::HomeStreet:
224 (*it)->setText(ent.homeStreet() );
225 break;
226 case Qtopia::HomeCity:
227 (*it)->setText( ent.homeCity() );
228 break;
229 case Qtopia::HomeState:
230 (*it)->setText( ent.homeState() );
231 break;
232 case Qtopia::HomeZip:
233 (*it)->setText( ent.homeZip() );
234 break;
235 case Qtopia::HomeCountry:
236 (*it)->setText( ent.homeCountry() );
237 break;
238 case Qtopia::HomePhone:
239 (*it)->setText( ent.homePhone() );
240 break;
241 case Qtopia::HomeFax:
242 (*it)->setText( ent.homeFax() );
243 break;
244 case Qtopia::HomeMobile:
245 (*it)->setText( ent.homeMobile() );
246 break;
247 case Qtopia::HomeWebPage:
248 (*it)->setText( ent.homeWebpage() );
249 break;
250
251 // business
252 case Qtopia::Company:
253 (*it)->setText( ent.company() );
254 break;
255 case Qtopia::BusinessStreet:
256 (*it)->setText( ent.businessStreet() );
257 break;
258 case Qtopia::BusinessCity:
259 (*it)->setText( ent.businessCity() );
260 break;
261 case Qtopia::BusinessState:
262 (*it)->setText( ent.businessState() );
263 break;
264 case Qtopia::BusinessZip:
265 (*it)->setText( ent.businessZip() );
266 break;
267 case Qtopia::BusinessCountry:
268 (*it)->setText( ent.businessCountry() );
269 break;
270 case Qtopia::BusinessWebPage:
271 (*it)->setText( ent.businessWebpage() );
272 break;
273 case Qtopia::JobTitle:
274 (*it)->setText( ent.jobTitle() );
275 break;
276 case Qtopia::Department:
277 (*it)->setText( ent.department() );
278 break;
279 case Qtopia::Office:
280 (*it)->setText( ent.office() );
281 break;
282 case Qtopia::BusinessPhone:
283 (*it)->setText( ent.businessPhone() );
284 break;
285 case Qtopia::BusinessFax:
286 (*it)->setText( ent.businessFax() );
287 break;
288 case Qtopia::BusinessMobile:
289 (*it)->setText( ent.businessMobile() );
290 break;
291 case Qtopia::BusinessPager:
292 (*it)->setText( ent.businessPager() );
293 break;
294 case Qtopia::Profession:
295 (*it)->setText( ent.profession() );
296 break;
297 case Qtopia::Assistant:
298 (*it)->setText( ent.assistant() );
299 break;
300 case Qtopia::Manager:
301 (*it)->setText( ent.manager() );
302 break;
303
304 // personal
305 case Qtopia::Spouse:
306 (*it)->setText( ent.spouse() );
307 break;
308 case Qtopia::Children:
309 (*it)->setText( ent.children() );
310 break;
311 case Qtopia::Birthday:
312 (*it)->setText( ent.birthday() );
313 break;
314 case Qtopia::Anniversary:
315 (*it)->setText( ent.anniversary() );
316 break;
317 case Qtopia::Nickname:
318 (*it)->setText( ent.nickname() );
319 break;
320
321 }
322 }
323
324 QString gender = ent.gender();
325 genderCombo->setCurrentItem( gender.toInt() );
326
327 txtNote->setText( ent.notes() );
328}
329
330void AbEditor::accept()
331{
332 if ( isEmpty() )
333 reject();
334 else {
335 saveEntry();
336 QDialog::accept();
337 }
338}
339
340bool AbEditor::isEmpty()
341{
342 // analyze all the fields and make sure there is _something_ there
343 // that warrants saving...
344 QString t = firstEdit->text();
345 if ( !t.isEmpty() && containsAlphaNum( t ) )
346 return false;
347
348 t = lastEdit->text();
349 if ( !t.isEmpty() && containsAlphaNum( t ) )
350 return false;
351
352 QListIterator<QLineEdit> it( listValue );
353 for ( ; it.current(); ++it ) {
354 t = it.current()->text();
355 if ( !t.isEmpty() && containsAlphaNum( t ) )
356 return false;
357 }
358
359 t = txtNote->text();
360 if ( !t.isEmpty() && containsAlphaNum( t ) )
361 return false;
362
363 return true;
364}
365
366void AbEditor::saveEntry()
367{
368 QString strDefaultEmail, strOtherEmail;
369
370 // determine if there has been a change in names
371 if ( ent.firstName() != firstEdit->text() ||
372 ent.lastName() != lastEdit->text()
373 || (middleEdit && ent.middleName() != middleEdit->text()) ) {
374 // set the names
375 ent.setFirstName( firstEdit->text() );
376 ent.setLastName( lastEdit->text() );
377 if ( middleEdit )
378 ent.setMiddleName( middleEdit->text() );
379 ent.setFileAs();
380 }
381
382 ent.setCategories( cmbCat->currentCategories() );
383
384 QListIterator<QLineEdit> it( listValue );
385 int i;
386 QValueList<int>::ConstIterator<int> vlIt;
387 for ( i = 0, vlIt = orderedValues->begin();
388 it.current(); ++it, ++vlIt, i++ ) {
389 switch( *vlIt ) {
390 case Qtopia::Title:
391 ent.setTitle( it.current()->text() );
392 break;
393 case Qtopia::MiddleName:
394 ent.setMiddleName( it.current()->text() );
395 break;
396 case Qtopia::Suffix:
397 ent.setSuffix( it.current()->text() );
398 break;
399 // case Qtopia::Category:
400 // {
401 // // QStringList slCat = QStringList::split( ";", value );
402 // // QValueList<int> cat;
403 // // for ( QStringList::ConstIterator it = slCat.begin();
404 // // it != slCat.end(); ++it )
405 // // cat.append( (*it).toInt() );
406 // // ent.setCategories( cat );
407 // }
408 // break;
409
410 // email
411 case Qtopia::DefaultEmail:
412 case Qtopia::Emails:
413 parseEmailFrom( it.current()->text(), strDefaultEmail,
414 strOtherEmail );
415 ent.setDefaultEmail( strDefaultEmail );
416 ent.setEmails( strOtherEmail );
417 break;
418
419 // home
420 case Qtopia::HomeStreet:
421 ent.setHomeStreet( it.current()->text() );
422 break;
423 case Qtopia::HomeCity:
424 ent.setHomeCity( it.current()->text() );
425 break;
426 case Qtopia::HomeState:
427 ent.setHomeState( it.current()->text() );
428 break;
429 case Qtopia::HomeZip:
430 ent.setHomeZip( it.current()->text() );
431 break;
432 case Qtopia::HomeCountry:
433 ent.setHomeCountry( it.current()->text() );
434 break;
435 case Qtopia::HomePhone:
436 ent.setHomePhone( it.current()->text() );
437 break;
438 case Qtopia::HomeFax:
439 ent.setHomeFax( it.current()->text() );
440 break;
441 case Qtopia::HomeMobile:
442 ent.setHomeMobile( it.current()->text() );
443 break;
444 case Qtopia::HomeWebPage:
445 ent.setHomeWebpage( it.current()->text() );
446 break;
447
448 // business
449 case Qtopia::Company:
450 ent.setCompany( it.current()->text() );
451 break;
452 case Qtopia::BusinessStreet:
453 ent.setBusinessStreet( it.current()->text() );
454 break;
455 case Qtopia::BusinessCity:
456 ent.setBusinessCity( it.current()->text() );
457 break;
458 case Qtopia::BusinessState:
459 ent.setBusinessState( it.current()->text() );
460 break;
461 case Qtopia::BusinessZip:
462 ent.setBusinessZip( it.current()->text() );
463 break;
464 case Qtopia::BusinessCountry:
465 ent.setBusinessCountry( it.current()->text() );
466 break;
467 case Qtopia::BusinessWebPage:
468 ent.setBusinessWebpage( it.current()->text() );
469 break;
470 case Qtopia::JobTitle:
471 ent.setJobTitle( it.current()->text() );
472 break;
473 case Qtopia::Department:
474 ent.setDepartment( it.current()->text() );
475 break;
476 case Qtopia::Office:
477 ent.setOffice( it.current()->text() );
478 break;
479 case Qtopia::BusinessPhone:
480 ent.setBusinessPhone( it.current()->text() );
481 break;
482 case Qtopia::BusinessFax:
483 ent.setBusinessFax( it.current()->text() );
484 break;
485 case Qtopia::BusinessMobile:
486 ent.setBusinessMobile( it.current()->text() );
487 break;
488 case Qtopia::BusinessPager:
489 ent.setBusinessPager( it.current()->text() );
490 break;
491 case Qtopia::Profession:
492 ent.setProfession( it.current()->text() );
493 break;
494 case Qtopia::Assistant:
495 ent.setAssistant( it.current()->text() );
496 break;
497 case Qtopia::Manager:
498 ent.setManager( it.current()->text() );
499 break;
500
501 // personal
502 case Qtopia::Spouse:
503 ent.setSpouse( it.current()->text() );
504 break;
505 case Qtopia::Children:
506 ent.setChildren( it.current()->text() );
507 break;
508 case Qtopia::Birthday:
509 ent.setBirthday( it.current()->text() );
510 break;
511 case Qtopia::Anniversary:
512 ent.setAnniversary( it.current()->text() );
513 break;
514 case Qtopia::Nickname:
515 ent.setNickname( it.current()->text() );
516 break;
517 default:
518 break;
519
520 }
521 }
522
523 int gender = genderCombo->currentItem();
524 ent.setGender( QString::number( gender ) );
525
526 QString str = txtNote->text();
527 if ( !str.isNull() )
528 ent.setNotes( str );
529}
530
531void AbEditor::slotNote()
532{
533 dlgNote->showMaximized();
534 if ( !dlgNote->exec() ) {
535 // reset the note...
536 txtNote->setText( ent.notes() );
537 }
538}
539
540void AbEditor::setNameFocus()
541{
542 firstEdit->setFocus();
543}
544
545void parseEmailFrom( const QString &txt, QString &strDefaultEmail,
546 QString &strAll )
547{
548 int where,
549 start;
550 if ( txt.isEmpty() )
551 return;
552 // find the first
553 where = txt.find( ',' );
554 if ( where < 0 ) {
555 strDefaultEmail = txt;
556 strAll = txt;
557 } else {
558 strDefaultEmail = txt.left( where ).stripWhiteSpace();
559 strAll = strDefaultEmail;
560 while ( where > -1 ) {
561 strAll.append(" ");
562 start = where;
563 where = txt.find( ',', where + 1 );
564 if ( where > - 1 )
565 strAll.append( txt.mid(start + 1, where - start - 1).stripWhiteSpace() );
566 else // grab until the end...
567 strAll.append( txt.right(txt.length() - start - 1).stripWhiteSpace() );
568 }
569 }
570}
571
572void parseEmailTo( const QString &strDefaultEmail,
573 const QString &strOtherEmail, QString &strBack )
574{
575 // create a comma dilimeted set of emails...
576 // use the power of short circuiting...
577 bool foundDefault = false;
578 QString strTmp;
579 int start = 0;
580 int where;
581 // start at the beginng.
582 strBack = strDefaultEmail;
583 where = 0;
584 while ( where > -1 ) {
585 start = where;
586 where = strOtherEmail.find( ' ', where + 1 );
587 if ( where > 0 ) {
588 strTmp = strOtherEmail.mid( start, where - start ).stripWhiteSpace();
589 } else
590 strTmp = strOtherEmail.right( strOtherEmail.length() - start ).stripWhiteSpace();
591 if ( foundDefault || strTmp != strDefaultEmail ) {
592 strBack.append( ", " );
593 strBack.append( strTmp );
594 } else
595 foundDefault = true;
596 }
597}
598
599
600static inline bool containsAlphaNum( const QString &str )
601{
602 int i,
603 count = str.length();
604 for ( i = 0; i < count; i++ )
605 if ( !str[i].isSpace() )
606 return TRUE;
607 return FALSE;
608}
609
610static inline bool constainsWhiteSpace( const QString &str )
611{
612 int i,
613 count = str.length();
614 for (i = 0; i < count; i++ )
615 if ( str[i].isSpace() )
616 return TRUE;
617 return FALSE;
618}
619
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qt Palmtop Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef ABEDITOR_H
21#define ABEDITOR_H
22
23#include <qpe/contact.h>
24
25#include <qdialog.h>
26#include <qlist.h>
27#include <qmap.h>
28#include <qstringlist.h>
29
30class QScrollView;
31class QMultiLineEdit;
32class QLineEdit;
33class QLabel;
34class QComboBox;
35class CategorySelect;
36
37class AbEditor : public QDialog
38{
39 Q_OBJECT
40public:
41 AbEditor( const Contact &entry, const QValueList<int> *newOrdedValues,
42 QStringList *slNewOrdered,
43 QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
44 ~AbEditor();
45 void loadFields();
46 void setNameFocus();
47 Contact entry() const { return ent; }
48
49public slots:
50 void slotNote();
51 void setEntry( const Contact &entry );
52
53protected slots:
54 void accept();
55
56private:
57 void init();
58 void initMap();
59 void saveEntry();
60 bool isEmpty();
61
62private:
63 QDialog *dlgNote;
64 QLabel *lblNote;
65 QMultiLineEdit *txtNote;
66 Contact ent;
67 QScrollView *svPage;
68 QLineEdit *firstEdit;
69 QLineEdit *lastEdit;
70 QLineEdit *middleEdit;
71 QComboBox *genderCombo;
72 QList<QLineEdit> listValue;
73 QList<QLabel> listName;
74 const QValueList<int> *orderedValues;
75 QStringList *slOrdered;
76 CategorySelect *cmbCat;
77};
78
79#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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qt Palmtop Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "ablabel.h"
22
23#include <qpe/stringutil.h>
24
25#include <qregexp.h>
26#include <qstylesheet.h>
27
28AbLabel::AbLabel( QWidget *parent, const char *name )
29 : QTextView( parent, name )
30{
31}
32
33AbLabel::~AbLabel()
34{
35}
36
37void AbLabel::init( const Contact &entry )
38{
39 ent = entry;
40}
41
42void AbLabel::sync()
43{
44 QString text = ent.toRichText();
45 setText( text );
46}
47
48void AbLabel::keyPressEvent( QKeyEvent *e )
49{
50 if ( e->key() == Qt::Key_F33 ) {
51 emit okPressed();
52 }
53}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qt Palmtop Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef ABLABEL_H
21#define ABLABEL_H
22
23#include <qpe/contact.h>
24#include <qtextview.h>
25
26class AbLabel : public QTextView
27{
28 Q_OBJECT
29
30public:
31 AbLabel( QWidget *parent, const char *name = 0 );
32 ~AbLabel();
33
34public slots:
35 void init( const Contact &entry );
36 void sync();
37
38signals:
39 void okPressed();
40
41protected:
42 void keyPressEvent( QKeyEvent * );
43
44private:
45 Contact ent;
46
47};
48
49#endif // ABLABEL_H
50
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qt Palmtop Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include <qpe/categoryselect.h>
22#include <qpe/config.h>
23#include <qpe/stringutil.h>
24#include <qpe/qcopenvelope_qws.h>
25
26#include <qasciidict.h>
27#include <qdatetime.h>
28#include <qfile.h>
29
30#include "abtable.h"
31
32#include <errno.h>
33#include <fcntl.h>
34#include <unistd.h>
35#include <stdlib.h>
36
37#include <ctype.h> //toupper() for key hack
38
39static bool contactCompare( const Contact &cnt, const QRegExp &r, int category );
40
41//### qtmail/addresslist.cpp hardcodes this filename as well
42static QString journalFileName()
43{
44 QString str = getenv("HOME");
45 str +="/.abjournal";
46 return str;
47}
48
49
50
51/*!
52 \class AbTableItem abtable.h
53
54 \brief QTableItem based class for showing a field of an entry
55*/
56
57AbTableItem::AbTableItem( QTable *t, EditType et, const QString &s,
58 const QString &secondSortKey)
59 : QTableItem( t, et, s )
60{
61 // sortKey = s.lower() + QChar( '\0' ) + secondSortKey.lower();
62 sortKey = Qtopia::buildSortKey( s, secondSortKey );
63}
64
65int AbTableItem::alignment() const
66{
67 return AlignLeft|AlignVCenter;
68}
69
70QString AbTableItem::key() const
71{
72 return sortKey;
73}
74
75// A way to reset the item, without out doing a delete or a new...
76void AbTableItem::setItem( const QString &txt, const QString &secondKey )
77{
78 setText( txt );
79 sortKey = Qtopia::buildSortKey( txt, secondKey );
80
81 // sortKey = txt.lower() + QChar( '\0' ) + secondKey.lower();
82}
83
84/*!
85 \class AbPickItem abtable.h
86
87 \brief QTableItem based class for showing slection of an entry
88*/
89
90AbPickItem::AbPickItem( QTable *t ) :
91 QTableItem(t, WhenCurrent, "?")
92{
93}
94
95QWidget *AbPickItem::createEditor() const
96{
97 QComboBox* combo = new QComboBox( table()->viewport() );
98 ( (AbPickItem*)this )->cb = combo;
99 AbTable* t = static_cast<AbTable*>(table());
100 QStringList c = t->choiceNames();
101 int cur = 0;
102 for (QStringList::ConstIterator it = c.begin(); it!=c.end(); ++it) {
103 if ( *it == text() )
104 cur = combo->count();
105 combo->insertItem(*it);
106 }
107 combo->setCurrentItem(cur);
108 return combo;
109}
110
111void AbPickItem::setContentFromEditor( QWidget *w )
112{
113 if ( w->inherits("QComboBox") )
114 setText( ( (QComboBox*)w )->currentText() );
115 else
116 QTableItem::setContentFromEditor( w );
117}
118
119/*!
120 \class AbTable abtable.h
121
122 \brief QTable based class for showing a list of entries
123*/
124
125AbTable::AbTable( const QValueList<int> *order, QWidget *parent, const char *name )
126// #ifdef QT_QTABLE_NOHEADER_CONSTRUCTOR
127// : QTable( 0, 0, parent, name, TRUE ),
128// #else
129 : QTable( parent, name ),
130// #endif
131 lastSortCol( -1 ),
132 asc( TRUE ),
133 intFields( order ),
134 currFindRow( -2 ),
135 mCat( 0 )
136{
137 mCat.load( categoryFileName() );
138 setSelectionMode( NoSelection );
139 init();
140 setSorting( TRUE );
141 connect( this, SIGNAL(clicked(int,int,int,const QPoint &)),
142 this, SLOT(itemClicked(int,int)) );
143}
144
145AbTable::~AbTable()
146{
147}
148
149void AbTable::init()
150{
151 setNumRows( 0 );
152 setNumCols( 2 );
153
154 horizontalHeader()->setLabel( 0, tr( "Full Name" ));
155 horizontalHeader()->setLabel( 1, tr( "Contact" ));
156 setLeftMargin( 0 );
157 verticalHeader()->hide();
158}
159
160void AbTable::columnClicked( int col )
161{
162 if ( !sorting() )
163 return;
164
165 if ( lastSortCol == -1 )
166 lastSortCol = col;
167
168 if ( col == lastSortCol ) {
169 asc = !asc;
170 } else {
171 lastSortCol = col;
172 asc = TRUE;
173 }
174 resort();
175}
176
177void AbTable::resort()
178{
179 if ( sorting() ) {
180 if ( lastSortCol == -1 )
181 lastSortCol = 0;
182 sortColumn( lastSortCol, asc, TRUE );
183 updateVisible();
184 }
185}
186
187Contact AbTable::currentEntry()
188{
189 Contact cnt;
190 AbTableItem *abItem;
191 abItem = static_cast<AbTableItem*>(item( currentRow(), 0 ));
192 if ( abItem ) {
193 cnt = contactList[abItem];
194 }
195 return cnt;
196}
197
198void AbTable::replaceCurrentEntry( const Contact &newContact )
199{
200 int row = currentRow();
201 updateJournal( newContact, Contact::ACTION_REPLACE, row );
202 updateVisible();
203
204 journalFreeReplace( newContact, row );
205}
206
207void AbTable::deleteCurrentEntry()
208{
209 int row = currentRow();
210 AbTableItem *abItem;
211 abItem = static_cast<AbTableItem*>(item( row, 0 ));
212 Contact oldContact;
213 oldContact = contactList[abItem];
214 updateJournal( oldContact, Contact::ACTION_REMOVE, row );
215
216 // a little wasteful, but it ensure's there is only one place
217 // where we delete.
218 journalFreeRemove( row );
219 updateVisible();
220
221 if ( numRows() == 0 )
222 emit empty( TRUE );
223}
224
225void AbTable::clear()
226{
227 contactList.clear();
228 for ( int r = 0; r < numRows(); ++r ) {
229 for ( int c = 0; c < numCols(); ++c ) {
230 if ( cellWidget( r, c ) )
231 clearCellWidget( r, c );
232 clearCell( r, c );
233 }
234 }
235 setNumRows( 0 );
236}
237
238void AbTable::refresh()
239{
240 int rows = numRows();
241 QString value;
242 AbTableItem *abi;
243 for ( int r = 0; r < rows; ++r ) {
244 abi = static_cast<AbTableItem*>( item(r, 0) );
245 value = findContactContact( contactList[abi] );
246 static_cast<AbTableItem*>( item(r, 1) )->setItem( value, abi->text() );
247 }
248 resort();
249}
250
251void AbTable::keyPressEvent( QKeyEvent *e )
252{
253 char key = toupper( e->ascii() );
254
255 if ( key >= 'A' && key <= 'Z' )
256 moveTo( key );
257
258 switch( e->key() ) {
259 case Qt::Key_Space:
260 case Qt::Key_Return:
261 case Qt::Key_Enter:
262 emit details();
263 break;
264 default:
265 QTable::keyPressEvent( e );
266 }
267}
268
269void AbTable::moveTo( char c )
270{
271
272 int rows = numRows();
273 QString value;
274 AbTableItem *abi;
275 int r;
276 if ( asc ) {
277 r = 0;
278 while ( r < rows-1) {
279 abi = static_cast<AbTableItem*>( item(r, 0) );
280 QChar first = abi->key()[0];
281 //### is there a bug in QChar to char comparison???
282 if ( first.row() || first.cell() >= c )
283 break;
284 r++;
285 }
286 } else {
287 //### should probably disable reverse sorting instead
288 r = rows - 1;
289 while ( r > 0 ) {
290 abi = static_cast<AbTableItem*>( item(r, 0) );
291 QChar first = abi->key()[0];
292 //### is there a bug in QChar to char comparison???
293 if ( first.row() || first.cell() >= c )
294 break;
295 r--;
296 }
297 }
298 setCurrentCell( r, currentColumn() );
299}
300
301
302QString AbTable::findContactName( const Contact &entry )
303{
304 // We use the fileAs, then company, defaultEmail
305 QString str;
306 str = entry.fileAs();
307 if ( str.isEmpty() ) {
308 str = entry.company();
309 if ( str.isEmpty() ) {
310 str = entry.defaultEmail();
311 }
312 }
313 return str;
314}
315
316QString AbTable::findContactContact( const Contact &entry )
317{
318 QString value;
319 value = "";
320 for ( QValueList<int>::ConstIterator it = intFields->begin();
321 it != intFields->end(); ++it ) {
322 switch ( *it ) {
323 default:
324 break;
325 case Qtopia::Title:
326 value = entry.title();
327 break;
328 case Qtopia::Suffix:
329 value = entry.suffix();
330 break;
331 case Qtopia::FileAs:
332 value = entry.fileAs();
333 break;
334 case Qtopia::DefaultEmail:
335 value = entry.defaultEmail();
336 case Qtopia::Emails:
337 value = entry.emails();
338 break;
339 case Qtopia::HomeStreet:
340 value = entry.homeStreet();
341 break;
342 case Qtopia::HomeCity:
343 value = entry.homeCity();
344 break;
345 case Qtopia::HomeState:
346 value = entry.homeState();
347 break;
348 case Qtopia::HomeZip:
349 value = entry.homeZip();
350 break;
351 case Qtopia::HomeCountry:
352 value = entry.homeCountry();
353 break;
354 case Qtopia::HomePhone:
355 value = entry.homePhone();
356 break;
357 case Qtopia::HomeFax:
358 value = entry.homeFax();
359 break;
360 case Qtopia::HomeMobile:
361 value = entry.homeMobile();
362 break;
363 case Qtopia::HomeWebPage:
364 value = entry.homeWebpage();
365 break;
366 case Qtopia::Company:
367 value = entry.company();
368 break;
369 case Qtopia::BusinessCity:
370 value = entry.businessCity();
371 break;
372 case Qtopia::BusinessStreet:
373 value = entry.businessStreet();
374 break;
375 case Qtopia::BusinessZip:
376 value = entry.businessZip();
377 break;
378 case Qtopia::BusinessCountry:
379 value = entry.businessCountry();
380 break;
381 case Qtopia::BusinessWebPage:
382 value = entry.businessWebpage();
383 break;
384 case Qtopia::JobTitle:
385 value = entry.jobTitle();
386 break;
387 case Qtopia::Department:
388 value = entry.department();
389 break;
390 case Qtopia::Office:
391 value = entry.office();
392 break;
393 case Qtopia::BusinessPhone:
394 value = entry.businessPhone();
395 break;
396 case Qtopia::BusinessFax:
397 value = entry.businessFax();
398 break;
399 case Qtopia::BusinessMobile:
400 value = entry.businessMobile();
401 break;
402 case Qtopia::BusinessPager:
403 value = entry.businessPager();
404 break;
405 case Qtopia::Profession:
406 value = entry.profession();
407 break;
408 case Qtopia::Assistant:
409 value = entry.assistant();
410 break;
411 case Qtopia::Manager:
412 value = entry.manager();
413 break;
414 case Qtopia::Spouse:
415 value = entry.spouse();
416 break;
417 case Qtopia::Gender:
418 value = entry.gender();
419 break;
420 case Qtopia::Birthday:
421 value = entry.birthday();
422 break;
423 case Qtopia::Anniversary:
424 value = entry.anniversary();
425 break;
426 case Qtopia::Nickname:
427 value = entry.nickname();
428 break;
429 case Qtopia::Children:
430 value = entry.children();
431 break;
432 case Qtopia::Notes:
433 value = entry.notes();
434 break;
435 }
436 if ( !value.isEmpty() )
437 break;
438 }
439 return value;
440}
441
442void AbTable::addEntry( const Contact &newCnt )
443{
444 int row = numRows();
445 setNumRows( row + 1 );
446 updateJournal( newCnt, Contact::ACTION_ADD );
447 insertIntoTable( newCnt, row );
448 setCurrentCell( row, 0 );
449 updateVisible();
450}
451
452void AbTable::updateJournal( const Contact &cnt,
453 Contact::journal_action action, int row )
454{
455 QFile f( journalFileName() );
456 if ( !f.open(IO_WriteOnly|IO_Append) )
457 return;
458 QString buf;
459 QCString str;
460 buf = "<Contact ";
461 cnt.save( buf );
462 buf += " action=\"" + QString::number( (int)action ) + "\" ";
463 if ( action == Contact::ACTION_REMOVE || action == Contact::ACTION_REPLACE)
464 buf += " actionrow=\"" + QString::number(row) + "\" ";
465 buf += "/>\n";
466 QCString cstr = buf.utf8();
467 f.writeBlock( cstr.data(), cstr.length() );
468 QCopEnvelope( "QPE/PIM", "addressbookUpdated()" );
469}
470
471bool AbTable::save( const QString &fn )
472{
473// QTime t;
474// t.start();
475
476 QString strNewFile = fn + ".new";
477 QFile f( strNewFile );
478 if ( !f.open( IO_WriteOnly|IO_Raw ) )
479 return false;
480
481 int total_written;
482 QString out;
483 out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n"
484 " <Groups>\n"
485 " </Groups>\n"
486 " <Contacts>\n";
487 QMapIterator<AbTableItem*, Contact> it;
488 for ( it = contactList.begin(); it != contactList.end(); ++it ) {
489 out += "<Contact ";
490 it.data().save( out );
491 out += "/>\n";
492 QCString cstr = out.utf8();
493 total_written = f.writeBlock( cstr.data(), cstr.length() );
494 if ( total_written != int(cstr.length()) ) {
495 f.close();
496 QFile::remove( strNewFile );
497 return false;
498 }
499 out = "";
500 }
501 out += " </Contacts>\n</AddressBook>\n";
502
503 QCString cstr = out.utf8();
504 total_written = f.writeBlock( cstr.data(), cstr.length() );
505 if ( total_written != int(cstr.length()) ) {
506 f.close();
507 QFile::remove( strNewFile );
508 return false;
509 }
510 f.close();
511
512// qDebug("saving: %d", t.elapsed() );
513
514 // move the file over, I'm just going to use the system call
515 // because, I don't feel like using QDir.
516 if ( ::rename( strNewFile.latin1(), fn.latin1() ) < 0 ) {
517 qWarning( "problem renaming file %s to %s, errno: %d",
518 strNewFile.latin1(), fn.latin1(), errno );
519 // remove the tmp file...
520 QFile::remove( strNewFile );
521 }
522 // remove the journal...
523 QFile::remove( journalFileName() );
524 return true;
525}
526
527void AbTable::load( const QString &fn )
528{
529 setSorting( false );
530 loadFile( fn, false );
531 // merge in the journal
532 if ( QFile::exists( journalFileName() ) ) {
533 loadFile( journalFileName(), true );
534 save( fn );
535 }
536 setSorting( true );
537 resort();
538}
539
540void AbTable::loadFile( const QString &strFile, bool journalFile )
541{
542// QTime t;
543// t.start();
544 QFile f( strFile );
545 if ( !f.open(IO_ReadOnly) )
546 return;
547 QList<Contact> list;
548 list.setAutoDelete( TRUE );
549 QByteArray ba = f.readAll();
550 f.close();
551 char *uc = ba.data();//(QChar *)data.unicode();
552 int len = ba.size();//data.length();
553 bool foundAction = false;
554 Contact::journal_action action;
555 bool foundKey = false;
556 int journalKey = 0;
557
558 const int JOURNALACTION = Qtopia::Notes + 1;
559 const int JOURNALROW = JOURNALACTION + 1;
560
561 // **********************************
562 // CHANGE THE SIZE OF THE DICT IF YOU ADD ANY MORE FIELDS!!!!
563 // **********************************
564 QAsciiDict<int> dict( 47 );
565 dict.setAutoDelete( TRUE );
566 dict.insert( "Uid", new int(Qtopia::AddressUid) );
567 dict.insert( "Title", new int(Qtopia::Title) );
568 dict.insert( "FirstName", new int(Qtopia::FirstName) );
569 dict.insert( "MiddleName", new int(Qtopia::MiddleName) );
570 dict.insert( "LastName", new int(Qtopia::LastName) );
571 dict.insert( "Suffix", new int(Qtopia::Suffix) );
572 dict.insert( "FileAs", new int(Qtopia::FileAs) );
573 dict.insert( "Categories", new int(Qtopia::AddressCategory) );
574 dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) );
575 dict.insert( "Emails", new int(Qtopia::Emails) );
576 dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) );
577 dict.insert( "HomeCity", new int(Qtopia::HomeCity) );
578 dict.insert( "HomeState", new int(Qtopia::HomeState) );
579 dict.insert( "HomeZip", new int(Qtopia::HomeZip) );
580 dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) );
581 dict.insert( "HomePhone", new int(Qtopia::HomePhone) );
582 dict.insert( "HomeFax", new int(Qtopia::HomeFax) );
583 dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) );
584 dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) );
585 dict.insert( "Company", new int(Qtopia::Company) );
586 dict.insert( "BusinessStreet", new int(Qtopia::BusinessStreet) );
587 dict.insert( "BusinessCity", new int(Qtopia::BusinessCity) );
588 dict.insert( "BusinessState", new int(Qtopia::BusinessState) );
589 dict.insert( "BusinessZip", new int(Qtopia::BusinessZip) );
590 dict.insert( "BusinessCountry", new int(Qtopia::BusinessCountry) );
591 dict.insert( "BusinessWebPage", new int(Qtopia::BusinessWebPage) );
592 dict.insert( "JobTitle", new int(Qtopia::JobTitle) );
593 dict.insert( "Department", new int(Qtopia::Department) );
594 dict.insert( "Office", new int(Qtopia::Office) );
595 dict.insert( "BusinessPhone", new int(Qtopia::BusinessPhone) );
596 dict.insert( "BusinessFax", new int(Qtopia::BusinessFax) );
597 dict.insert( "BusinessMobile", new int(Qtopia::BusinessMobile) );
598 dict.insert( "BusinessPager", new int(Qtopia::BusinessPager) );
599 dict.insert( "Profession", new int(Qtopia::Profession) );
600 dict.insert( "Assistant", new int(Qtopia::Assistant) );
601 dict.insert( "Manager", new int(Qtopia::Manager) );
602 dict.insert( "Spouse", new int(Qtopia::Spouse) );
603 dict.insert( "Children", new int(Qtopia::Children) );
604 dict.insert( "Gender", new int(Qtopia::Gender) );
605 dict.insert( "Birthday", new int(Qtopia::Birthday) );
606 dict.insert( "Anniversary", new int(Qtopia::Anniversary) );
607 dict.insert( "Nickname", new int(Qtopia::Nickname) );
608 dict.insert( "Notes", new int(Qtopia::Notes) );
609 dict.insert( "action", new int(JOURNALACTION) );
610 dict.insert( "actionrow", new int(JOURNALROW) );
611
612 int i = 0;
613 int num = 0;
614 char *point;
615 while ( (point = strstr( uc+i, "<Contact " ) ) != NULL ) {
616 i = point - uc;
617 // if we are reading the standard file, we just need to
618 // insert info, so just say we'll do an insert...
619 action = Contact::ACTION_ADD;
620 // new Contact
621 Contact *cnt = new Contact;
622 i += 9;
623 while ( 1 ) {
624 while ( i < len && (uc[i] == ' ' || uc[i] == '\n' || uc[i] == '\r') )
625 i++;
626 if ( i >= len-2 || (uc[i] == '/' && uc[i+1] == '>') )
627 break;
628 // we have another attribute read it.
629 int j = i;
630 while ( j < len && uc[j] != '=' )
631 j++;
632 char *attr = uc+i;
633 uc[j] = '\0';
634 //qDebug("attr=%s", attr.latin1() );
635 i = ++j; // skip =
636 while ( i < len && uc[i] != '"' )
637 i++;
638 j = ++i;
639 bool haveEnt = FALSE;
640 bool haveUtf = FALSE;
641 while ( j < len && uc[j] != '"' ) {
642 if ( uc[j] == '&' )
643 haveEnt = TRUE;
644 if ( ((unsigned char)uc[j]) > 0x7f )
645 haveUtf = TRUE;
646 j++;
647 }
648
649 if ( j == i ) {
650 // empty value
651 i = j + 1;
652 continue;
653 }
654
655 QString value = haveUtf ? QString::fromUtf8( uc+i, j-i )
656 : QString::fromLatin1( uc+i, j-i );
657 if ( haveEnt )
658 value = Qtopia::plainString( value );
659 i = j + 1;
660
661 int *find = dict[ attr ];
662 if ( !find ) {
663 cnt->setCustomField(attr, value);
664 continue;
665 }
666#if 1
667 switch( *find ) {
668 case Qtopia::AddressUid:
669 cnt->setUid( value.toInt() );
670 break;
671 case Qtopia::AddressCategory:
672 cnt->setCategories( Qtopia::Record::idsFromString( value ));
673 break;
674 case JOURNALACTION:
675 action = Contact::journal_action(value.toInt());
676 break;
677 case JOURNALROW:
678 journalKey = value.toInt();
679 break;
680
681 default:
682 cnt->insert( *find, value );
683 break;
684 }
685#endif
686 }
687
688 // sadly we can't delay adding of items from the journal to get
689 // the proper effect, but then, the journal should _never_ be
690 // that huge, and recovering from a crash is not necessarily
691 // a *fast* thing.
692 switch ( action ) {
693 case Contact::ACTION_ADD:
694 if ( journalFile ) {
695 int myrows = numRows();
696 setNumRows( myrows + 1 );
697 insertIntoTable( *cnt, myrows );
698 delete cnt;
699 }
700 else
701 list.append( cnt );
702 break;
703 case Contact::ACTION_REMOVE:
704 // yup, we don't use the entry to remove the object...
705 journalFreeRemove( journalKey );
706 delete cnt;
707 break;
708 case Contact::ACTION_REPLACE:
709 journalFreeReplace( *cnt, journalKey );
710 delete cnt;
711 break;
712 default:
713 break;
714 }
715 num++;
716 foundAction = false;
717 foundKey = false;
718 // if ( num % 100 == 0 ) {
719 // qDebug("loading file, num=%d, t=%d", num, t.elapsed() );
720 // }
721 }
722 if ( list.count() > 0 ) {
723 internalAddEntries( list );
724 }
725// qDebug("done loading %d, t=%d", num, t.elapsed() );
726
727}
728
729void AbTable::realignTable( int row )
730{
731 QTableItem *ti1,
732 *ti2;
733 int totalRows = numRows();
734 for ( int curr = row; curr < totalRows - 1; curr++ ) {
735 // the same info from the todo list still applies, but I
736 // don't think it is _too_ bad.
737 ti1 = item( curr + 1, 0 );
738 ti2 = item( curr + 1, 1 );
739 takeItem( ti1 );
740 takeItem( ti2 );
741 setItem( curr, 0, ti1 );
742 setItem( curr, 1, ti2 );
743 }
744 setNumRows( totalRows - 1 );
745 resort();
746}
747
748void AbTable::insertIntoTable( const Contact &cnt, int row )
749{
750 QString strName,
751 strContact;
752
753 strName = findContactName( cnt );
754 strContact = findContactContact( cnt );
755
756 AbTableItem *ati;
757 ati = new AbTableItem( this, QTableItem::Never, strName, strContact);
758 contactList.insert( ati, cnt );
759 setItem( row, 0, ati );
760 ati = new AbTableItem( this, QTableItem::Never, strContact, strName);
761 setItem( row, 1, ati );
762
763 //### cannot do this; table only has two columns at this point
764 // setItem( row, 2, new AbPickItem( this ) );
765
766 // resort at some point?
767}
768
769void AbTable::internalAddEntries( QList<Contact> &list )
770{
771 setUpdatesEnabled( FALSE );
772 setNumRows( list.count() );
773 int row = 0;
774 Contact *it;
775 for ( it = list.first(); it; it = list.next() )
776 insertIntoTable( *it, row++ );
777 resort();
778 setUpdatesEnabled( TRUE );
779}
780
781
782void AbTable::journalFreeReplace( const Contact &cnt, int row )
783{
784 QString strName,
785 strContact;
786 AbTableItem *ati;
787
788 strName = findContactName( cnt );
789 strContact = findContactContact( cnt );
790 ati = static_cast<AbTableItem*>(item(row, 0));
791 contactList.remove( ati );
792 ati->setItem( strName, strContact );
793 contactList.insert( ati, cnt );
794
795 ati = static_cast<AbTableItem*>(item(row, 1));
796 ati->setItem( strContact, strName );
797}
798
799void AbTable::journalFreeRemove( int row )
800{
801 AbTableItem *ati;
802 ati = static_cast<AbTableItem*>(item(row, 0));
803 if ( !ati )
804 return;
805 contactList.remove( ati );
806 realignTable( row );
807}
808
809#if QT_VERSION <= 230
810#ifndef SINGLE_APP
811void QTable::paintEmptyArea( QPainter *p, int cx, int cy, int cw, int ch )
812{
813 // Region of the rect we should draw
814 QRegion reg( QRect( cx, cy, cw, ch ) );
815 // Subtract the table from it
816 reg = reg.subtract( QRect( QPoint( 0, 0 ), tableSize() ) );
817 // And draw the rectangles (transformed as needed)
818 QArray<QRect> r = reg.rects();
819 for (unsigned int i=0; i<r.count(); i++)
820 p->fillRect( r[i], colorGroup().brush( QColorGroup::Base ) );
821}
822#endif
823#endif
824
825
826// int AbTable::rowHeight( int ) const
827// {
828// return 18;
829// }
830
831// int AbTable::rowPos( int row ) const
832// {
833// return 18*row;
834// }
835
836// int AbTable::rowAt( int pos ) const
837// {
838// return QMIN( pos/18, numRows()-1 );
839// }
840
841void AbTable::slotDoFind( const QString &findString, bool caseSensitive,
842 bool backwards, int category )
843{
844 if ( currFindRow < -1 )
845 currFindRow = currentRow() - 1;
846 clearSelection( TRUE );
847 int rows,
848 row;
849 AbTableItem *ati;
850 QRegExp r( findString );
851 r.setCaseSensitive( caseSensitive );
852 rows = numRows();
853 static bool wrapAround = true;
854
855 if ( !backwards ) {
856 for ( row = currFindRow + 1; row < rows; row++ ) {
857 ati = static_cast<AbTableItem*>( item(row, 0) );
858 if ( contactCompare( contactList[ati], r, category ) )
859 break;
860
861 }
862 } else {
863 for ( row = currFindRow - 1; row > -1; row-- ) {
864 ati = static_cast<AbTableItem*>( item(row, 0) );
865 if ( contactCompare( contactList[ati], r, category ) )
866 break;
867 }
868 }
869 if ( row >= rows || row < 0 ) {
870 if ( row < 0 )
871 currFindRow = rows;
872 else
873 currFindRow = -1;
874
875 if ( wrapAround )
876 emit signalWrapAround();
877 else
878 emit signalNotFound();
879
880 wrapAround = !wrapAround;
881 } else {
882 currFindRow = row;
883 QTableSelection foundSelection;
884 foundSelection.init( currFindRow, 0 );
885 foundSelection.expandTo( currFindRow, numCols() - 1 );
886 addSelection( foundSelection );
887 setCurrentCell( currFindRow, numCols() - 1 );
888 wrapAround = true;
889 }
890}
891
892static bool contactCompare( const Contact &cnt, const QRegExp &r, int category )
893{
894 bool returnMe;
895 QArray<int> cats;
896 cats = cnt.categories();
897
898 returnMe = false;
899 if ( (category == -1 && cats.count() == 0) || category == -2 )
900 returnMe = cnt.match( r );
901 else {
902 int i;
903 for ( i = 0; i < int(cats.count()); i++ ) {
904 if ( cats[i] == category ) {
905 returnMe = cnt.match( r );
906 break;
907 }
908 }
909 }
910 return returnMe;
911}
912
913void AbTable::fitColumns()
914{
915 int contentsWidth = visibleWidth();
916 int n = numCols();
917 int pw = n == 3 ? columnWidth(2) : 0;
918 setColumnWidth( 0, contentsWidth - contentsWidth / 2 );
919 setColumnWidth( 1, contentsWidth / 2 - pw );
920}
921
922void AbTable::show()
923{
924 fitColumns();
925 QTable::show();
926}
927
928void AbTable::setChoiceNames( const QStringList& list)
929{
930 choicenames = list;
931 if ( choicenames.isEmpty() ) {
932 // hide pick column
933 setNumCols( 2 );
934 } else {
935 // show pick column
936 setNumCols( 3 );
937 setColumnWidth( 2, fontMetrics().width(tr( "Pick" ))+8 );
938 horizontalHeader()->setLabel( 2, tr( "Pick" ));
939 }
940 fitColumns();
941}
942
943void AbTable::itemClicked(int,int col)
944{
945 if ( col == 2 ) {
946 return;
947 } else {
948 emit details();
949 }
950}
951
952QStringList AbTable::choiceNames() const
953{
954 return choicenames;
955}
956
957void AbTable::setChoiceSelection(int /*index*/, const QStringList& /*list*/)
958{
959 /* ######
960
961 QString selname = choicenames.at(index);
962 for (each row) {
963 Contact *c = contactForRow(row);
964 if ( list.contains(c->email) ) {
965 list.remove(c->email);
966 setText(row, 2, selname);
967 }
968 }
969 for (remaining list items) {
970 Contact *c = new contact(item);
971 setText(newrow, 2, selname);
972 }
973
974 */
975}
976
977QStringList AbTable::choiceSelection(int /*index*/) const
978{
979 QStringList r;
980 /* ######
981
982 QString selname = choicenames.at(index);
983 for (each row) {
984 Contact *c = contactForRow(row);
985 if ( text(row,2) == selname ) {
986 r.append(c->email);
987 }
988 }
989
990 */
991 return r;
992}
993
994void AbTable::setShowCategory( const QString &c )
995{
996 showCat = c;
997 updateVisible();
998}
999
1000QString AbTable::showCategory() const
1001{
1002 return showCat;
1003}
1004
1005
1006QStringList AbTable::categories()
1007{
1008 mCat.load( categoryFileName() );
1009 QStringList categoryList = mCat.labels( "Contacts" );
1010 return categoryList;
1011}
1012
1013void AbTable::updateVisible()
1014{
1015 int visible,
1016 totalRows,
1017 id,
1018 totalCats,
1019 it,
1020 row;
1021 bool hide;
1022 AbTableItem *ati;
1023 Contact *cnt;
1024 visible = 0;
1025
1026 setPaintingEnabled( FALSE );
1027
1028 totalRows = numRows();
1029 id = mCat.id( "Contacts", showCat );
1030 QArray<int> cats;
1031 for ( row = 0; row < totalRows; row++ ) {
1032 ati = static_cast<AbTableItem*>( item(row, 0) );
1033 cnt = &contactList[ati];
1034 cats = cnt->categories();
1035 hide = false;
1036 if ( !showCat.isEmpty() ) {
1037 if ( showCat == tr( "Unfiled" ) ) {
1038 if ( cats.count() > 0 )
1039 hide = true;
1040 } else {
1041 // do some comparing
1042 if ( !hide ) {
1043 hide = true;
1044 totalCats = int(cats.count());
1045 for ( it = 0; it < totalCats; it++ ) {
1046 if ( cats[it] == id ) {
1047 hide = false;
1048 break;
1049 }
1050 }
1051 }
1052 }
1053 }
1054 if ( hide ) {
1055 if ( currentRow() == row )
1056 setCurrentCell( -1, 0 );
1057 if ( rowHeight(row) > 0 )
1058 hideRow( row );
1059 } else {
1060 if ( rowHeight(row) == 0 ) {
1061 showRow( row );
1062 adjustRow( row );
1063 }
1064 visible++;
1065 }
1066 }
1067 if ( !visible )
1068 setCurrentCell( -1, 0 );
1069
1070 setPaintingEnabled( TRUE );
1071}
1072
1073
1074void AbTable::setPaintingEnabled( bool e )
1075{
1076 if ( e != enablePainting ) {
1077 if ( !enablePainting ) {
1078 enablePainting = true;
1079 rowHeightChanged( 0 );
1080 viewport()->update();
1081 } else {
1082 enablePainting = false;
1083 }
1084 }
1085}
1086
1087void AbTable::rowHeightChanged( int row )
1088{
1089 if ( enablePainting )
1090 QTable::rowHeightChanged( row );
1091}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qt Palmtop Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#ifndef ABTABLE_H
22#define ABTABLE_H
23
24#include <qpe/categories.h>
25#include <qpe/contact.h>
26
27#include <qmap.h>
28#include <qtable.h>
29#include <qstringlist.h>
30#include <qcombobox.h>
31
32class AbTableItem : public QTableItem
33{
34public:
35 AbTableItem( QTable *t, EditType et, const QString &s,
36 const QString &secondSortKey);
37 QString entryKey() const;
38 void setEntryKey( const QString & k );
39 virtual int alignment() const;
40 virtual QString key() const;
41 void setItem( const QString &txt, const QString &secondKey );
42
43private:
44 QString sortKey;
45};
46
47class AbPickItem : public QTableItem
48{
49public:
50 AbPickItem( QTable *t );
51
52 QWidget *createEditor() const;
53 void setContentFromEditor( QWidget *w );
54
55private:
56 QGuardedPtr<QComboBox> cb;
57};
58
59class AbTable : public QTable
60{
61 Q_OBJECT
62
63public:
64 AbTable( const QValueList<int> *ordered, QWidget *parent, const char *name=0 );
65 ~AbTable();
66 // NEW
67 void addEntry( const Contact &newContact );
68 Contact currentEntry();
69 void replaceCurrentEntry( const Contact &newContact );
70
71 void init();
72
73 void deleteCurrentEntry();
74 void clear();
75 void clearFindRow() { currFindRow = -2; }
76 void loadFields();
77 void refresh();
78 bool save( const QString &fn );
79 void load( const QString &fn );
80
81 // addresspicker mode
82 void setChoiceNames( const QStringList& list);
83 QStringList choiceNames() const;
84 void setChoiceSelection(int index, const QStringList& list);
85 QStringList choiceSelection(int index) const;
86 void setShowCategory( const QString &c );
87 QString showCategory() const;
88 QStringList categories();
89
90 void show();
91 void setPaintingEnabled( bool e );
92
93public slots:
94 void slotDoFind( const QString &str, bool caseSensitive, bool backwards,
95 int category );
96signals:
97 void empty( bool );
98 void details();
99 void signalNotFound();
100 void signalWrapAround();
101
102protected:
103 virtual void keyPressEvent( QKeyEvent *e );
104
105// int rowHeight( int ) const;
106// int rowPos( int row ) const;
107// virtual int rowAt( int pos ) const;
108
109
110protected slots:
111 void moveTo( char );
112 virtual void columnClicked( int col );
113 void itemClicked(int,int col);
114 void rowHeightChanged( int row );
115
116private:
117 void loadFile( const QString &strFile, bool journalFile );
118 void fitColumns();
119 void resort();
120 void updateJournal( const Contact &contact, Contact::journal_action action,
121 int row = -1 );
122 void insertIntoTable( const Contact &contact, int row );
123 void internalAddEntries( QList<Contact> &list );
124 QString findContactName( const Contact &entry );
125 QString findContactContact( const Contact &entry );
126 void journalFreeReplace( const Contact &cnt, int row );
127 void journalFreeRemove( int row );
128 void realignTable( int );
129 void updateVisible();
130 int lastSortCol;
131 bool asc;
132 QMap<AbTableItem*, Contact> contactList;
133 const QValueList<int> *intFields;
134 int currFindRow;
135 QString showCat;
136 QStringList choicenames;
137 bool enablePainting;
138 Categories mCat;
139};
140#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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qt Palmtop Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "abeditor.h"
22#include "ablabel.h"
23#include "abtable.h"
24#include "addresssettings.h"
25#include "addressbook.h"
26
27#include <qpe/qpeapplication.h>
28#include <qpe/config.h>
29#include <qpe/contact.h>
30#include <qpe/finddialog.h>
31#include <qpe/global.h>
32#include <qpe/resource.h>
33#include <qpe/ir.h>
34#include <qpe/qpemessagebox.h>
35#include <qpe/qcopenvelope_qws.h>
36
37#include <qaction.h>
38#include <qdialog.h>
39#include <qdir.h>
40#include <qfile.h>
41#include <qimage.h>
42#include <qlayout.h>
43#include <qpe/qpemenubar.h>
44#include <qmessagebox.h>
45#include <qpixmap.h>
46#include <qpopupmenu.h>
47#include <qpe/qpetoolbar.h>
48#include <qstringlist.h>
49#include <qtoolbutton.h>
50#include <qwhatsthis.h>
51
52#include <stdlib.h>
53#include <sys/stat.h>
54#include <sys/types.h>
55#include <fcntl.h>
56#include <unistd.h>
57
58#include <qdatetime.h>
59
60static QString addressbookOldXMLFilename()
61{
62 QString filename = QPEApplication::documentDir() + "addressbook.xml";
63 return filename;
64}
65
66static QString addressbookXMLFilename()
67{
68 QString filename = Global::applicationFileName("addressbook",
69 "addressbook.xml");
70 return filename;
71}
72
73static QString addressbookPersonalVCardName()
74{
75 QString filename = Global::applicationFileName("addressbook",
76 "businesscard.vcf");
77 return filename;
78}
79
80
81AddressbookWindow::AddressbookWindow( QWidget *parent, const char *name,
82 WFlags f )
83 : QMainWindow( parent, name, f ),
84 abEditor(0),
85 bAbEditFirstTime(TRUE),
86 syncing(FALSE)
87{
88 initFields();
89
90 setCaption( tr("Contacts") );
91 setIcon( Resource::loadPixmap( "AddressBook" ) );
92
93 setToolBarsMovable( FALSE );
94
95 // Create Toolbars
96
97 QPEToolBar *bar = new QPEToolBar( this );
98 bar->setHorizontalStretchable( TRUE );
99
100 QPEMenuBar *mbList = new QPEMenuBar( bar );
101 mbList->setMargin( 0 );
102
103 QPopupMenu *edit = new QPopupMenu( this );
104 mbList->insertItem( tr( "Contact" ), edit );
105
106 listTools = new QPEToolBar( this, "list operations" );
107
108
109 QAction *a = new QAction( tr( "New" ), Resource::loadPixmap( "new" ), QString::null,
110 0, this, 0 );
111 actionNew = a;
112 connect( a, SIGNAL( activated() ), this, SLOT( slotListNew() ) );
113 a->addTo( edit );
114 a->addTo( listTools );
115
116 a = new QAction( tr( "Edit" ), Resource::loadPixmap( "edit" ), QString::null,
117 0, this, 0 );
118 actionEdit = a;
119 connect( a, SIGNAL( activated() ), this, SLOT( slotViewEdit() ) );
120 a->addTo( edit );
121 a->addTo( listTools );
122
123 a = new QAction( tr( "Delete" ), Resource::loadPixmap( "trash" ), QString::null,
124 0, this, 0 );
125 actionTrash = a;
126 connect( a, SIGNAL( activated() ), this, SLOT( slotListDelete() ) );
127 a->addTo( edit );
128 a->addTo( listTools );
129
130 a = new QAction( tr( "Find" ), Resource::loadPixmap( "mag" ),
131 QString::null, 0, this, 0 );
132 actionFind = a;
133 connect( a, SIGNAL(activated()), this, SLOT(slotFind()) );
134 a->addTo( edit );
135 a->addTo( listTools );
136
137
138 a = new QAction( tr( "Write Mail To" ), Resource::loadPixmap( "qtmail/reply" ),
139 QString::null, 0, this, 0 );
140 a->setEnabled( FALSE );
141 actionMail = a;
142 connect( a, SIGNAL( activated() ), this, SLOT( writeMail() ) );
143 a->addTo( edit );
144 a->addTo( listTools );
145
146
147
148 if ( Ir::supported() ) {
149 a = new QAction( tr ("Beam Entry" ), Resource::loadPixmap( "beam" ), QString::null,
150 0, this, 0 );
151 actionBeam = a;
152 connect( a, SIGNAL( activated() ), this, SLOT( slotBeam() ) );
153 a->addTo( edit );
154 a->addTo( listTools );
155 }
156
157 edit->insertSeparator();
158
159 a = new QAction( tr("My Personal Details"), QString::null, 0, 0, 0, TRUE );
160 actionPersonal = a;
161 connect( a, SIGNAL( activated() ), this, SLOT( slotPersonalView() ) );
162 a->addTo( edit );
163
164
165 a = new QAction( tr( "Arrange Edit Fields"), QString::null, 0, 0 );
166 connect( a, SIGNAL( activated() ), this, SLOT( slotSettings() ) );
167 a->addTo( edit );
168
169 // Create Views
170
171 // This is safe to call without checking to see if it exists...
172 // not to mention it also does the necessary stuff for the
173 // journaling...
174 QString str = addressbookXMLFilename();
175 if ( str.isNull() ) {
176 QMessageBox::warning( this, tr("Out of Space"),
177 tr("There is not enough space to create\n"
178 "neccessary startup files.\n"
179 "\nFree up some space before\nentering data!")
180 );
181 }
182
183 abList = new AbTable( &orderedFields, this, "table" );
184 abList->setHScrollBarMode( QScrollView::AlwaysOff );
185 connect( abList, SIGNAL( empty( bool ) ),
186 this, SLOT( listIsEmpty( bool ) ) );
187 connect( abList, SIGNAL( details() ),
188 this, SLOT( slotListView() ) );
189 connect( abList, SIGNAL(currentChanged(int,int)),
190 this, SLOT(slotUpdateToolbar()) );
191
192 mView = 0;
193
194 abList->load( addressbookXMLFilename() );
195 if ( QFile::exists(addressbookOldXMLFilename()) ) {
196 abList->load( addressbookOldXMLFilename() );
197 QFile::remove(addressbookOldXMLFilename());
198 }
199
200 catMenu = new QPopupMenu( this );
201 catMenu->setCheckable( TRUE );
202 connect( catMenu, SIGNAL(activated(int)), this, SLOT(slotSetCategory(int)) );
203 populateCategories();
204
205 mbList->insertItem( tr("View"), catMenu );
206 setCentralWidget( abList );
207
208 // qDebug("adressbook contrsuction: t=%d", t.elapsed() );
209}
210
211void AddressbookWindow::setDocument( const QString &filename )
212{
213 if ( filename.find(".vcf") != int(filename.length()) - 4 ) return;
214
215 QValueList<Contact> cl = Contact::readVCard( filename );
216 for( QValueList<Contact>::Iterator it = cl.begin(); it != cl.end(); ++it ) {
217 // QString msg = tr("You received a vCard for\n%1.\nDo You want to add it to your\naddressbook?")
218 // .arg( (*it).fullName() );
219 // if ( QMessageBox::information( this, tr("received contact"), msg, QMessageBox::Ok, QMessageBox::Cancel ) ==
220 // QMessageBox::Ok ) {
221 abList->addEntry( *it );
222 // }
223 }
224
225}
226
227void AddressbookWindow::resizeEvent( QResizeEvent *e )
228{
229 QMainWindow::resizeEvent( e );
230
231 if ( centralWidget() == abList )
232 showList();
233 else if ( centralWidget() == mView )
234 showView();
235}
236
237AddressbookWindow::~AddressbookWindow()
238{
239}
240
241void AddressbookWindow::slotUpdateToolbar()
242{
243 Contact ce = abList->currentEntry();
244 actionMail->setEnabled( !ce.defaultEmail().isEmpty() );
245}
246
247void AddressbookWindow::showList()
248{
249 if ( mView ) mView->hide();
250 setCentralWidget( abList );
251 abList->show();
252 // update our focues... (or use a stack widget!);
253 abList->setFocus();
254}
255
256void AddressbookWindow::showView()
257{
258 if ( abList->numRows() > 0 ) {
259 abList->hide();
260 setCentralWidget( abView() );
261 mView->show();
262 mView->setFocus();
263 }
264}
265
266void AddressbookWindow::slotListNew()
267{
268 Contact cnt;
269 if( !syncing ) {
270 if ( abEditor )
271 abEditor->setEntry( cnt );
272 abView()->init( cnt );
273 editEntry( NewEntry );
274 } else {
275 QMessageBox::warning(this, tr("Contacts"),
276 tr("Can not edit data, currently syncing"));
277 }
278}
279
280void AddressbookWindow::slotListView()
281{
282 abView()->init( abList->currentEntry() );
283 mView->sync();
284 showView();
285}
286
287void AddressbookWindow::slotListDelete()
288{
289 if(!syncing) {
290 Contact tmpEntry = abList->currentEntry();
291
292 // get a name, do the best we can...
293 QString strName = tmpEntry.fullName();
294 if ( strName.isEmpty() ) {
295 strName = tmpEntry.company();
296 if ( strName.isEmpty() )
297 strName = "No Name";
298 }
299
300
301 if ( QPEMessageBox::confirmDelete( this, tr( "Contacts" ),
302 strName ) ) {
303 abList->deleteCurrentEntry();
304 showList();
305 }
306 } else {
307 QMessageBox::warning( this, tr("Contacts"),
308 tr("Can not edit data, currently syncing") );
309 }
310}
311
312void AddressbookWindow::slotViewBack()
313{
314 showList();
315}
316
317void AddressbookWindow::slotViewEdit()
318{
319 if(!syncing) {
320 if (actionPersonal->isOn()) {
321 editPersonal();
322 } else {
323 if ( !bAbEditFirstTime )
324 abEditor->setEntry( abList->currentEntry() );
325 editEntry( EditEntry );
326 }
327 } else {
328 QMessageBox::warning( this, tr("Contacts"),
329 tr("Can not edit data, currently syncing") );
330 }
331}
332
333
334
335void AddressbookWindow::writeMail()
336{
337 Contact c = abList->currentEntry();
338 QString name = c.fileAs();
339 QString email = c.defaultEmail();
340 QCopEnvelope e("QPE/Application/qtmail", "writeMail(QString,QString)");
341 e << name << email;
342}
343
344
345
346
347static const char * beamfile = "/tmp/obex/contact.vcf";
348
349void AddressbookWindow::slotBeam()
350{
351 QString filename;
352 Contact c;
353 if ( actionPersonal->isOn() ) {
354 filename = addressbookPersonalVCardName();
355 if (!QFile::exists(filename))
356 return; // can't beam a non-existent file
357 c = Contact::readVCard( filename )[0];
358 } else {
359 unlink( beamfile ); // delete if exists
360 c = abList->currentEntry();
361 mkdir("/tmp/obex/", 0755);
362 Contact::writeVCard( beamfile, c );
363 filename = beamfile;
364 }
365 Ir *ir = new Ir( this );
366 connect( ir, SIGNAL( done( Ir * ) ), this, SLOT( beamDone( Ir * ) ) );
367 QString description = c.fullName();
368 ir->send( filename, description, "text/x-vCard" );
369}
370
371void AddressbookWindow::beamDone( Ir *ir )
372{
373 delete ir;
374 unlink( beamfile );
375}
376
377
378static void parseName( const QString& name, QString *first, QString *middle,
379 QString * last )
380{
381
382 int comma = name.find ( "," );
383 QString rest;
384 if ( comma > 0 ) {
385 *last = name.left( comma );
386 comma++;
387 while ( comma < int(name.length()) && name[comma] == ' ' )
388 comma++;
389 rest = name.mid( comma );
390 } else {
391 int space = name.findRev( ' ' );
392 *last = name.mid( space+1 );
393 rest = name.left( space );
394 }
395 int space = rest.find( ' ' );
396 if ( space <= 0 ) {
397 *first = rest;
398 } else {
399 *first = rest.left( space );
400 *middle = rest.mid( space+1 );
401 }
402
403}
404
405
406void AddressbookWindow::appMessage(const QCString &msg, const QByteArray &data)
407{
408 if (msg == "editPersonal()") {
409 editPersonal();
410 } else if (msg == "editPersonalAndClose()") {
411 editPersonal();
412 close();
413 } else if ( msg == "addContact(QString,QString)" ) {
414 QDataStream stream(data,IO_ReadOnly);
415 QString name, email;
416 stream >> name >> email;
417
418 Contact cnt;
419 QString fn, mn, ln;
420 parseName( name, &fn, &mn, &ln );
421 //qDebug( " %s - %s - %s", fn.latin1(), mn.latin1(), ln.latin1() );
422 cnt.setFirstName( fn );
423 cnt.setMiddleName( mn );
424 cnt.setLastName( ln );
425 cnt.setEmails( email );
426 cnt.setDefaultEmail( email );
427 cnt.setFileAs();
428
429 if ( bAbEditFirstTime ) {
430 abEditor = new AbEditor( cnt, &orderedFields, &slOrderedFields,
431 this, "editor" );
432 bAbEditFirstTime = FALSE;
433 } else {
434 abEditor->setEntry( cnt );
435 }
436 abView()->init( cnt );
437 editEntry( NewEntry );
438
439
440
441 }
442#if 0
443 else if (msg == "pickAddresses(QCString,QCString,QStringList,...)" ) {
444 QDataStream stream(data,IO_ReadOnly);
445 QCString ch,m;
446 QStringList types;
447 stream >> ch >> m >> types;
448 AddressPicker picker(abList,this,0,TRUE);
449 picker.showMaximized();
450 picker.setChoiceNames(types);
451 int i=0;
452 for (QStringList::ConstIterator it = types.begin(); it!=types.end(); ++it) {
453 QStringList sel;
454 stream >> sel;
455 picker.setSelection(i++,sel);
456 }
457 picker.showMaximized();
458 picker.exec();
459
460 // ###### note: contacts may have been added - save here!
461
462 setCentralWidget(abList);
463 QCopEnvelope e(ch,m);
464 i=0;
465 for (QStringList::ConstIterator it = types.begin(); it!=types.end(); ++it) {
466 QStringList sel = picker.selection(i++);
467 e << sel;
468 }
469 }
470#endif
471
472}
473
474void AddressbookWindow::editPersonal()
475{
476 QString filename = addressbookPersonalVCardName();
477 Contact me;
478 if (QFile::exists(filename))
479 me = Contact::readVCard( filename )[0];
480 if (bAbEditFirstTime) {
481 abEditor = new AbEditor( me, &orderedFields, &slOrderedFields,
482 this, "editor" );
483 // don't create a new editor every time
484 bAbEditFirstTime = FALSE;
485 } else
486 abEditor->setEntry( me );
487
488 abEditor->setCaption(tr("Edit My Personal Details"));
489 abEditor->showMaximized();
490
491 // fix the foxus...
492 abEditor->setNameFocus();
493 if ( abEditor->exec() ) {
494 setFocus();
495 Contact new_personal = abEditor->entry();
496 QString fname = addressbookPersonalVCardName();
497 Contact::writeVCard( fname, new_personal );
498 abView()->init(new_personal);
499 abView()->sync();
500 }
501 abEditor->setCaption( tr("Edit Address") );
502}
503
504void AddressbookWindow::slotPersonalView()
505{
506 if (!actionPersonal->isOn()) {
507 // we just turned it off
508 setCaption( tr("Contacts") );
509 actionNew->setEnabled(TRUE);
510 actionTrash->setEnabled(TRUE);
511 actionFind->setEnabled(TRUE);
512 slotUpdateToolbar(); // maybe some of the above could be moved there
513 showList();
514 return;
515 }
516
517 // XXX need to disable some QActions.
518 actionNew->setEnabled(FALSE);
519 actionTrash->setEnabled(FALSE);
520 actionFind->setEnabled(FALSE);
521 actionMail->setEnabled(FALSE);
522
523 setCaption( tr("Contacts - My Personal Details") );
524 QString filename = addressbookPersonalVCardName();
525 Contact me;
526 if (QFile::exists(filename))
527 me = Contact::readVCard( filename )[0];
528
529 abView()->init( me );
530 abView()->sync();
531 abList->hide();
532 setCentralWidget( abView() );
533 mView->show();
534 mView->setFocus();
535}
536
537void AddressbookWindow::editEntry( EntryMode entryMode )
538{
539 Contact entry;
540 if ( bAbEditFirstTime ) {
541 abEditor = new AbEditor( entry, &orderedFields, &slOrderedFields,
542 this, "editor" );
543 bAbEditFirstTime = FALSE;
544 if ( entryMode == EditEntry )
545 abEditor->setEntry( abList->currentEntry() );
546 }
547 // other things may chane the caption.
548 abEditor->setCaption( tr("Edit Address") );
549
550#if defined(Q_WS_QWS) || defined(_WS_QWS_)
551 abEditor->showMaximized();
552#endif
553 // fix the foxus...
554 abEditor->setNameFocus();
555 if ( abEditor->exec() ) {
556 setFocus();
557 if ( entryMode == NewEntry ) {
558 Contact insertEntry = abEditor->entry();
559 insertEntry.assignUid();
560 abList->addEntry( insertEntry );
561 } else {
562 Contact replaceEntry = abEditor->entry();
563 if ( !replaceEntry.isValidUid() )
564 replaceEntry.assignUid();
565 abList->replaceCurrentEntry( replaceEntry );
566 }
567 }
568 populateCategories();
569 showList();
570}
571
572void AddressbookWindow::listIsEmpty( bool empty )
573{
574 if ( !empty ) {
575 deleteButton->setEnabled( TRUE );
576 }
577}
578
579void AddressbookWindow::reload()
580{
581 syncing = FALSE;
582 abList->clear();
583 abList->load( addressbookXMLFilename() );
584}
585
586void AddressbookWindow::flush()
587{
588 syncing = TRUE;
589 abList->save( addressbookXMLFilename() );
590}
591
592
593void AddressbookWindow::closeEvent( QCloseEvent *e )
594{
595 if ( centralWidget() == mView ) {
596 if (actionPersonal->isOn()) {
597 // pretend we clicked it off
598 actionPersonal->setOn(FALSE);
599 slotPersonalView();
600 } else {
601 showList();
602 }
603 e->ignore();
604 return;
605 }
606
607 if(syncing) {
608 /* shouldn't we save, I hear you say? well its already been set
609 so that an edit can not occur during a sync, and we flushed
610 at the start of the sync, so there is no need to save
611 Saving however itself would cause problems. */
612 e->accept();
613 return;
614 }
615//################## shouldn't always save
616 if ( save() )
617 e->accept();
618 else
619 e->ignore();
620}
621
622/*
623 Returns TRUE if it is OK to exit
624 */
625
626bool AddressbookWindow::save()
627{
628 QString str = addressbookXMLFilename();
629 if ( str.isNull() ) {
630 if ( QMessageBox::critical( 0, tr("Out of space"),
631 tr("Unable to save information.\n"
632 "Free up some space\n"
633 "and try again.\n"
634 "\nQuit anyway?"),
635 QMessageBox::Yes|QMessageBox::Escape,
636 QMessageBox::No|QMessageBox::Default )
637 != QMessageBox::No )
638 return TRUE;
639 else
640 return FALSE;
641 } else {
642 if ( !abList->save( str ) ) {
643 if ( QMessageBox::critical( 0, tr( "Out of space" ),
644 tr("Unable to save information.\n"
645 "Free up some space\n"
646 "and try again.\n"
647 "\nQuit anyway?"),
648 QMessageBox::Yes|QMessageBox::Escape,
649 QMessageBox::No|QMessageBox::Default )
650 != QMessageBox::No )
651 return TRUE;
652 else
653 return FALSE;
654 }
655 }
656 return TRUE;
657}
658
659void AddressbookWindow::slotSettings()
660{
661 AddressSettings frmSettings( this );
662#if defined(Q_WS_QWS) || defined(_WS_QWS_)
663 frmSettings.showMaximized();
664#endif
665
666 if ( frmSettings.exec() ) {
667 allFields.clear();
668 orderedFields.clear();
669 slOrderedFields.clear();
670 initFields();
671 if ( abEditor )
672 abEditor->loadFields();
673 abList->refresh();
674 }
675}
676
677
678void AddressbookWindow::initFields()
679{
680 // we really don't need the things from the configuration, anymore
681 // only thing that is important are the important categories. So,
682 // Call the contact functions that correspond to these old functions...
683
684 QStringList xmlFields = Contact::fields();
685 QStringList visibleFields = Contact::trfields();
686 xmlFields.remove( "Title" );
687 visibleFields.remove( tr("Name Title") );
688 visibleFields.remove( tr("Notes") );
689
690 int i,
691 version;
692 Config cfg( "AddressBook" );
693 QString zn;
694
695 // ### Write a function to keep this from happening again...
696 QStringList::ConstIterator it;
697 for ( i = 0, it = xmlFields.begin(); it != xmlFields.end(); ++it, i++ ) {
698 allFields.append( i + 3 );
699 }
700
701 cfg.setGroup( "Version" );
702 version = cfg.readNumEntry( "version" );
703 i = 0;
704 if ( version >= ADDRESSVERSION ) {
705
706 cfg.setGroup( "ImportantCategory" );
707
708 zn = cfg.readEntry( "Category" + QString::number(i), QString::null );
709 while ( !zn.isNull() ) {
710 if ( zn.contains( tr("Work") ) || zn.contains( tr("Mb") ) ) {
711 slOrderedFields.clear();
712 break;
713 }
714 slOrderedFields.append( zn );
715 zn = cfg.readEntry( "Category" + QString::number(++i), QString::null );
716 }
717 } else {
718 QString str;
719 str = getenv("HOME");
720 str += "/Settings/AddressBook.conf";
721 QFile::remove( str );
722 }
723 if ( slOrderedFields.count() > 0 ) {
724 for( QStringList::ConstIterator it = slOrderedFields.begin();
725 it != slOrderedFields.end(); ++it ) {
726 QValueList<int>::ConstIterator itVl;
727 QStringList::ConstIterator itVis;
728 itVl = allFields.begin();
729 for ( itVis = visibleFields.begin();
730 itVis != visibleFields.end() && itVl != allFields.end();
731 ++itVis, ++itVl ) {
732 if ( *it == *itVis && itVl != allFields.end() ) {
733 orderedFields.append( *itVl );
734 }
735 }
736 }
737 } else {
738 QValueList<int>::ConstIterator it;
739 for ( it = allFields.begin(); it != allFields.end(); ++it )
740 orderedFields.append( *it );
741
742 slOrderedFields = visibleFields;
743 orderedFields.remove( Qtopia::AddressUid );
744 orderedFields.remove( Qtopia::Title );
745 orderedFields.remove( Qtopia::Groups );
746 orderedFields.remove( Qtopia::AddressCategory );
747 orderedFields.remove( Qtopia::FirstName );
748 orderedFields.remove( Qtopia::LastName );
749 orderedFields.remove( Qtopia::DefaultEmail );
750 orderedFields.remove( Qtopia::FileAs );
751 orderedFields.remove( Qtopia::Notes );
752 orderedFields.remove( Qtopia::Gender );
753 slOrderedFields.remove( tr("Name Title") );
754 slOrderedFields.remove( tr("First Name") );
755 slOrderedFields.remove( tr("Last Name") );
756 slOrderedFields.remove( tr("File As") );
757 slOrderedFields.remove( tr("Default Email") );
758 slOrderedFields.remove( tr("Notes") );
759 slOrderedFields.remove( tr("Gender") );
760
761 }
762}
763
764
765AbLabel *AddressbookWindow::abView()
766{
767 if ( !mView ) {
768 mView = new AbLabel( this, "viewer" );
769 mView->init( Contact() );
770 connect( mView, SIGNAL( okPressed() ), this, SLOT( slotListView() ) );
771 }
772 return mView;
773}
774
775void AddressbookWindow::slotFind()
776{
777 if ( centralWidget() == abView() )
778 showList();
779 FindDialog frmFind( "Contacts", this );
780 QObject::connect( &frmFind, SIGNAL(signalFindClicked(const QString &, bool, bool, int)), abList, SLOT(slotDoFind( const QString&,bool,bool,int)));
781 QObject::connect( abList, SIGNAL(signalNotFound()), &frmFind, SLOT(slotNotFound()) );
782 QObject::connect( abList, SIGNAL(signalWrapAround()), &frmFind, SLOT(slotWrapAround()) );
783 frmFind.exec();
784 if ( abList->numSelections() )
785 abList->clearSelection();
786 abList->clearFindRow();
787}
788
789void AddressbookWindow::slotSetCategory( int c )
790{
791 if ( c <= 0 )
792 return;
793 for ( unsigned int i = 1; i < catMenu->count(); i++ )
794 catMenu->setItemChecked( i, c == (int)i );
795 if ( c == 1 ) {
796 abList->setShowCategory( QString::null );
797 setCaption( tr("Contacts") + " - " + tr ( "All" ) );
798 } else if ( c == (int)catMenu->count() ) {
799 abList->setShowCategory( tr( "Unfiled" ) );
800 setCaption( tr("Contacts") + " - " + tr( "Unfiled" ) );
801 } else {
802 QString cat = abList->categories()[c - 2];
803 abList->setShowCategory( cat );
804 setCaption( tr("Contacts") + " - " + cat );
805 }
806}
807
808void AddressbookWindow::populateCategories()
809{
810 catMenu->clear();
811
812 int id,
813 rememberId;
814 id = 1;
815 catMenu->insertItem( tr( "All" ), id++ );
816 QStringList categories = abList->categories();
817 categories.append( tr( "Unfiled" ) );
818 for ( QStringList::Iterator it = categories.begin();
819 it != categories.end(); ++it ) {
820 catMenu->insertItem( *it, id );
821 if ( *it == abList->showCategory() )
822 rememberId = id;
823 ++id;
824 }
825 if ( abList->showCategory().isEmpty() )
826 slotSetCategory( 1 );
827 else
828 slotSetCategory( rememberId );
829}
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 @@
1<!DOCTYPE CW><CW>
2<customwidgets>
3 <customwidget>
4 <class>AbLineEdit</class>
5 <header location="local">ablineedit.h</header>
6 <sizehint>
7 <width>-1</width>
8 <height>-1</height>
9 </sizehint>
10 <pixmap>
11 <data format="XPM.GZ" length="646">789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758</data>
12 </pixmap>
13 </customwidget>
14 <customwidget>
15 <class>AbMultiLineEdit</class>
16 <header location="local">abmultilineedit.h</header>
17 <sizehint>
18 <width>-1</width>
19 <height>-1</height>
20 </sizehint>
21 <pixmap>
22 <data format="XPM.GZ" length="646">789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758</data>
23 </pixmap>
24 </customwidget>
25</customwidgets>
26</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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qt Palmtop Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef Addressbook_H
21#define Addressbook_H
22
23#include <qmainwindow.h>
24
25class AbEditor;
26class AbLabel;
27class AbTable;
28class QPEToolBar;
29class QPopupMenu;
30class QToolButton;
31class QDialog;
32class Ir;
33class QAction;
34
35class AddressbookWindow: public QMainWindow
36{
37 Q_OBJECT
38public:
39 AddressbookWindow( QWidget *parent = 0, const char *name = 0, WFlags f = 0 );
40 ~AddressbookWindow();
41
42protected:
43 void resizeEvent( QResizeEvent * e );
44 void showList();
45 void showView();
46 enum EntryMode { NewEntry=0, EditEntry };
47 void editPersonal();
48 void editEntry( EntryMode );
49 void closeEvent( QCloseEvent *e );
50 bool save();
51
52public slots:
53 void flush();
54 void reload();
55 void appMessage(const QCString &, const QByteArray &);
56 void setDocument( const QString & );
57
58private slots:
59 void slotListNew();
60 void slotListView();
61 void slotListDelete();
62 void slotViewBack();
63 void slotViewEdit();
64 void slotPersonalView();
65 void listIsEmpty( bool );
66 void slotSettings();
67 void writeMail();
68 void slotBeam();
69 void beamDone( Ir * );
70 void slotFind();
71 void slotSetCategory( int );
72 void slotUpdateToolbar();
73
74private:
75 void initFields();// inititialize our fields...
76 AbLabel *abView();
77 void populateCategories();
78
79 QPopupMenu *catMenu;
80 QPEToolBar *listTools;
81 QToolButton *deleteButton;
82 QValueList<int> allFields,
83 orderedFields;
84 QStringList slOrderedFields;
85 enum Panes { paneList=0, paneView, paneEdit };
86 AbEditor *abEditor;
87 AbLabel *mView;
88 AbTable *abList;
89
90 QAction *actionNew, *actionEdit, *actionTrash, *actionFind, *actionBeam,
91 *actionPersonal, *actionMail;
92
93 bool bAbEditFirstTime;
94 int viewMargin;
95
96 bool syncing;
97};
98
99#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 @@
1 TEMPLATE= app
2 CONFIG = qt warn_on release
3 DESTDIR = $(QPEDIR)/bin
4 HEADERS= addressbook.h \
5 abeditor.h \
6 ablabel.h \
7 abtable.h \
8 addresssettings.h
9 SOURCES= main.cpp \
10 addressbook.cpp \
11 abeditor.cpp \
12 ablabel.cpp \
13 abtable.cpp \
14 addresssettings.cpp
15 INTERFACES= addresssettingsbase.ui
16
17 TARGET = addressbook
18INCLUDEPATH += $(QPEDIR)/include
19 DEPENDPATH+= $(QPEDIR)/include
20LIBS += -lqpe
21
22TRANSLATIONS = ../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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qt Palmtop Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "addresspicker.h"
22#include "abtable.h"
23
24#include <qlayout.h>
25
26/*!
27 \a tab is reparented for use in the picker. Take it back out if you want
28 to regain ownership.
29*/
30AddressPicker::AddressPicker(AbTable* tab, QWidget* parent, const char* name, bool modal) :
31 QDialog(parent,name,modal)
32{
33 QVBoxLayout* vb = new QVBoxLayout(this);
34 tab->reparent(this,QPoint(0,0));
35 table = tab;
36 vb->addWidget(table);
37}
38
39void AddressPicker::setChoiceNames(const QStringList& list)
40{
41 table->setChoiceNames(list);
42}
43
44void AddressPicker::setSelection(int index, const QStringList& list)
45{
46 table->setChoiceSelection(index,list);
47}
48
49QStringList AddressPicker::selection(int index) const
50{
51 return table->choiceSelection(index);
52}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qt Palmtop Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef AddressPicker_H
21#define AddressPicker_H
22
23#include <qdialog.h>
24
25class AbTable;
26
27class AddressPicker : public QDialog {
28public:
29 AddressPicker(AbTable* table, QWidget* parent, const char* name=0, bool modal=FALSE);
30
31 void setChoiceNames(const QStringList&);
32 void setSelection(int index, const QStringList&);
33 QStringList selection(int index) const;
34
35private:
36 AbTable* table;
37};
38
39#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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qt Palmtop Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21
22#include "addresssettings.h"
23
24#include <qpe/config.h>
25#include <qpe/contact.h>
26
27#include <qfile.h>
28#include <qlistbox.h>
29
30#include <stdlib.h>
31
32AddressSettings::AddressSettings( QWidget *parent, const char *name )
33 : AddressSettingsBase( parent, name, TRUE )
34{
35 init();
36}
37
38AddressSettings::~AddressSettings()
39{
40}
41
42void AddressSettings::init()
43{
44 QStringList slFields = Contact::trfields();
45 // Make this match what is in initFields
46 slFields.remove( tr("Name Title") );
47 slFields.remove( tr("First Name") );
48 slFields.remove( tr("Last Name") );
49 slFields.remove( tr("File As") );
50 slFields.remove( tr("Default Email") );
51 slFields.remove( tr("Notes") );
52 slFields.remove( tr("Gender") );
53
54
55 for( QStringList::Iterator it = slFields.begin();
56 it != slFields.end(); ++it ) {
57 fieldListBox->insertItem( *it );
58 }
59
60 Config cfg( "AddressBook" );
61
62 cfg.setGroup( "Version" );
63 int version;
64 version = cfg.readNumEntry( "version" );
65 if ( version >= ADDRESSVERSION ) {
66 int i = 0;
67 int p = 0;
68 cfg.setGroup( "ImportantCategory" );
69 QString zn = cfg.readEntry( "Category" + QString::number(i),
70 QString::null );
71 while ( !zn.isNull() ) {
72 for ( int m = i; m < (int)fieldListBox->count(); m++ ) {
73 if ( fieldListBox->text( m ) == zn ) {
74 if ( m != p ) {
75 fieldListBox->removeItem( m );
76 fieldListBox->insertItem( zn, p );
77 }
78 p++;
79 break;
80 }
81 }
82 zn = cfg.readEntry( "Category" + QString::number(++i),
83 QString::null );
84 }
85
86 fieldListBox->setCurrentItem( 0 );
87 } else {
88 QString str;
89 str = getenv("HOME");
90
91 str += "/Settings/AddressBook.conf";
92 QFile::remove( str );
93 }
94}
95
96void AddressSettings::itemUp()
97{
98 int i = fieldListBox->currentItem();
99 if ( i > 0 ) {
100 QString item = fieldListBox->currentText();
101 fieldListBox->removeItem( i );
102 fieldListBox->insertItem( item, i-1 );
103 fieldListBox->setCurrentItem( i-1 );
104 }
105}
106
107void AddressSettings::itemDown()
108{
109 int i = fieldListBox->currentItem();
110 if ( i < (int)fieldListBox->count() - 1 ) {
111 QString item = fieldListBox->currentText();
112 fieldListBox->removeItem( i );
113 fieldListBox->insertItem( item, i+1 );
114 fieldListBox->setCurrentItem( i+1 );
115 }
116}
117
118void AddressSettings::accept()
119{
120 save();
121 QDialog::accept();
122}
123
124
125void AddressSettings::save()
126{
127 Config cfg( "AddressBook" );
128 cfg.setGroup( "Version" );
129 // *** To change the version change it here...
130 cfg.writeEntry( "version", QString::number(ADDRESSVERSION) );
131 cfg.setGroup( "ImportantCategory" );
132
133 for ( int i = 0; i < (int)fieldListBox->count(); i++ ) {
134 cfg.writeEntry( "Category"+QString::number(i), fieldListBox->text(i) );
135 }
136}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qt Palmtop Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#ifndef _ADDRESSSETTINGS_H_
22#define _ADDRESSSETTINGS_H_
23
24#include <qlist.h>
25#include <qstringlist.h>
26#include "addresssettingsbase.h"
27
28const int ADDRESSVERSION = 3;
29
30class AddressSettings : public AddressSettingsBase
31{
32 Q_OBJECT
33public:
34 AddressSettings( QWidget *parent = 0, const char *name = 0 );
35 ~AddressSettings();
36
37protected:
38 void accept();
39 virtual void itemUp();
40 virtual void itemDown();
41
42private:
43 void init();
44 void save();
45};
46
47#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 @@
1<!DOCTYPE UI><UI>
2<class>AddressSettingsBase</class>
3<comment>/**********************************************************************
4** Copyright (C) 2001 Trolltech AS. All rights reserved.
5**
6** This file is part of Qt Palmtop Environment.
7**
8** This file may be distributed and/or modified under the terms of the
9** GNU General Public License version 2 as published by the Free Software
10** Foundation and appearing in the file LICENSE.GPL included in the
11** packaging of this file.
12**
13** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
14** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
15**
16** See http://www.trolltech.com/gpl/ for GPL licensing information.
17**
18** Contact info@trolltech.com if any conditions of this licensing are
19** not clear to you.
20**
21** $Id$
22**
23**********************************************************************/</comment>
24<widget>
25 <class>QDialog</class>
26 <property stdset="1">
27 <name>name</name>
28 <cstring>AddressSettingsBase</cstring>
29 </property>
30 <property stdset="1">
31 <name>geometry</name>
32 <rect>
33 <x>0</x>
34 <y>0</y>
35 <width>244</width>
36 <height>207</height>
37 </rect>
38 </property>
39 <property stdset="1">
40 <name>caption</name>
41 <string>Arrange Edit Fields</string>
42 </property>
43 <property>
44 <name>layoutMargin</name>
45 </property>
46 <property>
47 <name>layoutSpacing</name>
48 </property>
49 <grid>
50 <property stdset="1">
51 <name>margin</name>
52 <number>6</number>
53 </property>
54 <property stdset="1">
55 <name>spacing</name>
56 <number>6</number>
57 </property>
58 <widget row="1" column="0" rowspan="3" colspan="1" >
59 <class>QListBox</class>
60 <property stdset="1">
61 <name>name</name>
62 <cstring>fieldListBox</cstring>
63 </property>
64 </widget>
65 <widget row="0" column="0" rowspan="1" colspan="2" >
66 <class>QLabel</class>
67 <property stdset="1">
68 <name>name</name>
69 <cstring>lblExplain</cstring>
70 </property>
71 <property stdset="1">
72 <name>sizePolicy</name>
73 <sizepolicy>
74 <hsizetype>1</hsizetype>
75 <vsizetype>1</vsizetype>
76 </sizepolicy>
77 </property>
78 <property stdset="1">
79 <name>frameShape</name>
80 <enum>MShape</enum>
81 </property>
82 <property stdset="1">
83 <name>frameShadow</name>
84 <enum>MShadow</enum>
85 </property>
86 <property stdset="1">
87 <name>text</name>
88 <string>Select the field order:</string>
89 </property>
90 <property stdset="1">
91 <name>alignment</name>
92 <set>AlignTop|AlignLeft</set>
93 </property>
94 <property>
95 <name>hAlign</name>
96 </property>
97 <property>
98 <name>vAlign</name>
99 </property>
100 </widget>
101 <widget row="1" column="1" >
102 <class>QPushButton</class>
103 <property stdset="1">
104 <name>name</name>
105 <cstring>upButton</cstring>
106 </property>
107 <property stdset="1">
108 <name>text</name>
109 <string>Up</string>
110 </property>
111 <property stdset="1">
112 <name>autoRepeat</name>
113 <bool>true</bool>
114 </property>
115 </widget>
116 <widget row="2" column="1" >
117 <class>QPushButton</class>
118 <property stdset="1">
119 <name>name</name>
120 <cstring>downButton</cstring>
121 </property>
122 <property stdset="1">
123 <name>text</name>
124 <string>Down</string>
125 </property>
126 <property stdset="1">
127 <name>autoRepeat</name>
128 <bool>true</bool>
129 </property>
130 </widget>
131 <spacer row="3" column="1" >
132 <property>
133 <name>name</name>
134 <cstring>Spacer2</cstring>
135 </property>
136 <property stdset="1">
137 <name>orientation</name>
138 <enum>Vertical</enum>
139 </property>
140 <property stdset="1">
141 <name>sizeType</name>
142 <enum>Expanding</enum>
143 </property>
144 <property>
145 <name>sizeHint</name>
146 <size>
147 <width>20</width>
148 <height>20</height>
149 </size>
150 </property>
151 </spacer>
152 </grid>
153</widget>
154<connections>
155 <connection>
156 <sender>upButton</sender>
157 <signal>clicked()</signal>
158 <receiver>AddressSettingsBase</receiver>
159 <slot>itemUp()</slot>
160 </connection>
161 <connection>
162 <sender>downButton</sender>
163 <signal>clicked()</signal>
164 <receiver>AddressSettingsBase</receiver>
165 <slot>itemDown()</slot>
166 </connection>
167 <slot access="protected">itemUp()</slot>
168 <slot access="protected">itemDown()</slot>
169</connections>
170</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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qt Palmtop Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "addressbook.h"
22
23#include <qpe/qpeapplication.h>
24#include <qpe/qcopenvelope_qws.h>
25#include <qstring.h>
26
27int main( int argc, char ** argv )
28{
29 QPEApplication a( argc, argv );
30
31 AddressbookWindow mw;
32 QObject::connect( &a, SIGNAL( flush() ), &mw, SLOT( flush() ) );
33 QObject::connect( &a, SIGNAL( reload() ), &mw, SLOT( reload() ) );
34 QObject::connect( &a, SIGNAL( appMessage(const QCString &, const QByteArray &) ),
35 &mw, SLOT( appMessage(const QCString &, const QByteArray &) ) );
36
37 mw.setCaption( AddressbookWindow::tr("Contacts") );
38 a.showMainDocumentWidget(&mw);
39
40 return a.exec();
41}
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 @@
1Files: bin/addressbook apps/Applications/addressbook.desktop
2Priority: optional
3Section: qpe/applications
4Maintainer: Warwick Allison <warwick@trolltech.com>
5Architecture: arm
6Version: $QPE_VERSION-3
7Depends: qpe-base ($QPE_VERSION)
8Description: Contacts
9 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 @@
1moc_*
2Makefile
3dateentry.h
4datebookdayheader.h
5dateentry.cpp
6datebookdayheader.cpp
7datebookweekheader.cpp
8datebookweekheader.h
9datebooksettingsbase.h
10datebooksettingsbase.cpp
11repeatentrybase.cpp
12repeatentrybase.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 @@
1#############################################################################
2
3####### Compiler, tools and options
4
5 CXX =$(SYSCONF_CXX) $(QT_CXX_MT)
6 CXXFLAGS=$(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
7 CC =$(SYSCONF_CC) $(QT_C_MT)
8 CFLAGS =$(SYSCONF_CFLAGS)
9 INCPATH =-I$(QPEDIR)/include
10 LFLAGS =$(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
11 LIBS =$(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
12 MOC =$(SYSCONF_MOC)
13 UIC =$(SYSCONF_UIC)
14
15####### Target
16
17DESTDIR = $(QPEDIR)/bin/
18VER_MAJ = 1
19VER_MIN = 0
20VER_PATCH = 0
21 TARGET= datebook
22TARGET1 = lib$(TARGET).so.$(VER_MAJ)
23
24####### Files
25
26 HEADERS =datebookday.h \
27 datebook.h \
28 dateentryimpl.h \
29 datebookdayheaderimpl.h \
30 datebooksettings.h \
31 datebookweek.h \
32 datebookweekheaderimpl.h \
33 repeatentry.h
34 SOURCES =main.cpp \
35 datebookday.cpp \
36 datebook.cpp \
37 dateentryimpl.cpp \
38 datebookdayheaderimpl.cpp \
39 datebooksettings.cpp \
40 datebookweek.cpp \
41 datebookweekheaderimpl.cpp \
42 repeatentry.cpp
43 OBJECTS =main.o \
44 datebookday.o \
45 datebook.o \
46 dateentryimpl.o \
47 datebookdayheaderimpl.o \
48 datebooksettings.o \
49 datebookweek.o \
50 datebookweekheaderimpl.o \
51 repeatentry.o \
52 dateentry.o \
53 datebookdayheader.o \
54 datebooksettingsbase.o \
55 datebookweekheader.o \
56 repeatentrybase.o
57INTERFACES = dateentry.ui \
58 datebookdayheader.ui \
59 datebooksettingsbase.ui \
60 datebookweekheader.ui \
61 repeatentrybase.ui
62UICDECLS = dateentry.h \
63 datebookdayheader.h \
64 datebooksettingsbase.h \
65 datebookweekheader.h \
66 repeatentrybase.h
67UICIMPLS = dateentry.cpp \
68 datebookdayheader.cpp \
69 datebooksettingsbase.cpp \
70 datebookweekheader.cpp \
71 repeatentrybase.cpp
72 SRCMOC =moc_datebookday.cpp \
73 moc_datebook.cpp \
74 moc_dateentryimpl.cpp \
75 moc_datebookdayheaderimpl.cpp \
76 moc_datebookweek.cpp \
77 moc_datebookweekheaderimpl.cpp \
78 moc_repeatentry.cpp \
79 moc_dateentry.cpp \
80 moc_datebookdayheader.cpp \
81 moc_datebooksettingsbase.cpp \
82 moc_datebookweekheader.cpp \
83 moc_repeatentrybase.cpp
84 OBJMOC =moc_datebookday.o \
85 moc_datebook.o \
86 moc_dateentryimpl.o \
87 moc_datebookdayheaderimpl.o \
88 moc_datebookweek.o \
89 moc_datebookweekheaderimpl.o \
90 moc_repeatentry.o \
91 moc_dateentry.o \
92 moc_datebookdayheader.o \
93 moc_datebooksettingsbase.o \
94 moc_datebookweekheader.o \
95 moc_repeatentrybase.o
96
97
98####### Implicit rules
99
100.SUFFIXES: .cpp .cxx .cc .C .c
101
102.cpp.o:
103 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
104
105.cxx.o:
106 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
107
108.cc.o:
109 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
110
111.C.o:
112 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
113
114.c.o:
115 $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
116
117####### Build rules
118
119
120all: $(DESTDIR)$(TARGET)
121
122$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
123 $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
124
125moc: $(SRCMOC)
126
127tmake:
128 tmake datebook.pro
129
130clean:
131 -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
132 -rm -f *~ core
133 -rm -f allmoc.cpp
134
135####### Extension Modules
136
137listpromodules:
138 @echo
139
140listallmodules:
141 @echo
142
143listaddonpromodules:
144 @echo
145
146listaddonentmodules:
147 @echo
148
149
150REQUIRES=
151
152####### Sub-libraries
153
154
155###### Combined headers
156
157
158
159####### Compile
160
161main.o: main.cpp \
162 datebook.h \
163 $(QPEDIR)/include/qpe/datebookdb.h \
164 $(QPEDIR)/include/qpe/event.h \
165 $(QPEDIR)/include/qpe/palmtoprecord.h \
166 $(QPEDIR)/include/qpe/qpeapplication.h
167
168datebookday.o: datebookday.cpp \
169 datebookday.h \
170 $(QPEDIR)/include/qpe/event.h \
171 $(QPEDIR)/include/qpe/palmtoprecord.h \
172 datebookdayheaderimpl.h \
173 datebookdayheader.h \
174 $(QPEDIR)/include/qpe/datebookdb.h \
175 $(QPEDIR)/include/qpe/resource.h \
176 $(QPEDIR)/include/qpe/qpeapplication.h \
177 $(QPEDIR)/include/qpe/timestring.h \
178 $(QPEDIR)/include/qpe/qpedebug.h
179
180datebook.o: datebook.cpp \
181 datebook.h \
182 $(QPEDIR)/include/qpe/datebookdb.h \
183 $(QPEDIR)/include/qpe/event.h \
184 $(QPEDIR)/include/qpe/palmtoprecord.h \
185 datebookday.h \
186 datebooksettings.h \
187 datebooksettingsbase.h \
188 datebookweek.h \
189 dateentryimpl.h \
190 dateentry.h \
191 $(QPEDIR)/include/qpe/datebookmonth.h \
192 $(QPEDIR)/include/qpe/qpeapplication.h \
193 $(QPEDIR)/include/qpe/config.h \
194 $(QPEDIR)/include/qpe/qpedebug.h \
195 $(QPEDIR)/include/qpe/finddialog.h \
196 $(QPEDIR)/include/qpe/ir.h \
197 $(QPEDIR)/include/qpe/qpemenubar.h \
198 $(QPEDIR)/include/qpe/qpemessagebox.h \
199 $(QPEDIR)/include/qpe/resource.h \
200 $(QPEDIR)/include/qpe/sound.h \
201 $(QPEDIR)/include/qpe/timestring.h \
202 $(QPEDIR)/include/qpe/qpetoolbar.h \
203 $(QPEDIR)/include/qpe/tzselect.h \
204 $(QPEDIR)/include/qpe/xmlreader.h
205
206dateentryimpl.o: dateentryimpl.cpp \
207 dateentryimpl.h \
208 dateentry.h \
209 $(QPEDIR)/include/qpe/event.h \
210 $(QPEDIR)/include/qpe/palmtoprecord.h \
211 repeatentry.h \
212 repeatentrybase.h \
213 $(QPEDIR)/include/qpe/qpeapplication.h \
214 $(QPEDIR)/include/qpe/categoryselect.h \
215 $(QPEDIR)/include/qpe/datebookmonth.h \
216 $(QPEDIR)/include/qpe/global.h \
217 $(QPEDIR)/include/qpe/timeconversion.h \
218 $(QPEDIR)/include/qpe/timestring.h \
219 $(QPEDIR)/include/qpe/tzselect.h
220
221datebookdayheaderimpl.o: datebookdayheaderimpl.cpp \
222 datebookdayheaderimpl.h \
223 datebookdayheader.h \
224 $(QPEDIR)/include/qpe/datebookmonth.h \
225 $(QPEDIR)/include/qpe/event.h \
226 $(QPEDIR)/include/qpe/palmtoprecord.h \
227 $(QPEDIR)/include/qpe/timestring.h
228
229datebooksettings.o: datebooksettings.cpp \
230 datebooksettings.h \
231 datebooksettingsbase.h \
232 $(QPEDIR)/include/qpe/qpeapplication.h
233
234datebookweek.o: datebookweek.cpp \
235 datebookweek.h \
236 $(QPEDIR)/include/qpe/event.h \
237 $(QPEDIR)/include/qpe/palmtoprecord.h \
238 datebookweekheaderimpl.h \
239 datebookweekheader.h \
240 $(QPEDIR)/include/qpe/calendar.h \
241 $(QPEDIR)/include/qpe/datebookdb.h \
242 $(QPEDIR)/include/qpe/qpeapplication.h \
243 $(QPEDIR)/include/qpe/timestring.h
244
245datebookweekheaderimpl.o: datebookweekheaderimpl.cpp \
246 datebookweekheaderimpl.h \
247 datebookweekheader.h
248
249repeatentry.o: repeatentry.cpp \
250 repeatentry.h \
251 repeatentrybase.h \
252 $(QPEDIR)/include/qpe/event.h \
253 $(QPEDIR)/include/qpe/palmtoprecord.h \
254 $(QPEDIR)/include/qpe/datebookmonth.h \
255 $(QPEDIR)/include/qpe/qpeapplication.h \
256 $(QPEDIR)/include/qpe/timestring.h
257
258dateentry.h: dateentry.ui
259 $(UIC) dateentry.ui -o $(INTERFACE_DECL_PATH)/dateentry.h
260
261dateentry.cpp: dateentry.ui
262 $(UIC) dateentry.ui -i dateentry.h -o dateentry.cpp
263
264datebookdayheader.h: datebookdayheader.ui
265 $(UIC) datebookdayheader.ui -o $(INTERFACE_DECL_PATH)/datebookdayheader.h
266
267datebookdayheader.cpp: datebookdayheader.ui
268 $(UIC) datebookdayheader.ui -i datebookdayheader.h -o datebookdayheader.cpp
269
270datebooksettingsbase.h: datebooksettingsbase.ui
271 $(UIC) datebooksettingsbase.ui -o $(INTERFACE_DECL_PATH)/datebooksettingsbase.h
272
273datebooksettingsbase.cpp: datebooksettingsbase.ui
274 $(UIC) datebooksettingsbase.ui -i datebooksettingsbase.h -o datebooksettingsbase.cpp
275
276datebookweekheader.h: datebookweekheader.ui
277 $(UIC) datebookweekheader.ui -o $(INTERFACE_DECL_PATH)/datebookweekheader.h
278
279datebookweekheader.cpp: datebookweekheader.ui
280 $(UIC) datebookweekheader.ui -i datebookweekheader.h -o datebookweekheader.cpp
281
282repeatentrybase.h: repeatentrybase.ui
283 $(UIC) repeatentrybase.ui -o $(INTERFACE_DECL_PATH)/repeatentrybase.h
284
285repeatentrybase.cpp: repeatentrybase.ui
286 $(UIC) repeatentrybase.ui -i repeatentrybase.h -o repeatentrybase.cpp
287
288dateentry.o: dateentry.cpp
289
290datebookdayheader.o: datebookdayheader.cpp
291
292datebooksettingsbase.o: datebooksettingsbase.cpp
293
294datebookweekheader.o: datebookweekheader.cpp
295
296repeatentrybase.o: repeatentrybase.cpp
297
298moc_datebookday.o: moc_datebookday.cpp \
299 datebookday.h \
300 $(QPEDIR)/include/qpe/event.h \
301 $(QPEDIR)/include/qpe/palmtoprecord.h
302
303moc_datebook.o: moc_datebook.cpp \
304 datebook.h \
305 $(QPEDIR)/include/qpe/datebookdb.h \
306 $(QPEDIR)/include/qpe/event.h \
307 $(QPEDIR)/include/qpe/palmtoprecord.h
308
309moc_dateentryimpl.o: moc_dateentryimpl.cpp \
310 dateentryimpl.h \
311 dateentry.h \
312 $(QPEDIR)/include/qpe/event.h \
313 $(QPEDIR)/include/qpe/palmtoprecord.h
314
315moc_datebookdayheaderimpl.o: moc_datebookdayheaderimpl.cpp \
316 datebookdayheaderimpl.h \
317 datebookdayheader.h
318
319moc_datebookweek.o: moc_datebookweek.cpp \
320 datebookweek.h \
321 $(QPEDIR)/include/qpe/event.h \
322 $(QPEDIR)/include/qpe/palmtoprecord.h
323
324moc_datebookweekheaderimpl.o: moc_datebookweekheaderimpl.cpp \
325 datebookweekheaderimpl.h \
326 datebookweekheader.h
327
328moc_repeatentry.o: moc_repeatentry.cpp \
329 repeatentry.h \
330 repeatentrybase.h \
331 $(QPEDIR)/include/qpe/event.h \
332 $(QPEDIR)/include/qpe/palmtoprecord.h
333
334moc_dateentry.o: moc_dateentry.cpp \
335 dateentry.h
336
337moc_datebookdayheader.o: moc_datebookdayheader.cpp \
338 datebookdayheader.h
339
340moc_datebooksettingsbase.o: moc_datebooksettingsbase.cpp \
341 datebooksettingsbase.h
342
343moc_datebookweekheader.o: moc_datebookweekheader.cpp \
344 datebookweekheader.h
345
346moc_repeatentrybase.o: moc_repeatentrybase.cpp \
347 repeatentrybase.h
348
349moc_datebookday.cpp: datebookday.h
350 $(MOC) datebookday.h -o moc_datebookday.cpp
351
352moc_datebook.cpp: datebook.h
353 $(MOC) datebook.h -o moc_datebook.cpp
354
355moc_dateentryimpl.cpp: dateentryimpl.h
356 $(MOC) dateentryimpl.h -o moc_dateentryimpl.cpp
357
358moc_datebookdayheaderimpl.cpp: datebookdayheaderimpl.h
359 $(MOC) datebookdayheaderimpl.h -o moc_datebookdayheaderimpl.cpp
360
361moc_datebookweek.cpp: datebookweek.h
362 $(MOC) datebookweek.h -o moc_datebookweek.cpp
363
364moc_datebookweekheaderimpl.cpp: datebookweekheaderimpl.h
365 $(MOC) datebookweekheaderimpl.h -o moc_datebookweekheaderimpl.cpp
366
367moc_repeatentry.cpp: repeatentry.h
368 $(MOC) repeatentry.h -o moc_repeatentry.cpp
369
370moc_dateentry.cpp: dateentry.h
371 $(MOC) dateentry.h -o moc_dateentry.cpp
372
373moc_datebookdayheader.cpp: datebookdayheader.h
374 $(MOC) datebookdayheader.h -o moc_datebookdayheader.cpp
375
376moc_datebooksettingsbase.cpp: datebooksettingsbase.h
377 $(MOC) datebooksettingsbase.h -o moc_datebooksettingsbase.cpp
378
379moc_datebookweekheader.cpp: datebookweekheader.h
380 $(MOC) datebookweekheader.h -o moc_datebookweekheader.cpp
381
382moc_repeatentrybase.cpp: repeatentrybase.h
383 $(MOC) repeatentrybase.h -o moc_repeatentrybase.cpp
384
385
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19** $Id$
20**
21**********************************************************************/
22
23#include "datebook.h"
24#include "datebookday.h"
25#include "datebooksettings.h"
26#include "datebookweek.h"
27#include "dateentryimpl.h"
28
29#include <qpe/datebookmonth.h>
30#include <qpe/qpeapplication.h>
31#include <qpe/config.h>
32#include <qpe/qpedebug.h>
33#include <qpe/event.h>
34#include <qpe/finddialog.h>
35#include <qpe/ir.h>
36#include <qpe/qpemenubar.h>
37#include <qpe/qpemessagebox.h>
38#include <qpe/resource.h>
39#include <qpe/sound.h>
40#include <qpe/timestring.h>
41#include <qpe/qpetoolbar.h>
42#include <qpe/tzselect.h>
43#include <qpe/xmlreader.h>
44
45#include <qaction.h>
46#include <qcopchannel_qws.h>
47#include <qdatetime.h>
48#include <qdialog.h>
49#include <qfile.h>
50#include <qlabel.h>
51#include <qlayout.h>
52#include <qmessagebox.h>
53#include <qpopupmenu.h>
54#include <qpushbutton.h>
55#include <qtextcodec.h>
56#include <qtextstream.h>
57#include <qtl.h>
58#include <qwidgetstack.h>
59#include <qwindowsystem_qws.h>
60
61#include <sys/stat.h>
62#include <sys/types.h>
63#include <fcntl.h>
64#include <unistd.h>
65
66#include <stdlib.h>
67
68#define DAY 1
69#define WEEK 2
70#define MONTH 3
71
72
73DateBook::DateBook( QWidget *parent, const char *, WFlags f )
74 : QMainWindow( parent, "datebook", f ),
75 aPreset( FALSE ),
76 presetTime( -1 ),
77 startTime( 8 ), // an acceptable default
78 syncing(FALSE),
79 inSearch(FALSE)
80{
81 QTime t;
82 t.start();
83 db = new DateBookDB;
84 qDebug("loading db t=%d", t.elapsed() );
85 loadSettings();
86 setCaption( tr("Calendar") );
87 setIcon( Resource::loadPixmap( "datebook_icon" ) );
88
89 setToolBarsMovable( FALSE );
90
91 QPEToolBar *bar = new QPEToolBar( this );
92 bar->setHorizontalStretchable( TRUE );
93
94 QPEMenuBar *mb = new QPEMenuBar( bar );
95 mb->setMargin( 0 );
96
97 QPEToolBar *sub_bar = new QPEToolBar(this);
98
99 QPopupMenu *view = new QPopupMenu( this );
100 QPopupMenu *settings = new QPopupMenu( this );
101
102 mb->insertItem( tr( "View" ), view );
103 mb->insertItem( tr( "Settings" ), settings );
104
105 QActionGroup *g = new QActionGroup( this );
106 g->setExclusive( TRUE );
107
108 QAction *a = new QAction( tr( "New" ), Resource::loadPixmap( "new" ),
109 QString::null, 0, this, 0 );
110 connect( a, SIGNAL( activated() ), this, SLOT( fileNew() ) );
111 a->addTo( sub_bar );
112
113 a = new QAction( tr( "Day" ), Resource::loadPixmap( "day" ), QString::null, 0, g, 0 );
114 connect( a, SIGNAL( activated() ), this, SLOT( viewDay() ) );
115 a->addTo( sub_bar );
116 a->addTo( view );
117 a->setToggleAction( TRUE );
118 a->setOn( TRUE );
119 dayAction = a;
120 a = new QAction( tr( "Week" ), Resource::loadPixmap( "week" ), QString::null, 0, g, 0 );
121 connect( a, SIGNAL( activated() ), this, SLOT( viewWeek() ) );
122 a->addTo( sub_bar );
123 a->addTo( view );
124 a->setToggleAction( TRUE );
125 weekAction = a;
126 a = new QAction( tr( "Month" ), Resource::loadPixmap( "month" ), QString::null, 0, g, 0 );
127 connect( a, SIGNAL( activated() ), this, SLOT( viewMonth() ) );
128 a->addTo( sub_bar );
129 a->addTo( view );
130 a->setToggleAction( TRUE );
131 monthAction = a;
132
133 a = new QAction( tr( "Find" ), Resource::loadPixmap( "mag" ), QString::null, 0, g, 0 );
134 connect( a, SIGNAL(activated()), this, SLOT(slotFind()) );
135 a->addTo( sub_bar );
136
137 a = new QAction( tr( "Today" ), QString::null, 0, 0 );
138 connect( a, SIGNAL( activated() ), this, SLOT( slotToday() ) );
139 a->addTo( view );
140
141 a = new QAction( tr( "Alarm and Start Time..." ), QString::null, 0, 0 );
142 connect( a, SIGNAL( activated() ), this, SLOT( slotSettings() ) );
143 a->addTo( settings );
144
145 views = new QWidgetStack( this );
146 setCentralWidget( views );
147
148 dayView = 0;
149 weekView = 0;
150 monthView = 0;
151
152 viewDay();
153 connect( qApp, SIGNAL(clockChanged(bool)),
154 this, SLOT(changeClock(bool)) );
155 connect( qApp, SIGNAL(weekChanged(bool)),
156 this, SLOT(changeWeek(bool)) );
157
158#if defined(Q_WS_QWS) && !defined(QT_NO_COP)
159 connect( qApp, SIGNAL(appMessage(const QCString&, const QByteArray&)),
160 this, SLOT(appMessage(const QCString&, const QByteArray&)) );
161#endif
162
163 // listen on QPE/System
164#if defined(Q_WS_QWS)
165#if !defined(QT_NO_COP)
166 QCopChannel *channel = new QCopChannel( "QPE/System", this );
167 connect( channel, SIGNAL(received(const QCString&, const QByteArray&)),
168 this, SLOT(receive(const QCString&, const QByteArray&)) );
169#endif
170#endif
171
172 qDebug("done t=%d", t.elapsed() );
173
174}
175
176void DateBook::receive( const QCString &msg, const QByteArray &data )
177{
178 QDataStream stream( data, IO_ReadOnly );
179 if ( msg == "timeChange(QString)" ) {
180 // update active view!
181 if ( dayAction->isOn() )
182 viewDay();
183 else if ( weekAction->isOn() )
184 viewWeek();
185 else if ( monthAction->isOn() )
186 viewMonth();
187 }
188}
189
190DateBook::~DateBook()
191{
192}
193
194void DateBook::slotSettings()
195{
196 DateBookSettings frmSettings( ampm, this );
197 frmSettings.setStartTime( startTime );
198 frmSettings.setAlarmPreset( aPreset, presetTime );
199#if defined (Q_WS_QWS) || defined(_WS_QWS_)
200 frmSettings.showMaximized();
201#endif
202
203 if ( frmSettings.exec() ) {
204 aPreset = frmSettings.alarmPreset();
205 presetTime = frmSettings.presetTime();
206 startTime = frmSettings.startTime();
207 if ( dayView )
208 dayView->setStartViewTime( startTime );
209 if ( weekView )
210 weekView->setStartViewTime( startTime );
211 saveSettings();
212
213 // make the change obvious
214 if ( views->visibleWidget() ) {
215 if ( views->visibleWidget() == dayView )
216 dayView->redraw();
217 else if ( views->visibleWidget() == weekView )
218 weekView->redraw();
219 }
220 }
221}
222
223void DateBook::fileNew()
224{
225 slotNewEventFromKey("");
226}
227
228QString DateBook::checkEvent(const Event &e)
229{
230 /* check if overlaps with itself */
231 bool checkFailed = FALSE;
232
233 /* check the next 12 repeats. should catch most problems */
234 QDate current_date = e.start().date();
235 Event previous = e;
236 for(int i = 0; i < 12; i++)
237 {
238 QDateTime next;
239 if (!nextOccurance(previous, current_date.addDays(1), next)) {
240 break; // no more repeats
241 }
242 if(next < previous.end()) {
243 checkFailed = TRUE;
244 break;
245 }
246 current_date = next.date();
247 }
248
249 if(checkFailed)
250 return tr("Event duration is potentially longer\n"
251 "than interval between repeats.");
252
253 return QString::null;
254}
255
256QDate DateBook::currentDate()
257{
258 QDate d = QDate::currentDate();
259
260 if ( dayView && views->visibleWidget() == dayView ) {
261 d = dayView->date();
262 } else if ( weekView && views->visibleWidget() == weekView ) {
263 d = weekView->date();
264 } else if ( monthView && views->visibleWidget() == monthView ) {
265 d = monthView->selectedDate();
266 }
267
268 return d;
269}
270
271void DateBook::viewDay()
272{
273 initDay();
274 dayAction->setOn( TRUE );
275 QDate d = currentDate();
276 dayView->setDate( d );
277 views->raiseWidget( dayView );
278 dayView->redraw();
279}
280
281void DateBook::viewWeek()
282{
283 initWeek();
284 weekAction->setOn( TRUE );
285 QDate d = currentDate();
286 weekView->setDate( d );
287 views->raiseWidget( weekView );
288 weekView->redraw();
289}
290
291void DateBook::viewMonth()
292{
293 initMonth();
294 monthAction->setOn( TRUE );
295 QDate d = currentDate();
296 monthView->setDate( d.year(), d.month(), d.day() );
297 views->raiseWidget( monthView );
298 monthView->redraw();
299}
300
301void DateBook::editEvent( const Event &e )
302{
303 if (syncing) {
304 QMessageBox::warning( this, tr("Calendar"),
305 tr( "Can not edit data, currently syncing") );
306 return;
307 }
308
309 // workaround added for text input.
310 QDialog editDlg( this, 0, TRUE );
311 DateEntry *entry;
312 editDlg.setCaption( tr("Edit Event") );
313 QVBoxLayout *vb = new QVBoxLayout( &editDlg );
314 QScrollView *sv = new QScrollView( &editDlg, "scrollview" );
315 sv->setResizePolicy( QScrollView::AutoOneFit );
316 // KLUDGE!!!
317 sv->setHScrollBarMode( QScrollView::AlwaysOff );
318 vb->addWidget( sv );
319 entry = new DateEntry( onMonday, e, ampm, &editDlg, "editor" );
320 entry->timezone->setEnabled( FALSE );
321 sv->addChild( entry );
322
323#if defined(Q_WS_QWS) || defined(_WS_QWS_)
324 editDlg.showMaximized();
325#endif
326 while (editDlg.exec() ) {
327 Event newEv = entry->event();
328 QString error = checkEvent(newEv);
329 if (!error.isNull()) {
330 if (QMessageBox::warning(this, "error box",
331 error, "Fix it", "Continue", 0, 0, 1) == 0)
332 continue;
333 }
334 db->editEvent(e, newEv);
335 emit newEvent();
336 break;
337 }
338}
339
340void DateBook::removeEvent( const Event &e )
341{
342 if (syncing) {
343 QMessageBox::warning( this, tr("Calendar"),
344 tr( "Can not edit data, currently syncing") );
345 return;
346 }
347
348 QString strName = e.description();
349
350 if ( !QPEMessageBox::confirmDelete( this, tr( "Calendar" ),strName ) )
351 return;
352
353 db->removeEvent( e );
354 if ( views->visibleWidget() == dayView && dayView )
355 dayView->redraw();
356}
357
358void DateBook::addEvent( const Event &e )
359{
360 QDate d = e.start().date();
361 initDay();
362 dayView->setDate( d );
363}
364
365void DateBook::showDay( int year, int month, int day )
366{
367 initDay();
368 dayView->setDate( year, month, day );
369 views->raiseWidget( dayView );
370 dayAction->setOn( TRUE );
371}
372
373void DateBook::initDay()
374{
375 if ( !dayView ) {
376 dayView = new DateBookDay( ampm, onMonday, db, views, "day view" );
377 views->addWidget( dayView, DAY );
378 dayView->setStartViewTime( startTime );
379 connect( this, SIGNAL( newEvent() ),
380 dayView, SLOT( redraw() ) );
381 connect( dayView, SIGNAL( newEvent() ),
382 this, SLOT( fileNew() ) );
383 connect( dayView, SIGNAL( removeEvent( const Event & ) ),
384 this, SLOT( removeEvent( const Event & ) ) );
385 connect( dayView, SIGNAL( editEvent( const Event & ) ),
386 this, SLOT( editEvent( const Event & ) ) );
387 connect( dayView, SIGNAL( beamEvent( const Event & ) ),
388 this, SLOT( beamEvent( const Event & ) ) );
389 connect( dayView, SIGNAL(sigNewEvent(const QString &)),
390 this, SLOT(slotNewEventFromKey(const QString &)) );
391 }
392}
393
394void DateBook::initWeek()
395{
396 if ( !weekView ) {
397 weekView = new DateBookWeek( ampm, onMonday, db, views, "week view" );
398 weekView->setStartViewTime( startTime );
399 views->addWidget( weekView, WEEK );
400 connect( weekView, SIGNAL( showDate( int, int, int ) ),
401 this, SLOT( showDay( int, int, int ) ) );
402 connect( this, SIGNAL( newEvent() ),
403 weekView, SLOT( redraw() ) );
404 }
405 //But also get it right: the year that we display can be different
406 //from the year of the current date. So, first find the year
407 //number of the current week.
408
409 int yearNumber, totWeeks;
410 calcWeek( currentDate(), totWeeks, yearNumber, onMonday );
411
412 QDate d = QDate( yearNumber, 12, 31 );
413 calcWeek( d, totWeeks, yearNumber, onMonday );
414
415 while ( totWeeks == 1 ) {
416 d = d.addDays( -1 );
417 calcWeek( d, totWeeks, yearNumber, onMonday );
418 }
419 if ( totWeeks != weekView->totalWeeks() )
420 weekView->setTotalWeeks( totWeeks );
421}
422
423void DateBook::initMonth()
424{
425 if ( !monthView ) {
426 monthView = new DateBookMonth( views, "month view", FALSE, db );
427 views->addWidget( monthView, MONTH );
428 connect( monthView, SIGNAL( dateClicked( int, int, int ) ),
429 this, SLOT( showDay( int, int, int ) ) );
430 connect( this, SIGNAL( newEvent() ),
431 monthView, SLOT( redraw() ) );
432 qApp->processEvents();
433 }
434}
435
436void DateBook::loadSettings()
437{
438 {
439 Config config( "qpe" );
440 config.setGroup("Time");
441 ampm = config.readBoolEntry( "AMPM", TRUE );
442 onMonday = config.readBoolEntry( "MONDAY" );
443 }
444
445 {
446 Config config("DateBook");
447 config.setGroup("Main");
448 startTime = config.readNumEntry("startviewtime", 8);
449 aPreset = config.readBoolEntry("alarmpreset");
450 presetTime = config.readNumEntry("presettime");
451 }
452}
453
454void DateBook::saveSettings()
455{
456 Config config( "qpe" );
457 Config configDB( "DateBook" );
458 configDB.setGroup( "Main" );
459 configDB.writeEntry("startviewtime",startTime);
460 configDB.writeEntry("alarmpreset",aPreset);
461 configDB.writeEntry("presettime",presetTime);
462}
463
464void DateBook::appMessage(const QCString& msg, const QByteArray& data)
465{
466 bool needShow = FALSE;
467 if ( msg == "alarm(QDateTime,int)" ) {
468 QDataStream ds(data,IO_ReadOnly);
469 QDateTime when; int warn;
470 ds >> when >> warn;
471
472 // check to make it's okay to continue,
473 // this is the case that the time was set ahead, and
474 // we are forced given a stale alarm...
475 QDateTime current = QDateTime::currentDateTime();
476 if ( current.time().hour() != when.time().hour()
477 && current.time().minute() != when.time().minute() )
478 return;
479
480 QValueList<EffectiveEvent> list = db->getEffectiveEvents(when.addSecs(warn*60));
481 if ( list.count() > 0 ) {
482 QString msg;
483 bool bSound = FALSE;
484 int stopTimer = 0;
485 bool found = FALSE;
486 for ( QValueList<EffectiveEvent>::ConstIterator it=list.begin();
487 it!=list.end(); ++it ) {
488 if ( (*it).event().hasAlarm() ) {
489 found = TRUE;
490 msg += "<CENTER><B>" + (*it).description() + "</B>"
491 + "<BR>" + (*it).location() + "<BR>"
492 + TimeString::dateString((*it).event().start(),ampm)
493 + (warn
494 ? tr(" (in " + QString::number(warn)
495 + tr(" minutes)"))
496 : QString(""))
497 + "<BR>"
498 + (*it).notes() + "</CENTER>";
499 if ( (*it).event().alarmSound() != Event::Silent ) {
500 bSound = TRUE;
501 }
502 }
503 }
504 if ( found ) {
505 if ( bSound ) {
506 Sound::soundAlarm();
507 stopTimer = startTimer( 5000 );
508 }
509
510 QDialog dlg( this, 0, TRUE );
511 QVBoxLayout *vb = new QVBoxLayout( &dlg );
512 QScrollView *view = new QScrollView( &dlg, "scrollView");
513 view->setResizePolicy( QScrollView::AutoOneFit );
514 vb->addWidget( view );
515 QLabel *lblMsg = new QLabel( msg, &dlg );
516 view->addChild( lblMsg );
517 QPushButton *cmdOk = new QPushButton( tr("OK"), &dlg );
518 connect( cmdOk, SIGNAL(clicked()), &dlg, SLOT(accept()) );
519 vb->addWidget( cmdOk );
520
521#if defined(Q_WS_QWS) || defined(_WS_QWS_)
522 dlg.showMaximized();
523#endif
524 needShow = dlg.exec();
525
526 if ( bSound )
527 killTimer( stopTimer );
528 }
529 }
530 } else if ( msg == "nextView()" ) {
531 QWidget* cur = views->visibleWidget();
532 if ( cur ) {
533 if ( cur == dayView )
534 viewWeek();
535 else if ( cur == weekView )
536 viewMonth();
537 else if ( cur == monthView )
538 viewDay();
539 needShow = TRUE;
540 }
541 }
542 if ( needShow ) {
543#if defined(Q_WS_QWS) || defined(_WS_QWS_)
544 showMaximized();
545#else
546 show();
547#endif
548 raise();
549 QPEApplication::setKeepRunning();
550 setActiveWindow();
551 }
552}
553
554void DateBook::reload()
555{
556 db->reload();
557 if ( dayAction->isOn() )
558 viewDay();
559 else if ( weekAction->isOn() )
560 viewWeek();
561 else if ( monthAction->isOn() )
562 viewMonth();
563 syncing = FALSE;
564}
565
566void DateBook::flush()
567{
568 syncing = TRUE;
569 db->save();
570}
571
572void DateBook::timerEvent( QTimerEvent *e )
573{
574 static int stop = 0;
575 if ( stop < 10 ) {
576 Sound::soundAlarm();
577 stop++;
578 } else {
579 stop = 0;
580 killTimer( e->timerId() );
581 }
582}
583
584void DateBook::changeClock( bool newClock )
585{
586 ampm = newClock;
587 // repaint the affected objects...
588 if (dayView) dayView->redraw();
589 if (weekView) weekView->redraw();
590}
591
592void DateBook::changeWeek( bool m )
593{
594 /* no need to redraw, each widget catches. Do need to
595 store though for widgets we haven't made yet */
596 onMonday = m;
597}
598
599void DateBook::slotToday()
600{
601 // we need to view today
602 QDate dt = QDate::currentDate();
603 showDay( dt.year(), dt.month(), dt.day() );
604}
605
606void DateBook::closeEvent( QCloseEvent *e )
607{
608 if(syncing) {
609 /* no need to save, did that at flush */
610 e->accept();
611 return;
612 }
613
614 // save settings will generate it's own error messages, no
615 // need to do checking ourselves.
616 saveSettings();
617 if ( db->save() )
618 e->accept();
619 else {
620 if ( QMessageBox::critical( this, tr( "Out of space" ),
621 tr("Calendar was unable to save\n"
622 "your changes.\n"
623 "Free up some space and try again.\n"
624 "\nQuit anyway?"),
625 QMessageBox::Yes|QMessageBox::Escape,
626 QMessageBox::No|QMessageBox::Default )
627 != QMessageBox::No )
628 e->accept();
629 else
630 e->ignore();
631 }
632}
633
634// Entering directly from the "keyboard"
635void DateBook::slotNewEventFromKey( const QString &str )
636{
637 if (syncing) {
638 QMessageBox::warning( this, tr("Calendar"),
639 tr( "Can not edit data, currently syncing") );
640 return;
641 }
642
643 // We get to here from a key pressed in the Day View
644 // So we can assume some things. We want the string
645 // passed in to be part of the description.
646 QDateTime start, end;
647 if ( views->visibleWidget() == dayView ) {
648 dayView->selectedDates( start, end );
649 } else if ( views->visibleWidget() == monthView ) {
650 QDate d = monthView->selectedDate();
651 start = end = d;
652 start.setTime( QTime( 10, 0 ) );
653 end.setTime( QTime( 12, 0 ) );
654 } else if ( views->visibleWidget() == weekView ) {
655 QDate d = weekView->date();
656 start = end = d;
657 start.setTime( QTime( 10, 0 ) );
658 end.setTime( QTime( 12, 0 ) );
659 }
660
661 // argh! This really needs to be encapsulated in a class
662 // or function.
663 QDialog newDlg( this, 0, TRUE );
664 newDlg.setCaption( DateEntryBase::tr("New Event") );
665 DateEntry *e;
666 QVBoxLayout *vb = new QVBoxLayout( &newDlg );
667 QScrollView *sv = new QScrollView( &newDlg );
668 sv->setResizePolicy( QScrollView::AutoOneFit );
669 sv->setFrameStyle( QFrame::NoFrame );
670 sv->setHScrollBarMode( QScrollView::AlwaysOff );
671 vb->addWidget( sv );
672
673 Event ev;
674 ev.setDescription( str );
675 // When the new gui comes in, change this...
676 ev.setLocation( tr("(Unknown)") );
677 ev.setStart( start );
678 ev.setEnd( end );
679
680 e = new DateEntry( onMonday, ev, ampm, &newDlg );
681 e->setAlarmEnabled( aPreset, presetTime, Event::Loud );
682 sv->addChild( e );
683#if defined(Q_WS_QWS) || defined(_WS_QWS_)
684 newDlg.showMaximized();
685#endif
686 while (newDlg.exec()) {
687 ev = e->event();
688 ev.assignUid();
689 QString error = checkEvent( ev );
690 if ( !error.isNull() ) {
691 if ( QMessageBox::warning( this, tr("Error!"),
692 error, tr("Fix it"), tr("Continue"), 0, 0, 1 ) == 0 )
693 continue;
694 }
695 db->addEvent( ev );
696 emit newEvent();
697 break;
698 }
699}
700
701void DateBook::setDocument( const QString &filename )
702{
703 if ( filename.find(".vcs") != int(filename.length()) - 4 ) return;
704
705 QValueList<Event> tl = Event::readVCalendar( filename );
706 for( QValueList<Event>::Iterator it = tl.begin(); it != tl.end(); ++it ) {
707 db->addEvent( *it );
708 }
709}
710
711static const char * beamfile = "/tmp/obex/event.vcs";
712
713void DateBook::beamEvent( const Event &e )
714{
715 qDebug("trying to beamn");
716 unlink( beamfile ); // delete if exists
717 mkdir("/tmp/obex/", 0755);
718 Event::writeVCalendar( beamfile, e );
719 Ir *ir = new Ir( this );
720 connect( ir, SIGNAL( done( Ir * ) ), this, SLOT( beamDone( Ir * ) ) );
721 QString description = e.description();
722 ir->send( beamfile, description, "text/x-vCalendar" );
723}
724
725void DateBook::beamDone( Ir *ir )
726{
727 delete ir;
728 unlink( beamfile );
729}
730
731void DateBook::slotFind()
732{
733 // move it to the day view...
734 viewDay();
735 FindDialog frmFind( "Calendar", this );
736 frmFind.setUseDate( true );
737 frmFind.setDate( currentDate() );
738 QObject::connect( &frmFind,
739 SIGNAL(signalFindClicked(const QString&, const QDate&,
740 bool, bool, int)),
741 this,
742 SLOT(slotDoFind(const QString&, const QDate&,
743 bool, bool, int)) );
744 QObject::connect( this,
745 SIGNAL(signalNotFound()),
746 &frmFind,
747 SLOT(slotNotFound()) );
748 QObject::connect( this,
749 SIGNAL(signalWrapAround()),
750 &frmFind,
751 SLOT(slotWrapAround()) );
752 frmFind.exec();
753 inSearch = false;
754}
755
756bool catComp( QArray<int> cats, int category )
757{
758 bool returnMe;
759 int i,
760 count;
761
762 count = int(cats.count());
763 returnMe = false;
764 if ( (category == -1 && count == 0) || category == -2 )
765 returnMe = true;
766 else {
767 for ( i = 0; i < count; i++ ) {
768 if ( category == cats[i] ) {
769 returnMe = true;
770 break;
771 }
772 }
773 }
774 return returnMe;
775}
776
777
778void DateBook::slotDoFind( const QString& txt, const QDate &dt,
779 bool caseSensitive, bool /*backwards*/,
780 int category )
781{
782 QDateTime dtEnd( QDate(3001, 1, 1), QTime(0, 0, 0) ),
783 next;
784
785 QRegExp r( txt );
786 r.setCaseSensitive( caseSensitive );
787
788
789 static Event rev,
790 nonrev;
791 if ( !inSearch ) {
792 rev.setStart( QDateTime(QDate(1960, 1, 1), QTime(0, 0, 0)) );
793 nonrev.setStart( rev.start() );
794 inSearch = true;
795 }
796 static QDate searchDate = dt;
797 static bool wrapAround = true;
798 bool candidtate;
799 candidtate = false;
800
801 QValueList<Event> repeats = db->getRawRepeats();
802
803 // find the candidate for the first repeat that matches...
804 QValueListConstIterator<Event> it;
805 QDate start = dt;
806 for ( it = repeats.begin(); it != repeats.end(); ++it ) {
807 if ( catComp( (*it).categories(), category ) ) {
808 while ( nextOccurance( *it, start, next ) ) {
809 if ( next < dtEnd ) {
810 if ( (*it).match( r ) && !(next <= rev.start()) ) {
811 rev = *it;
812 dtEnd = next;
813 rev.setStart( next );
814 candidtate = true;
815 wrapAround = true;
816 start = dt;
817 break;
818 } else
819 start = next.date().addDays( 1 );
820 }
821 }
822 }
823 }
824
825 // now the for first non repeat...
826 QValueList<Event> nonRepeats = db->getNonRepeatingEvents( dt, dtEnd.date() );
827 qHeapSort( nonRepeats.begin(), nonRepeats.end() );
828 for ( it = nonRepeats.begin(); it != nonRepeats.end(); ++it ) {
829 if ( catComp( (*it).categories(), category ) ) {
830 if ( (*it).start() < dtEnd ) {
831 if ( (*it).match( r ) && !(*it <= nonrev) ) {
832 nonrev = *it;
833 dtEnd = nonrev.start();
834 candidtate = true;
835 wrapAround = true;
836 break;
837 }
838 }
839 }
840 }
841 if ( candidtate ) {
842 dayView->setStartViewTime( dtEnd.time().hour() );
843 dayView->setDate( dtEnd.date().year(), dtEnd.date().month(),
844 dtEnd.date().day() );
845 } else {
846 if ( wrapAround ) {
847 emit signalWrapAround();
848 rev.setStart( QDateTime(QDate(1960, 1, 1), QTime(0, 0, 0)) );
849 nonrev.setStart( rev.start() );
850 } else
851 emit signalNotFound();
852 wrapAround = !wrapAround;
853 }
854}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef DATEBOOK_H
21#define DATEBOOK_H
22
23#include <qpe/datebookdb.h>
24
25#include <qmainwindow.h>
26
27class QAction;
28class QWidgetStack;
29class DateBookDay;
30class DateBookWeek;
31class DateBookMonth;
32class Event;
33class QDate;
34class Ir;
35
36class DateBook : public QMainWindow
37{
38 Q_OBJECT
39
40public:
41 DateBook( QWidget *parent = 0, const char *name = 0, WFlags f = 0 );
42 ~DateBook();
43
44signals:
45 void newEvent();
46 void signalNotFound();
47 void signalWrapAround();
48
49protected:
50 QDate currentDate();
51 void timerEvent( QTimerEvent *e );
52 void closeEvent( QCloseEvent *e );
53
54public slots:
55 void flush();
56 void reload();
57
58private slots:
59 void fileNew();
60 void slotSettings();
61 void slotToday();// view today
62 void changeClock( bool newClock );
63 void changeWeek( bool newDay );
64 void appMessage(const QCString& msg, const QByteArray& data);
65 // handle key events in the day view...
66 void slotNewEventFromKey( const QString &str );
67 void slotFind();
68 void slotDoFind( const QString &, const QDate &, bool, bool, int );
69
70 void viewDay();
71 void viewWeek();
72 void viewMonth();
73
74 void showDay( int y, int m, int d );
75
76 void editEvent( const Event &e );
77 void removeEvent( const Event &e );
78
79 void receive( const QCString &msg, const QByteArray &data );
80 void setDocument( const QString & );
81 void beamEvent( const Event &e );
82 void beamDone( Ir *ir );
83
84private:
85 void addEvent( const Event &e );
86 void initDay();
87 void initWeek();
88 void initMonth();
89 void loadSettings();
90 void saveSettings();
91
92private:
93 DateBookDB *db;
94 QWidgetStack *views;
95 DateBookDay *dayView;
96 DateBookWeek *weekView;
97 DateBookMonth *monthView;
98 QAction *dayAction, *weekAction, *monthAction;
99 bool aPreset; // have everything set to alarm?
100 int presetTime; // the standard time for the alarm
101 int startTime;
102 bool ampm;
103 bool onMonday;
104
105 bool syncing;
106 bool inSearch;
107
108 QString checkEvent(const Event &);
109};
110
111#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 @@
1 TEMPLATE= app
2 CONFIG += qt warn_on release
3 DESTDIR = $(QPEDIR)/bin
4
5 HEADERS= datebookday.h \
6 datebook.h \
7 dateentryimpl.h \
8 datebookdayheaderimpl.h \
9 datebooksettings.h \
10 datebookweek.h \
11 datebookweekheaderimpl.h \
12 repeatentry.h
13
14 SOURCES= main.cpp \
15 datebookday.cpp \
16 datebook.cpp \
17 dateentryimpl.cpp \
18 datebookdayheaderimpl.cpp \
19 datebooksettings.cpp \
20 datebookweek.cpp \
21 datebookweekheaderimpl.cpp \
22 repeatentry.cpp
23
24 INTERFACES= dateentry.ui \
25 datebookdayheader.ui \
26 datebooksettingsbase.ui \
27 datebookweekheader.ui \
28 repeatentrybase.ui
29
30INCLUDEPATH += $(QPEDIR)/include
31 DEPENDPATH+= $(QPEDIR)/include
32LIBS += -lqpe
33
34 TARGET = datebook
35
36TRANSLATIONS = ../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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "datebookday.h"
22#include "datebookdayheaderimpl.h"
23
24#include <qpe/datebookdb.h>
25#include <qpe/resource.h>
26#include <qpe/event.h>
27#include <qpe/qpeapplication.h>
28#include <qpe/timestring.h>
29#include <qpe/qpedebug.h>
30
31#include <qheader.h>
32#include <qdatetime.h>
33#include <qpainter.h>
34#include <qsimplerichtext.h>
35#include <qpopupmenu.h>
36#include <qtextcodec.h>
37#include <qpalette.h>
38
39DateBookDayView::DateBookDayView( bool whichClock, QWidget *parent,
40 const char *name )
41 : QTable( 24, 1, parent, name ),
42 ampm( whichClock )
43{
44 enableClipper(TRUE);
45 setTopMargin( 0 );
46 horizontalHeader()->hide();
47 setLeftMargin(38);
48 setColumnStretchable( 0, TRUE );
49 setHScrollBarMode( QScrollView::AlwaysOff );
50 verticalHeader()->setPalette(white);
51 verticalHeader()->setResizeEnabled(FALSE);
52 setSelectionMode( Single );
53
54 // get rid of being able to edit things...
55 QTableItem *tmp;
56 int row;
57 for ( row = 0; row < numRows(); row++ ) {
58 tmp = new QTableItem( this, QTableItem::Never, QString::null);
59 setItem( row, 0, tmp );
60 }
61 initHeader();
62 QObject::connect( qApp, SIGNAL(clockChanged(bool)),
63 this, SLOT(slotChangeClock(bool)) );
64}
65
66void DateBookDayView::initHeader()
67{
68 QString strTmp;
69 for ( int i = 0; i < 24; ++i ) {
70 if ( ampm ) {
71 if ( i == 0 )
72 strTmp = QString::number(12) + ":00";
73 else if ( i == 12 )
74 strTmp = QString::number(12) + tr(":00p");
75 else if ( i > 12 )
76 strTmp = QString::number( i - 12 ) + tr(":00p");
77 else
78 strTmp = QString::number(i) + ":00";
79 } else {
80 if ( i < 10 )
81 strTmp = "0" + QString::number(i) + ":00";
82 else
83 strTmp = QString::number(i) + ":00";
84 }
85 strTmp = strTmp.rightJustify( 6, ' ' );
86 verticalHeader()->setLabel( i, strTmp );
87 setRowStretchable( i, FALSE );
88 }
89}
90
91void DateBookDayView::slotChangeClock( bool newClock )
92{
93 ampm = newClock;
94 initHeader();
95}
96
97bool DateBookDayView::whichClock() const
98{
99 return ampm;
100}
101
102void DateBookDayView::moveUp()
103{
104 scrollBy(0, -20);
105}
106
107void DateBookDayView::moveDown()
108{
109 scrollBy(0, 20);
110}
111
112void DateBookDayView::paintCell( QPainter *p, int, int, const QRect &cr, bool )
113{
114 int w = cr.width();
115 int h = cr.height();
116 p->fillRect( 0, 0, w, h, colorGroup().brush( QColorGroup::Base ) );
117 if ( showGrid() ) {
118 // Draw our lines
119 int x2 = w - 1;
120 int y2 = h - 1;
121 QPen pen( p->pen() );
122 p->setPen( colorGroup().mid() );
123 p->drawLine( x2, 0, x2, y2 );
124 p->drawLine( 0, y2, x2, y2 );
125 p->setPen( pen );
126 }
127}
128
129void DateBookDayView::paintFocus( QPainter *, const QRect & )
130{
131}
132
133
134void DateBookDayView::resizeEvent( QResizeEvent *e )
135{
136 QTable::resizeEvent( e );
137 columnWidthChanged( 0 );
138 emit sigColWidthChanged();
139}
140
141void DateBookDayView::keyPressEvent( QKeyEvent *e )
142{
143 QString txt = e->text();
144 if ( !txt.isNull() && txt[0] > ' ' && e->key() < 0x1000 ) {
145 // we this is some sort of thing we know about...
146 e->accept();
147 emit sigCapturedKey( txt );
148 } else {
149 // I don't know what this key is, do you?
150 e->ignore();
151 }
152}
153
154
155//===========================================================================
156
157DateBookDay::DateBookDay( bool ampm, bool startOnMonday,
158 DateBookDB *newDb, QWidget *parent,
159 const char *name )
160 : QVBox( parent, name ),
161 currDate( QDate::currentDate() ),
162 db( newDb ),
163 startTime( 0 )
164{
165 widgetList.setAutoDelete( true );
166 header = new DateBookDayHeader( startOnMonday, this, "day header" );
167 header->setDate( currDate.year(), currDate.month(), currDate.day() );
168 view = new DateBookDayView( ampm, this, "day view" );
169 connect( header, SIGNAL( dateChanged( int, int, int ) ),
170 this, SLOT( dateChanged( int, int, int ) ) );
171 connect( view, SIGNAL( sigColWidthChanged() ),
172 this, SLOT( slotColWidthChanged() ) );
173 connect( qApp, SIGNAL(weekChanged(bool)),
174 this, SLOT(slotWeekChanged(bool)) );
175 connect( view, SIGNAL(sigCapturedKey(const QString &)),
176 this, SIGNAL(sigNewEvent(const QString&)) );
177}
178
179void DateBookDay::selectedDates( QDateTime &start, QDateTime &end )
180{
181 start.setDate( currDate );
182 end.setDate( currDate );
183
184 int sh=99,eh=-1;
185
186 int n = dayView()->numSelections();
187
188 for (int i=0; i<n; i++) {
189 QTableSelection sel = dayView()->selection( i );
190 sh = QMIN(sh,sel.topRow());
191 eh = QMAX(sh,sel.bottomRow()+1);
192 }
193 if (sh > 23 || eh < 1) {
194 sh=8;
195 eh=9;
196 }
197
198 start.setTime( QTime( sh, 0, 0 ) );
199 end.setTime( QTime( eh, 0, 0 ) );
200}
201
202void DateBookDay::setDate( int y, int m, int d )
203{
204 header->setDate( y, m, d );
205}
206
207void DateBookDay::setDate( QDate d)
208{
209 header->setDate( d.year(), d.month(), d.day() );
210}
211
212void DateBookDay::dateChanged( int y, int m, int d )
213{
214 QDate date( y, m, d );
215 if ( currDate == date )
216 return;
217 currDate.setYMD( y, m, d );
218 relayoutPage();
219 dayView()->clearSelection();
220 QTableSelection ts;
221 ts.init( startTime, 0 );
222 ts.expandTo( startTime, 0 );
223 dayView()->addSelection( ts );
224}
225
226void DateBookDay::redraw()
227{
228 if ( isUpdatesEnabled() )
229 relayoutPage();
230}
231
232void DateBookDay::getEvents()
233{
234 widgetList.clear();
235
236 QValueList<EffectiveEvent> eventList = db->getEffectiveEvents( currDate,
237 currDate );
238 QValueListIterator<EffectiveEvent> it;
239 for ( it = eventList.begin(); it != eventList.end(); ++it ) {
240 DateBookDayWidget* w = new DateBookDayWidget( *it, this );
241 connect( w, SIGNAL( deleteMe( const Event & ) ),
242 this, SIGNAL( removeEvent( const Event & ) ) );
243 connect( w, SIGNAL( editMe( const Event & ) ),
244 this, SIGNAL( editEvent( const Event & ) ) );
245 connect( w, SIGNAL( beamMe( const Event & ) ),
246 this, SIGNAL( beamEvent( const Event & ) ) );
247 widgetList.append( w );
248 }
249}
250
251static int place( const DateBookDayWidget *item, bool *used, int maxn )
252{
253 int place = 0;
254 int start = item->event().start().hour();
255 QTime e = item->event().end();
256 int end = e.hour();
257 if ( e.minute() < 5 )
258 end--;
259 if ( end < start )
260 end = start;
261 while ( place < maxn ) {
262 bool free = TRUE;
263 int s = start;
264 while( s <= end ) {
265 if ( used[10*s+place] ) {
266 free = FALSE;
267 break;
268 }
269 s++;
270 }
271 if ( free ) break;
272 place++;
273 }
274 if ( place == maxn ) {
275 return -1;
276 }
277 while( start <= end ) {
278 used[10*start+place] = TRUE;
279 start++;
280 }
281 return place;
282}
283
284
285void DateBookDay::relayoutPage( bool fromResize )
286{
287 setUpdatesEnabled( FALSE );
288 if ( !fromResize )
289 getEvents(); // no need we already have them!
290
291 int wCount = widgetList.count();
292 int wid = view->columnWidth(0)-1;
293 int n = 1;
294
295 if ( wCount < 20 ) {
296 for ( int i = 0; i < wCount; ) {
297 DateBookDayWidget *w = widgetList.at(i);
298 int x = 0;
299 int xp = 0;
300 QRect geom = w->geometry();
301 geom.setX( x );
302 geom.setWidth( wid );
303 while ( xp < n && intersects( w, geom ) ) {
304 x += wid;
305 xp++;
306 geom.moveBy( wid, 0 );
307 }
308 if ( xp >= n ) {
309 n++;
310 wid = ( view->columnWidth(0)-1 ) / n;
311 i = 0;
312 } else {
313 w->setGeometry( geom );
314 i++;
315 }
316 }
317 view->setContentsPos( 0, startTime * view->rowHeight(0) );
318 } else {
319
320
321 int hours[24];
322 memset( hours, 0, 24*sizeof( int ) );
323 bool overFlow = FALSE;
324 for ( int i = 0; i < wCount; i++ ) {
325 DateBookDayWidget *w = widgetList.at(i);
326 int start = w->event().start().hour();
327 QTime e = w->event().end();
328 int end = e.hour();
329 if ( e.minute() < 5 )
330 end--;
331 if ( end < start )
332 end = start;
333 while( start <= end ) {
334 hours[start]++;
335 if ( hours[start] >= 10 )
336 overFlow = TRUE;
337 ++start;
338 }
339 if ( overFlow )
340 break;
341 }
342 for ( int i = 0; i < 24; i++ ) {
343 n = QMAX( n, hours[i] );
344 }
345 wid = ( view->columnWidth(0)-1 ) / n;
346
347 bool used[24*10];
348 memset( used, FALSE, 24*10*sizeof( bool ) );
349
350 for ( int i = 0; i < wCount; i++ ) {
351 DateBookDayWidget *w = widgetList.at(i);
352 int xp = place( w, used, n );
353 if ( xp != -1 ) {
354 QRect geom = w->geometry();
355 geom.setX( xp*wid );
356 geom.setWidth( wid );
357 w->setGeometry( geom );
358 }
359 }
360 view->setContentsPos( 0, startTime * view->rowHeight(0) );
361 }
362 setUpdatesEnabled( TRUE );
363 return;
364}
365
366DateBookDayWidget *DateBookDay::intersects( const DateBookDayWidget *item, const QRect &geom )
367{
368 int i = 0;
369 DateBookDayWidget *w = widgetList.at(i);
370 int wCount = widgetList.count();
371 while ( i < wCount && w != item ) {
372 if ( w->geometry().intersects( geom ) ) {
373 return w;
374 }
375 w = widgetList.at(++i);
376 }
377
378 return 0;
379}
380
381
382QDate DateBookDay::date() const
383{
384 return currDate;
385}
386
387void DateBookDay::setStartViewTime( int startHere )
388{
389 startTime = startHere;
390 dayView()->clearSelection();
391 QTableSelection ts;
392 ts.init( startTime, 0 );
393 ts.expandTo( startTime, 0 );
394 dayView()->addSelection( ts );
395}
396
397int DateBookDay::startViewTime() const
398{
399 return startTime;
400}
401
402void DateBookDay::slotWeekChanged( bool bStartOnMonday )
403{
404 header->setStartOfWeek( bStartOnMonday );
405 // redraw();
406}
407
408void DateBookDay::keyPressEvent(QKeyEvent *e)
409{
410 switch(e->key()) {
411 case Key_Up:
412 view->moveUp();
413 break;
414 case Key_Down:
415 view->moveDown();
416 break;
417 case Key_Left:
418 setDate(QDate(currDate).addDays(-1));
419 break;
420 case Key_Right:
421 setDate(QDate(currDate).addDays(1));
422 break;
423 default:
424 e->ignore();
425 }
426}
427
428//===========================================================================
429
430DateBookDayWidget::DateBookDayWidget( const EffectiveEvent &e,
431 DateBookDay *db )
432 : QWidget( db->dayView()->viewport() ), ev( e ), dateBook( db )
433{
434 bool whichClock = db->dayView()->whichClock();
435
436 // why would someone use "<"? Oh well, fix it up...
437 // I wonder what other things may be messed up...
438 QString strDesc = ev.description();
439 int where = strDesc.find( "<" );
440 while ( where != -1 ) {
441 strDesc.remove( where, 1 );
442 strDesc.insert( where, "&#60;" );
443 where = strDesc.find( "<", where );
444 }
445
446 QString strCat;
447 // ### Fix later...
448// QString strCat = ev.category();
449// where = strCat.find( "<" );
450// while ( where != -1 ) {
451 // strCat.remove( where, 1 );
452 // strCat.insert( where, "&#60;" );
453 // where = strCat.find( "<", where );
454// }
455
456 QString strNote = ev.notes();
457 where = strNote.find( "<" );
458 while ( where != -1 ) {
459 strNote.remove( where, 1 );
460 strNote.insert( where, "&#60;" );
461 where = strNote.find( "<", where );
462 }
463
464 text = "<b>" + strDesc + "</b><br>" + "<i>"
465 + strCat + "</i>"
466 + "<br><b>" + tr("Start") + "</b>: ";
467
468
469 if ( e.startDate() != ev.date() ) {
470 // multi-day event. Show start date
471 text += TimeString::longDateString( e.startDate() );
472 } else {
473 // Show start time.
474 text += TimeString::timeString( ev.start(), whichClock, FALSE );
475 }
476
477 text += "<br><b>" + tr("End") + "</b>: ";
478 if ( e.endDate() != ev.date() ) {
479 // multi-day event. Show end date
480 text += TimeString::longDateString( e.endDate() );
481 } else {
482 // Show end time.
483 text += TimeString::timeString( ev.end(), whichClock, FALSE );
484 }
485 text += "<br><br>" + strNote;
486 setBackgroundMode( PaletteBase );
487
488 QTime s = ev.start();
489 QTime e = ev.end();
490 int y = s.hour()*60+s.minute();
491 int h = e.hour()*60+e.minute()-y;
492 int rh = dateBook->dayView()->rowHeight(0);
493 y = y*rh/60;
494 h = h*rh/60;
495 if ( h < 3 )
496 h = 3;
497 geom.setY( y );
498 geom.setHeight( h );
499}
500
501DateBookDayWidget::~DateBookDayWidget()
502{
503}
504
505void DateBookDayWidget::paintEvent( QPaintEvent *e )
506{
507 QPainter p( this );
508 p.setPen( QColor(100, 100, 100) );
509 p.setBrush( QColor( 255, 240, 230 ) ); // based on priority?
510 p.drawRect(rect());
511
512 int y = 0;
513 int d = 0;
514
515 if ( ev.event().hasAlarm() ) {
516 p.drawPixmap( width() - 16, 0, Resource::loadPixmap( "bell" ) );
517 y = 20;
518 d = 20;
519 }
520
521 if ( ev.event().hasRepeat() ) {
522 p.drawPixmap( width() - 16, y, Resource::loadPixmap( "repeat" ) );
523 d = 20;
524 }
525
526 QSimpleRichText rt( text, font() );
527 rt.setWidth( geom.width() - d - 6 );
528 rt.draw( &p, 3, 0, e->region(), colorGroup() );
529}
530
531void DateBookDayWidget::mousePressEvent( QMouseEvent *e )
532{
533 QPopupMenu m;
534 m.insertItem( tr( "Edit" ), 1 );
535 m.insertItem( tr( "Delete" ), 2 );
536 m.insertItem( tr( "Beam" ), 3 );
537 int r = m.exec( e->globalPos() );
538 if ( r == 1 ) {
539 emit editMe( ev.event() );
540 } else if ( r == 2 ) {
541 emit deleteMe( ev.event() );
542 } else if ( r == 3 ) {
543 emit beamMe( ev.event() );
544 }
545}
546
547void DateBookDayWidget::setGeometry( const QRect &r )
548{
549 geom = r;
550 setFixedSize( r.width()+1, r.height()+1 );
551 dateBook->dayView()->moveChild( this, r.x(), r.y()-1 );
552 show();
553}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef DATEBOOKDAY_H
21#define DATEBOOKDAY_H
22
23#include <qpe/event.h>
24
25#include <qdatetime.h>
26#include <qtable.h>
27#include <qvbox.h>
28#include <qlist.h>
29
30class DateBookDayHeader;
31class DateBookDB;
32class QDateTime;
33class QMouseEvent;
34class QPaintEvent;
35class QResizeEvent;
36
37class DateBookDayView : public QTable
38{
39 Q_OBJECT
40public:
41 DateBookDayView( bool hourClock, QWidget *parent, const char *name );
42 bool whichClock() const;
43
44public slots:
45 void moveUp();
46 void moveDown();
47
48signals:
49 void sigColWidthChanged();
50 void sigCapturedKey( const QString &txt );
51protected slots:
52 void slotChangeClock( bool );
53protected:
54 virtual void paintCell( QPainter *p, int row, int col, const QRect &cr, bool selected );
55 virtual void paintFocus( QPainter *p, const QRect &cr );
56 virtual void resizeEvent( QResizeEvent *e );
57 void keyPressEvent( QKeyEvent *e );
58 void initHeader();
59private:
60 bool ampm;
61};
62
63class DateBookDay;
64class DateBookDayWidget : public QWidget
65{
66 Q_OBJECT
67
68public:
69 DateBookDayWidget( const EffectiveEvent &e, DateBookDay *db );
70 ~DateBookDayWidget();
71
72 const QRect &geometry() { return geom; }
73 void setGeometry( const QRect &r );
74
75 const EffectiveEvent &event() const { return ev; }
76
77signals:
78 void deleteMe( const Event &e );
79 void editMe( const Event &e );
80 void beamMe( const Event &e );
81
82protected:
83 void paintEvent( QPaintEvent *e );
84 void mousePressEvent( QMouseEvent *e );
85
86private:
87 const EffectiveEvent ev;
88 DateBookDay *dateBook;
89 QString text;
90 QRect geom;
91};
92
93class DateBookDay : public QVBox
94{
95 Q_OBJECT
96
97public:
98 DateBookDay( bool ampm, bool startOnMonday, DateBookDB *newDb,
99 QWidget *parent, const char *name );
100 void selectedDates( QDateTime &start, QDateTime &end );
101 QDate date() const;
102 DateBookDayView *dayView() const { return view; }
103 void setStartViewTime( int startHere );
104 int startViewTime() const;
105
106public slots:
107 void setDate( int y, int m, int d );
108 void setDate( QDate );
109 void redraw();
110 void slotWeekChanged( bool bStartOnMonday );
111
112signals:
113 void removeEvent( const Event& );
114 void editEvent( const Event& );
115 void beamEvent( const Event& );
116 void newEvent();
117 void sigNewEvent( const QString & );
118
119protected slots:
120 void keyPressEvent(QKeyEvent *);
121
122private slots:
123 void dateChanged( int y, int m, int d );
124 void slotColWidthChanged() { relayoutPage(); };
125
126private:
127 void getEvents();
128 void relayoutPage( bool fromResize = false );
129 DateBookDayWidget *intersects( const DateBookDayWidget *item, const QRect &geom );
130 QDate currDate;
131 DateBookDayView *view;
132 DateBookDayHeader *header;
133 DateBookDB *db;
134 QList<DateBookDayWidget> widgetList;
135 int startTime;
136};
137
138#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 @@
1<!DOCTYPE UI><UI>
2<class>DateBookDayHeaderBase</class>
3<comment>/**********************************************************************
4** Copyright (C) 2001 Trolltech AS. All rights reserved.
5**
6** This file is part of Qtopia Environment.
7**
8** This file may be distributed and/or modified under the terms of the
9** GNU General Public License version 2 as published by the Free Software
10** Foundation and appearing in the file LICENSE.GPL included in the
11** packaging of this file.
12**
13** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
14** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
15**
16** See http://www.trolltech.com/gpl/ for GPL licensing information.
17**
18** Contact info@trolltech.com if any conditions of this licensing are
19** not clear to you.
20**
21** $Id$
22**
23**********************************************************************/</comment>
24<widget>
25 <class>QWidget</class>
26 <property stdset="1">
27 <name>name</name>
28 <cstring>DateBookDayHeaderBase</cstring>
29 </property>
30 <property stdset="1">
31 <name>geometry</name>
32 <rect>
33 <x>0</x>
34 <y>0</y>
35 <width>249</width>
36 <height>26</height>
37 </rect>
38 </property>
39 <property stdset="1">
40 <name>caption</name>
41 <string>Form1</string>
42 </property>
43 <property>
44 <name>layoutMargin</name>
45 </property>
46 <property>
47 <name>layoutSpacing</name>
48 </property>
49 <hbox>
50 <property stdset="1">
51 <name>margin</name>
52 <number>0</number>
53 </property>
54 <property stdset="1">
55 <name>spacing</name>
56 <number>0</number>
57 </property>
58 <widget>
59 <class>QToolButton</class>
60 <property stdset="1">
61 <name>name</name>
62 <cstring>back</cstring>
63 </property>
64 <property stdset="1">
65 <name>text</name>
66 <string></string>
67 </property>
68 <property stdset="1">
69 <name>pixmap</name>
70 <pixmap>image0</pixmap>
71 </property>
72 <property stdset="1">
73 <name>toggleButton</name>
74 <bool>false</bool>
75 </property>
76 <property stdset="1">
77 <name>autoRepeat</name>
78 <bool>true</bool>
79 </property>
80 <property stdset="1">
81 <name>autoRaise</name>
82 <bool>true</bool>
83 </property>
84 <property stdset="1">
85 <name>toggleButton</name>
86 <bool>false</bool>
87 </property>
88 <property>
89 <name>toolTip</name>
90 <string></string>
91 </property>
92 </widget>
93 <widget>
94 <class>QToolButton</class>
95 <property stdset="1">
96 <name>name</name>
97 <cstring>date</cstring>
98 </property>
99 <property stdset="1">
100 <name>sizePolicy</name>
101 <sizepolicy>
102 <hsizetype>7</hsizetype>
103 <vsizetype>1</vsizetype>
104 </sizepolicy>
105 </property>
106 <property stdset="1">
107 <name>font</name>
108 <font>
109 <bold>1</bold>
110 </font>
111 </property>
112 <property stdset="1">
113 <name>text</name>
114 <string></string>
115 </property>
116 <property stdset="1">
117 <name>pixmap</name>
118 <pixmap></pixmap>
119 </property>
120 <property stdset="1">
121 <name>autoRepeat</name>
122 <bool>false</bool>
123 </property>
124 <property stdset="1">
125 <name>autoRaise</name>
126 <bool>false</bool>
127 </property>
128 </widget>
129 <widget>
130 <class>QButtonGroup</class>
131 <property stdset="1">
132 <name>name</name>
133 <cstring>grpDays</cstring>
134 </property>
135 <property stdset="1">
136 <name>frameShape</name>
137 <enum>NoFrame</enum>
138 </property>
139 <property stdset="1">
140 <name>frameShadow</name>
141 <enum>Plain</enum>
142 </property>
143 <property stdset="1">
144 <name>title</name>
145 <string></string>
146 </property>
147 <property stdset="1">
148 <name>exclusive</name>
149 <bool>true</bool>
150 </property>
151 <property>
152 <name>layoutMargin</name>
153 </property>
154 <property>
155 <name>layoutSpacing</name>
156 </property>
157 <hbox>
158 <property stdset="1">
159 <name>margin</name>
160 <number>0</number>
161 </property>
162 <property stdset="1">
163 <name>spacing</name>
164 <number>1</number>
165 </property>
166 <widget>
167 <class>QToolButton</class>
168 <property stdset="1">
169 <name>name</name>
170 <cstring>cmdDay1</cstring>
171 </property>
172 <property stdset="1">
173 <name>text</name>
174 <string>M</string>
175 </property>
176 <property stdset="1">
177 <name>toggleButton</name>
178 <bool>true</bool>
179 </property>
180 <property stdset="1">
181 <name>autoRaise</name>
182 <bool>true</bool>
183 </property>
184 <property stdset="1">
185 <name>toggleButton</name>
186 <bool>true</bool>
187 </property>
188 <property>
189 <name>toolTip</name>
190 <string></string>
191 </property>
192 </widget>
193 <widget>
194 <class>QToolButton</class>
195 <property stdset="1">
196 <name>name</name>
197 <cstring>cmdDay2</cstring>
198 </property>
199 <property stdset="1">
200 <name>text</name>
201 <string>T</string>
202 </property>
203 <property stdset="1">
204 <name>toggleButton</name>
205 <bool>true</bool>
206 </property>
207 <property stdset="1">
208 <name>autoRaise</name>
209 <bool>true</bool>
210 </property>
211 <property stdset="1">
212 <name>toggleButton</name>
213 <bool>true</bool>
214 </property>
215 <property>
216 <name>toolTip</name>
217 <string></string>
218 </property>
219 </widget>
220 <widget>
221 <class>QToolButton</class>
222 <property stdset="1">
223 <name>name</name>
224 <cstring>cmdDay3</cstring>
225 </property>
226 <property stdset="1">
227 <name>text</name>
228 <string>W</string>
229 </property>
230 <property stdset="1">
231 <name>toggleButton</name>
232 <bool>true</bool>
233 </property>
234 <property stdset="1">
235 <name>autoRaise</name>
236 <bool>true</bool>
237 </property>
238 <property stdset="1">
239 <name>toggleButton</name>
240 <bool>true</bool>
241 </property>
242 <property>
243 <name>toolTip</name>
244 <string></string>
245 </property>
246 </widget>
247 <widget>
248 <class>QToolButton</class>
249 <property stdset="1">
250 <name>name</name>
251 <cstring>cmdDay4</cstring>
252 </property>
253 <property stdset="1">
254 <name>text</name>
255 <string>T</string>
256 </property>
257 <property stdset="1">
258 <name>pixmap</name>
259 <pixmap></pixmap>
260 </property>
261 <property stdset="1">
262 <name>toggleButton</name>
263 <bool>true</bool>
264 </property>
265 <property stdset="1">
266 <name>autoRepeat</name>
267 <bool>false</bool>
268 </property>
269 <property stdset="1">
270 <name>autoRaise</name>
271 <bool>true</bool>
272 </property>
273 <property stdset="1">
274 <name>toggleButton</name>
275 <bool>true</bool>
276 </property>
277 <property>
278 <name>toolTip</name>
279 <string></string>
280 </property>
281 </widget>
282 <widget>
283 <class>QToolButton</class>
284 <property stdset="1">
285 <name>name</name>
286 <cstring>cmdDay5</cstring>
287 </property>
288 <property stdset="1">
289 <name>text</name>
290 <string>F</string>
291 </property>
292 <property stdset="1">
293 <name>toggleButton</name>
294 <bool>true</bool>
295 </property>
296 <property stdset="1">
297 <name>autoRaise</name>
298 <bool>true</bool>
299 </property>
300 <property stdset="1">
301 <name>toggleButton</name>
302 <bool>true</bool>
303 </property>
304 <property>
305 <name>toolTip</name>
306 <string></string>
307 </property>
308 </widget>
309 <widget>
310 <class>QToolButton</class>
311 <property stdset="1">
312 <name>name</name>
313 <cstring>cmdDay6</cstring>
314 </property>
315 <property stdset="1">
316 <name>text</name>
317 <string>S</string>
318 </property>
319 <property stdset="1">
320 <name>toggleButton</name>
321 <bool>true</bool>
322 </property>
323 <property stdset="1">
324 <name>autoRaise</name>
325 <bool>true</bool>
326 </property>
327 <property stdset="1">
328 <name>toggleButton</name>
329 <bool>true</bool>
330 </property>
331 <property>
332 <name>toolTip</name>
333 <string></string>
334 </property>
335 </widget>
336 <widget>
337 <class>QToolButton</class>
338 <property stdset="1">
339 <name>name</name>
340 <cstring>cmdDay7</cstring>
341 </property>
342 <property stdset="1">
343 <name>text</name>
344 <string>S</string>
345 </property>
346 <property stdset="1">
347 <name>toggleButton</name>
348 <bool>true</bool>
349 </property>
350 <property stdset="1">
351 <name>autoRaise</name>
352 <bool>true</bool>
353 </property>
354 <property stdset="1">
355 <name>toggleButton</name>
356 <bool>true</bool>
357 </property>
358 <property>
359 <name>toolTip</name>
360 <string></string>
361 </property>
362 </widget>
363 </hbox>
364 </widget>
365 <widget>
366 <class>QToolButton</class>
367 <property stdset="1">
368 <name>name</name>
369 <cstring>forward</cstring>
370 </property>
371 <property stdset="1">
372 <name>text</name>
373 <string></string>
374 </property>
375 <property stdset="1">
376 <name>pixmap</name>
377 <pixmap>image1</pixmap>
378 </property>
379 <property stdset="1">
380 <name>autoRepeat</name>
381 <bool>true</bool>
382 </property>
383 <property stdset="1">
384 <name>autoRaise</name>
385 <bool>true</bool>
386 </property>
387 </widget>
388 </hbox>
389</widget>
390<images>
391 <image>
392 <name>image0</name>
393 <data format="XPM.GZ" length="582">789c6dcfcd4e843010c0f13b4fd1d01b31bb6cb325211b1f41e3d1c4789876a60bcbd7aeae07637c773b6d5985d870e0f7ef50605b88e7a707516cb3f72b5c5b2b6c036fa2c08f61f87c79bdffcaf2dd5ef0558b5d7e97e51b61c5e33412df4b7f2fcbb09896a94ab557817063cd744cad74a915734aac35308740d018d9332d5ab0c8ec1229f2c2448d156a661b489ee1ab4e4cf2a08a790e24020abb0dd355442eec8e914e45526215790c749e8e89891069125de466b1fe14295705ccaa5863e2d05cc01894925b2a7e8217dd8a631eb169fd509af10fd1a9ebfbdf32008d9d0c07cd274f70ee162773ba2cdfee935c977ffe6b2edf87ec07796f81cd</data>
394 </image>
395 <image>
396 <name>image1</name>
397 <data format="XPM.GZ" length="627">789c7dcfc94ec3301006e07b9ec28a6f114a13cbb1a8108f00e28884387819676993340b07847877329ea8697a60ec83bfdf232f8784bdbfbdb0e4104db39e6bcb6ca54796b8afb6fdfef87cfe89e25cb2650ac1f2f8218a5366d96bdf01aef9b2e65928a4458a0c07b25c29890352e63293e19c53a0968f52230159e8c22981744495133552097554a1f982b4ce6aeb9013d215165c81ec894e109b4070ca85378f2b35f18c04050214b20d04d010762ba457003eecd6442f88f34a45f4817ea147762b35d1acf4c47457d784737d9f18ebee1363614bf852c6f812b6c460f90abb6e93ba694ed7c49fdbaeee2f76b83da71ba772e0db5d9ccf4b07dfdd5e858edd9b2948fff9d796fc3e457f660e8d47</data>
398 </image>
399</images>
400<connections>
401 <connection>
402 <sender>forward</sender>
403 <signal>clicked()</signal>
404 <receiver>DateBookDayHeaderBase</receiver>
405 <slot>goForward()</slot>
406 </connection>
407 <connection>
408 <sender>back</sender>
409 <signal>clicked()</signal>
410 <receiver>DateBookDayHeaderBase</receiver>
411 <slot>goBack()</slot>
412 </connection>
413 <connection>
414 <sender>grpDays</sender>
415 <signal>clicked(int)</signal>
416 <receiver>DateBookDayHeaderBase</receiver>
417 <slot>setDay( int )</slot>
418 </connection>
419 <slot access="public">goBack()</slot>
420 <slot access="public">goForward()</slot>
421 <slot access="public">setDate( int, int, int )</slot>
422 <slot access="public">setDay( int )</slot>
423</connections>
424</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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#include "datebookdayheaderimpl.h"
21
22#include <qpe/datebookmonth.h>
23#include <qpe/timestring.h>
24
25#include <qbuttongroup.h>
26#include <qpopupmenu.h>
27#include <qstringlist.h>
28#include <qtimer.h>
29#include <qtoolbutton.h>
30
31/*
32 * Constructs a DateBookDayHeader which is a child of 'parent', with the
33 * name 'name' and widget flags set to 'f'
34 *
35 * The dialog will by default be modeless, unless you set 'modal' to
36 * TRUE to construct a modal dialog.
37 */
38DateBookDayHeader::DateBookDayHeader( bool useMonday,
39 QWidget* parent, const char* name )
40 : DateBookDayHeaderBase( parent, name ),
41 bUseMonday( useMonday )
42{
43 connect(date,SIGNAL(pressed()),this,SLOT(pickDate()));
44
45 setupNames();
46
47 setBackgroundMode( PaletteButton );
48 grpDays->setBackgroundMode( PaletteButton );
49}
50
51/*
52 * Destroys the object and frees any allocated resources
53 */
54DateBookDayHeader::~DateBookDayHeader()
55{
56 // no need to delete child widgets, Qt does it all for us
57}
58
59void DateBookDayHeader::setStartOfWeek( bool onMonday )
60{
61 bUseMonday = onMonday;
62 setupNames();
63 setDate( currDate.year(), currDate.month(), currDate.day() );
64}
65
66void DateBookDayHeader::setupNames()
67{
68 if ( bUseMonday ) {
69 cmdDay1->setText( DateBookDayHeaderBase::tr("Monday").left(1) );
70 cmdDay2->setText( DateBookDayHeaderBase::tr("Tuesday").left(1) );
71 cmdDay3->setText( DateBookDayHeaderBase::tr("Wednesday").left(1) );
72 cmdDay4->setText( DateBookDayHeaderBase::tr("Thursday").left(1) );
73 cmdDay5->setText( DateBookDayHeaderBase::tr("Friday").left(1) );
74 cmdDay6->setText( DateBookDayHeaderBase::tr("Saturday").left(1) );
75 cmdDay7->setText( DateBookDayHeaderBase::tr("Sunday").left(1) );
76 } else {
77 cmdDay1->setText( DateBookDayHeaderBase::tr("Sunday").left(1) );
78 cmdDay2->setText( DateBookDayHeaderBase::tr("Monday").left(1) );
79 cmdDay3->setText( DateBookDayHeaderBase::tr("Tuesday").left(1) );
80 cmdDay4->setText( DateBookDayHeaderBase::tr("Wednesday").left(1) );
81 cmdDay5->setText( DateBookDayHeaderBase::tr("Thursday").left(1) );
82 cmdDay6->setText( DateBookDayHeaderBase::tr("Friday").left(1) );
83 cmdDay7->setText( DateBookDayHeaderBase::tr("Saturday").left(1) );
84 }
85}
86
87
88void DateBookDayHeader::pickDate()
89{
90 static QPopupMenu *m1 = 0;
91 static DateBookMonth *picker = 0;
92 if ( !m1 ) {
93 m1 = new QPopupMenu( this );
94 picker = new DateBookMonth( m1, 0, TRUE );
95 m1->insertItem( picker );
96 connect( picker, SIGNAL( dateClicked( int, int, int ) ),
97 this, SLOT( setDate( int, int, int ) ) );
98 connect( m1, SIGNAL( aboutToHide() ),
99 this, SLOT( gotHide() ) );
100 }
101 picker->setDate( currDate.year(), currDate.month(), currDate.day() );
102 m1->popup(mapToGlobal(date->pos()+QPoint(0,date->height())));
103 picker->setFocus();
104}
105
106void DateBookDayHeader::gotHide()
107{
108 // we have to redo the button...
109 date->setDown( false );
110}
111
112/*
113 * public slot
114 */
115void DateBookDayHeader::goBack()
116{
117 currDate = currDate.addDays( -1 );
118 setDate( currDate.year(), currDate.month(), currDate.day() );
119}
120/*
121 * public slot
122 */
123void DateBookDayHeader::goForward()
124{
125 currDate = currDate.addDays( 1 );
126 setDate( currDate.year(), currDate.month(), currDate.day() );
127}
128
129
130/*
131 * public slot
132 */
133void DateBookDayHeader::setDate( int y, int m, int d )
134{
135 currDate.setYMD( y, m, d );
136 date->setText( TimeString::shortDate( currDate ) );
137
138 int iDayOfWeek = currDate.dayOfWeek();
139 // cleverly adjust the day depending on how we start the week
140 if ( bUseMonday )
141 iDayOfWeek--;
142 else {
143 if ( iDayOfWeek == 7 ) // Sunday
144 iDayOfWeek = 0;
145 }
146 grpDays->setButton( iDayOfWeek );
147 emit dateChanged( y, m, d );
148}
149
150/*
151 * public slot
152 */
153void DateBookDayHeader::setDay( int day )
154{
155 int realDay;
156 int dayOfWeek = currDate.dayOfWeek();
157
158 // a little adjustment is needed...
159 if ( bUseMonday )
160 realDay = day + 1 ;
161 else if ( !bUseMonday && day == 0 ) // sunday
162 realDay = 7;
163 else
164 realDay = day;
165 // special cases first...
166 if ( realDay == 7 && !bUseMonday ) {
167 while ( currDate.dayOfWeek() != realDay )
168 currDate = currDate.addDays( -1 );
169 } else if ( !bUseMonday && dayOfWeek == 7 && dayOfWeek > realDay ) {
170 while ( currDate.dayOfWeek() != realDay )
171 currDate = currDate.addDays( 1 );
172 } else if ( dayOfWeek < realDay ) {
173 while ( currDate.dayOfWeek() < realDay )
174 currDate = currDate.addDays( 1 );
175 } else if ( dayOfWeek > realDay ) {
176 while ( currDate.dayOfWeek() > realDay )
177 currDate = currDate.addDays( -1 );
178 }
179 // update the date...
180 setDate( currDate.year(), currDate.month(), currDate.day() );
181}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef DATEBOOKDAYHEADER_H
21#define DATEBOOKDAYHEADER_H
22#include "datebookdayheader.h"
23
24#include <qdatetime.h>
25
26class DateBookDayHeader : public DateBookDayHeaderBase
27{
28 Q_OBJECT
29
30public:
31 DateBookDayHeader( bool bUseMonday, QWidget* parent = 0,
32 const char* name = 0 );
33 ~DateBookDayHeader();
34 void setStartOfWeek( bool onMonday );
35
36public slots:
37 void goBack();
38 void goForward();
39 void setDate( int, int, int );
40 void setDay( int );
41 void gotHide();
42
43signals:
44 void dateChanged( int y, int m, int d );
45
46private slots:
47 void pickDate();
48
49
50private:
51 QDate currDate;
52 bool bUseMonday;
53 void setupNames();
54
55};
56
57#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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "datebooksettings.h"
22
23#include <qpe/qpeapplication.h>
24
25#include <qspinbox.h>
26#include <qcheckbox.h>
27#include <qcombobox.h>
28
29DateBookSettings::DateBookSettings( bool whichClock, QWidget *parent,
30 const char *name, bool modal, WFlags fl )
31 : DateBookSettingsBase( parent, name, modal, fl ),
32 ampm( whichClock )
33{
34 init();
35 QObject::connect( qApp, SIGNAL( clockChanged( bool ) ),
36 this, SLOT( slotChangeClock( bool ) ) );
37}
38
39DateBookSettings::~DateBookSettings()
40{
41}
42
43void DateBookSettings::setStartTime( int newStartViewTime )
44{
45 if ( ampm ) {
46 if ( newStartViewTime >= 12 ) {
47 newStartViewTime %= 12;
48 if ( newStartViewTime == 0 )
49 newStartViewTime = 12;
50 spinStart->setSuffix( tr(":00 PM") );
51 }
52 else if ( newStartViewTime == 0 ) {
53 newStartViewTime = 12;
54 spinStart->setSuffix( tr(":00 AM") );
55 }
56 oldtime = newStartViewTime;
57 }
58 spinStart->setValue( newStartViewTime );
59}
60
61int DateBookSettings::startTime() const
62{
63 int returnMe = spinStart->value();
64 if ( ampm ) {
65 if ( returnMe != 12 && spinStart->suffix().contains(tr("PM"), FALSE) )
66 returnMe += 12;
67 else if (returnMe == 12 && spinStart->suffix().contains(tr("AM"), TRUE))
68 returnMe = 0;
69 }
70 return returnMe;
71}
72
73
74void DateBookSettings::setAlarmPreset( bool bAlarm, int presetTime )
75{
76 chkAlarmPreset->setChecked( bAlarm );
77 if ( presetTime >=5 )
78 spinPreset->setValue( presetTime );
79}
80
81bool DateBookSettings::alarmPreset() const
82{
83 return chkAlarmPreset->isChecked();
84}
85
86int DateBookSettings::presetTime() const
87{
88 return spinPreset->value();
89}
90
91
92void DateBookSettings::slot12Hour( int i )
93{
94 if ( ampm ) {
95 if ( spinStart->suffix().contains( tr("AM"), FALSE ) ) {
96 if ( oldtime == 12 && i == 11 || oldtime == 11 && i == 12 )
97 spinStart->setSuffix( tr(":00 PM") );
98 } else {
99 if ( oldtime == 12 && i == 11 || oldtime == 11 && i == 12 )
100 spinStart->setSuffix( tr(":00 AM") );
101 }
102 oldtime = i;
103 }
104}
105
106void DateBookSettings::init()
107{
108 if ( ampm ) {
109 spinStart->setMinValue( 1 );
110 spinStart->setMaxValue( 12 );
111 spinStart->setValue( 12 );
112 spinStart->setSuffix( tr(":00 AM") );
113 oldtime = 12;
114 } else {
115 spinStart->setMinValue( 0 );
116 spinStart->setMaxValue( 23 );
117 spinStart->setSuffix( tr(":00") );
118 }
119}
120
121void DateBookSettings::slotChangeClock( bool whichClock )
122{
123 int saveMe;
124 saveMe = spinStart->value();
125 if ( ampm && spinStart->suffix().contains( tr("AM"), FALSE ) ) {
126 if ( saveMe == 12 )
127 saveMe = 0;
128 } else if ( ampm && spinStart->suffix().contains( tr("PM"), FALSE ) ) {
129 if ( saveMe != 12 )
130 saveMe += 12;
131 }
132 ampm = whichClock;
133 init();
134 setStartTime( saveMe );
135}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#ifndef DATEBOOKSETTINGS_H
22#define DATEBOOKSETTINGS_H
23#include "datebooksettingsbase.h"
24
25class DateBookSettings : public DateBookSettingsBase
26{
27public:
28 DateBookSettings( bool whichClock, QWidget *parent = 0,
29 const char *name = 0, bool modal = TRUE, WFlags = 0 );
30 ~DateBookSettings();
31 void setStartTime( int newStartViewTime );
32 int startTime() const;
33 void setAlarmPreset( bool bAlarm, int presetTime );
34 bool alarmPreset() const;
35 int presetTime() const;
36 void setAlarmType( int alarmType );
37 int alarmType() const;
38
39private slots:
40 void slot12Hour( int );
41 void slotChangeClock( bool );
42
43private:
44 void init();
45 bool ampm;
46 int oldtime;
47};
48#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 @@
1<!DOCTYPE UI><UI>
2<class>DateBookSettingsBase</class>
3<comment>**********************************************************************
4** Copyright (C) 2000 Trolltech AS. All rights reserved.
5**
6** This file is part of Qtopia Environment.
7**
8** This file may be distributed and/or modified under the terms of the
9** GNU General Public License version 2 as published by the Free Software
10** Foundation and appearing in the file LICENSE.GPL included in the
11** packaging of this file.
12**
13** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
14** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
15**
16** See http://www.trolltech.com/gpl/ for GPL licensing information.
17**
18** Contact info@trolltech.com if any conditions of this licensing are
19** not clear to you.
20**
21** $Id$
22**
23**********************************************************************</comment>
24<widget>
25 <class>QDialog</class>
26 <property stdset="1">
27 <name>name</name>
28 <cstring>DateBookSettingsBase</cstring>
29 </property>
30 <property stdset="1">
31 <name>geometry</name>
32 <rect>
33 <x>0</x>
34 <y>0</y>
35 <width>232</width>
36 <height>290</height>
37 </rect>
38 </property>
39 <property stdset="1">
40 <name>caption</name>
41 <string>Preferences</string>
42 </property>
43 <property>
44 <name>layoutMargin</name>
45 </property>
46 <property>
47 <name>layoutSpacing</name>
48 </property>
49 <vbox>
50 <property stdset="1">
51 <name>margin</name>
52 <number>5</number>
53 </property>
54 <property stdset="1">
55 <name>spacing</name>
56 <number>1</number>
57 </property>
58 <widget>
59 <class>QGroupBox</class>
60 <property stdset="1">
61 <name>name</name>
62 <cstring>fraStart</cstring>
63 </property>
64 <property stdset="1">
65 <name>frameShape</name>
66 <enum>Box</enum>
67 </property>
68 <property stdset="1">
69 <name>frameShadow</name>
70 <enum>Sunken</enum>
71 </property>
72 <property stdset="1">
73 <name>title</name>
74 <string>Start viewing events</string>
75 </property>
76 <vbox>
77 <property stdset="1">
78 <name>margin</name>
79 <number>11</number>
80 </property>
81 <property stdset="1">
82 <name>spacing</name>
83 <number>6</number>
84 </property>
85 <widget>
86 <class>QLayoutWidget</class>
87 <property stdset="1">
88 <name>name</name>
89 <cstring>Layout1</cstring>
90 </property>
91 <hbox>
92 <property stdset="1">
93 <name>margin</name>
94 <number>0</number>
95 </property>
96 <property stdset="1">
97 <name>spacing</name>
98 <number>6</number>
99 </property>
100 <widget>
101 <class>QLabel</class>
102 <property stdset="1">
103 <name>name</name>
104 <cstring>lblStartTime</cstring>
105 </property>
106 <property stdset="1">
107 <name>text</name>
108 <string>Start Time:</string>
109 </property>
110 </widget>
111 <widget>
112 <class>QSpinBox</class>
113 <property stdset="1">
114 <name>name</name>
115 <cstring>spinStart</cstring>
116 </property>
117 <property stdset="1">
118 <name>suffix</name>
119 <string>:00</string>
120 </property>
121 <property stdset="1">
122 <name>wrapping</name>
123 <bool>true</bool>
124 </property>
125 <property stdset="1">
126 <name>maxValue</name>
127 <number>23</number>
128 </property>
129 </widget>
130 </hbox>
131 </widget>
132 </vbox>
133 </widget>
134 <widget>
135 <class>QGroupBox</class>
136 <property stdset="1">
137 <name>name</name>
138 <cstring>fraAlarm</cstring>
139 </property>
140 <property stdset="1">
141 <name>title</name>
142 <string>Alarm Settings</string>
143 </property>
144 <vbox>
145 <property stdset="1">
146 <name>margin</name>
147 <number>11</number>
148 </property>
149 <property stdset="1">
150 <name>spacing</name>
151 <number>6</number>
152 </property>
153 <widget>
154 <class>QLayoutWidget</class>
155 <property stdset="1">
156 <name>name</name>
157 <cstring>Layout6</cstring>
158 </property>
159 <hbox>
160 <property stdset="1">
161 <name>margin</name>
162 <number>0</number>
163 </property>
164 <property stdset="1">
165 <name>spacing</name>
166 <number>6</number>
167 </property>
168 <widget>
169 <class>QCheckBox</class>
170 <property stdset="1">
171 <name>name</name>
172 <cstring>chkAlarmPreset</cstring>
173 </property>
174 <property stdset="1">
175 <name>text</name>
176 <string>Alarm Preset</string>
177 </property>
178 </widget>
179 <widget>
180 <class>QSpinBox</class>
181 <property stdset="1">
182 <name>name</name>
183 <cstring>spinPreset</cstring>
184 </property>
185 <property stdset="1">
186 <name>enabled</name>
187 <bool>false</bool>
188 </property>
189 <property stdset="1">
190 <name>suffix</name>
191 <string> minutes</string>
192 </property>
193 <property stdset="1">
194 <name>maxValue</name>
195 <number>180</number>
196 </property>
197 <property stdset="1">
198 <name>minValue</name>
199 <number>0</number>
200 </property>
201 <property stdset="1">
202 <name>lineStep</name>
203 <number>5</number>
204 </property>
205 <property stdset="1">
206 <name>value</name>
207 <number>5</number>
208 </property>
209 </widget>
210 </hbox>
211 </widget>
212 </vbox>
213 </widget>
214 </vbox>
215</widget>
216<connections>
217 <connection>
218 <sender>chkAlarmPreset</sender>
219 <signal>toggled(bool)</signal>
220 <receiver>spinPreset</receiver>
221 <slot>setEnabled(bool)</slot>
222 </connection>
223 <connection>
224 <sender>spinStart</sender>
225 <signal>valueChanged(int)</signal>
226 <receiver>DateBookSettingsBase</receiver>
227 <slot>slot12Hour( int )</slot>
228 </connection>
229 <slot access="public">slotChangeClock( bool )</slot>
230 <slot access="public">slot12Hour( int )</slot>
231</connections>
232</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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#include "datebookweek.h"
21#include "datebookweekheaderimpl.h"
22
23#include <qpe/calendar.h>
24#include <qpe/datebookdb.h>
25#include <qpe/event.h>
26#include <qpe/qpeapplication.h>
27#include <qpe/timestring.h>
28
29#include <qdatetime.h>
30#include <qheader.h>
31#include <qlabel.h>
32#include <qlayout.h>
33#include <qpainter.h>
34#include <qpopupmenu.h>
35#include <qtimer.h>
36#include <qspinbox.h>
37#include <qstyle.h>
38
39//-----------------------------------------------------------------
40
41
42DateBookWeekItem::DateBookWeekItem( const EffectiveEvent e )
43 : ev( e )
44{
45 // with the current implementation change the color for all day events
46 if ( ev.event().type() == Event::AllDay && !ev.event().hasAlarm() ) {
47 c = Qt::green;
48 } else {
49 c = ev.event().hasAlarm() ? Qt::red : Qt::blue;
50 }
51}
52
53void DateBookWeekItem::setGeometry( int x, int y, int w, int h )
54{
55 r.setRect( x, y, w, h );
56}
57
58
59//------------------=---------------------------------------------
60
61DateBookWeekView::DateBookWeekView( bool ap, bool startOnMonday,
62 QWidget *parent, const char *name )
63 : QScrollView( parent, name ), ampm( ap ), bOnMonday( startOnMonday ),
64 showingEvent( false )
65{
66 items.setAutoDelete( true );
67
68 viewport()->setBackgroundMode( PaletteBase );
69
70 header = new QHeader( this );
71 header->addLabel( "" );
72
73 header->setMovingEnabled( false );
74 header->setResizeEnabled( false );
75 header->setClickEnabled( false, 0 );
76 initNames();
77
78
79 connect( header, SIGNAL(clicked(int)), this, SIGNAL(showDay(int)) );
80
81 QObject::connect(qApp, SIGNAL(clockChanged(bool)),
82 this, SLOT(slotChangeClock(bool)));
83
84 QFontMetrics fm( font() );
85 rowHeight = fm.height()+2;
86
87 resizeContents( width(), 24*rowHeight );
88}
89
90void DateBookWeekView::initNames()
91{
92 static bool bFirst = true;
93 if ( bFirst ) {
94 if ( bOnMonday ) {
95 header->addLabel( tr("M", "Monday" ) );
96 header->addLabel( tr("T", "Tuesday") );
97 header->addLabel( tr("W", "Wednesday" ) );
98 header->addLabel( tr("T", "Thursday" ) );
99 header->addLabel( tr("F", "Friday" ) );
100 header->addLabel( tr("S", "Saturday" ) );
101 header->addLabel( tr("S", "Sunday" ) );
102 } else {
103 header->addLabel( tr("S", "Sunday" ) );
104 header->addLabel( tr("M", "Monday") );
105 header->addLabel( tr("T", "Tuesday") );
106 header->addLabel( tr("W", "Wednesday" ) );
107 header->addLabel( tr("T", "Thursday" ) );
108 header->addLabel( tr("F", "Friday" ) );
109 header->addLabel( tr("S", "Saturday" ) );
110 }
111 bFirst = false;
112 } else {
113 // we are change things...
114 if ( bOnMonday ) {
115 header->setLabel( 1, tr("M", "Monday") );
116 header->setLabel( 2, tr("T", "Tuesday") );
117 header->setLabel( 3, tr("W", "Wednesday" ) );
118 header->setLabel( 4, tr("T", "Thursday" ) );
119 header->setLabel( 5, tr("F", "Friday" ) );
120 header->setLabel( 6, tr("S", "Saturday" ) );
121 header->setLabel( 7, tr("S", "Sunday" ) );
122 } else {
123 header->setLabel( 1, tr("S", "Sunday" ) );
124 header->setLabel( 2, tr("M", "Monday") );
125 header->setLabel( 3, tr("T", "Tuesday") );
126 header->setLabel( 4, tr("W", "Wednesday" ) );
127 header->setLabel( 5, tr("T", "Thursday" ) );
128 header->setLabel( 6, tr("F", "Friday" ) );
129 header->setLabel( 7, tr("S", "Saturday" ) );
130 }
131 }
132}
133
134
135
136void DateBookWeekView::showEvents( QValueList<EffectiveEvent> &ev )
137{
138 items.clear();
139 QValueListIterator<EffectiveEvent> it;
140 for ( it = ev.begin(); it != ev.end(); ++it ) {
141 DateBookWeekItem *i = new DateBookWeekItem( *it );
142 positionItem( i );
143 items.append( i );
144 }
145 viewport()->update();
146}
147
148void DateBookWeekView::moveToHour( int h )
149{
150 int offset = h*rowHeight;
151 setContentsPos( 0, offset );
152}
153
154void DateBookWeekView::keyPressEvent( QKeyEvent *e )
155{
156 e->ignore();
157}
158
159void DateBookWeekView::slotChangeClock( bool c )
160{
161 ampm = c;
162 viewport()->update();
163}
164
165static inline int db_round30min( int m )
166{
167 if ( m < 15 )
168 m = 0;
169 else if ( m < 45 )
170 m = 1;
171 else
172 m = 2;
173
174 return m;
175}
176
177void DateBookWeekView::alterDay( int day )
178{
179 if ( !bOnMonday ) {
180 day--;
181 }
182 emit showDay( day );
183}
184
185void DateBookWeekView::positionItem( DateBookWeekItem *i )
186{
187 const int Width = 8;
188 const EffectiveEvent ev = i->event();
189
190 // 30 minute intervals
191 int y = ev.start().hour() * 2;
192 y += db_round30min( ev.start().minute() );
193 if ( y > 47 )
194 y = 47;
195 y = y * rowHeight / 2;
196
197 int h;
198 if ( ev.event().type() == Event::AllDay ) {
199 h = 48;
200 y = 0;
201 } else {
202 h = ( ev.end().hour() - ev.start().hour() ) * 2;
203 h += db_round30min( ev.end().minute() - ev.start().minute() );
204 if ( h < 1 ) h = 1;
205 }
206 h = h * rowHeight / 2;
207
208 int dow = ev.date().dayOfWeek();
209 if ( !bOnMonday ) {
210 if ( dow == 7 )
211 dow = 1;
212 else
213 dow++;
214 }
215 int x = header->sectionPos( dow ) - 1;
216 int xlim = header->sectionPos( dow ) + header->sectionSize( dow );
217 DateBookWeekItem *isect = 0;
218 do {
219 i->setGeometry( x, y, Width, h );
220 isect = intersects( i );
221 x += Width - 1;
222 } while ( isect && x < xlim );
223}
224
225DateBookWeekItem *DateBookWeekView::intersects( const DateBookWeekItem *item )
226{
227 QRect geom = item->geometry();
228
229 // We allow the edges to overlap
230 geom.moveBy( 1, 1 );
231 geom.setSize( geom.size()-QSize(2,2) );
232
233 QListIterator<DateBookWeekItem> it(items);
234 for ( ; it.current(); ++it ) {
235 DateBookWeekItem *i = it.current();
236 if ( i != item ) {
237 if ( i->geometry().intersects( geom ) ) {
238 return i;
239 }
240 }
241 }
242
243 return 0;
244}
245
246void DateBookWeekView::contentsMousePressEvent( QMouseEvent *e )
247{
248 QListIterator<DateBookWeekItem> it(items);
249 for ( ; it.current(); ++it ) {
250 DateBookWeekItem *i = it.current();
251 if ( i->geometry().contains( e->pos() ) ) {
252 showingEvent = true;
253 emit signalShowEvent( i->event() );
254 break;
255 }
256 }
257}
258
259void DateBookWeekView::contentsMouseReleaseEvent( QMouseEvent *e )
260{
261 if ( showingEvent ) {
262 showingEvent = false;
263 emit signalHideEvent();
264 } else {
265 int d = header->sectionAt( e->pos().x() );
266 if ( d > 0 ) {
267 // if ( !bOnMonday )
268 // d--;
269 emit showDay( d );
270 }
271 }
272}
273
274void DateBookWeekView::drawContents( QPainter *p, int cx, int cy, int cw, int ch )
275{
276 QRect ur( cx, cy, cw, ch );
277 p->setPen( lightGray );
278 for ( int i = 1; i <= 7; i++ )
279 p->drawLine( header->sectionPos(i)-2, cy, header->sectionPos(i)-2, cy+ch );
280
281 p->setPen( black );
282 for ( int t = 0; t < 24; t++ ) {
283 int y = t*rowHeight;
284 if ( QRect( 1, y, 20, rowHeight ).intersects( ur ) ) {
285 QString s;
286 if ( ampm ) {
287 if ( t == 0 )
288 s = QString::number( 12 );
289 else if ( t == 12 )
290 s = QString::number(12) + tr( "p" );
291 else if ( t > 12 ) {
292 if ( t - 12 < 10 )
293 s = " ";
294 else
295 s = "";
296 s += QString::number( t - 12 ) + tr("p");
297 } else {
298 if ( 12 - t < 3 )
299 s = "";
300 else
301 s = " ";
302 s += QString::number( t );
303 }
304 } else {
305 s = QString::number( t );
306 if ( s.length() == 1 )
307 s.prepend( "0" );
308 }
309 p->drawText( 1, y+p->fontMetrics().ascent()+1, s );
310 }
311 }
312
313 QListIterator<DateBookWeekItem> it(items);
314 for ( ; it.current(); ++it ) {
315 DateBookWeekItem *i = it.current();
316 if ( i->geometry().intersects( ur ) ) {
317 p->setBrush( i->color() );
318 p->drawRect( i->geometry() );
319 }
320 }
321}
322
323void DateBookWeekView::resizeEvent( QResizeEvent *e )
324{
325 const int hourWidth = 20;
326 QScrollView::resizeEvent( e );
327 int avail = width()-qApp->style().scrollBarExtent().width()-1;
328 header->setGeometry( 0, 0, avail, header->sizeHint().height() );
329 setMargins( 0, header->height(), 0, 0 );
330 header->resizeSection( 0, hourWidth );
331 int sw = (avail - hourWidth) / 7;
332 for ( int i = 1; i < 7; i++ )
333 header->resizeSection( i, sw );
334 header->resizeSection( 7, avail - hourWidth - sw*6 );
335}
336
337void DateBookWeekView::setStartOfWeek( bool bStartOnMonday )
338{
339 bOnMonday = bStartOnMonday;
340 initNames();
341}
342
343//-------------------------------------------------------------------
344
345DateBookWeek::DateBookWeek( bool ap, bool startOnMonday, DateBookDB *newDB,
346 QWidget *parent, const char *name )
347 : QWidget( parent, name ),
348 db( newDB ),
349 startTime( 0 ),
350 ampm( ap ),
351 bStartOnMonday( startOnMonday )
352{
353 setFocusPolicy(StrongFocus);
354 QVBoxLayout *vb = new QVBoxLayout( this );
355 header = new DateBookWeekHeader( bStartOnMonday, this );
356 view = new DateBookWeekView( ampm, startOnMonday, this );
357 vb->addWidget( header );
358 vb->addWidget( view );
359
360 lblDesc = new QLabel( this, "event label" );
361 lblDesc->setFrameStyle( QFrame::Plain | QFrame::Box );
362 lblDesc->setBackgroundColor( yellow );
363 lblDesc->hide();
364
365 tHide = new QTimer( this );
366
367 connect( view, SIGNAL( showDay( int ) ),
368 this, SLOT( showDay( int ) ) );
369 connect( view, SIGNAL(signalShowEvent(const EffectiveEvent&)),
370 this, SLOT(slotShowEvent(const EffectiveEvent&)) );
371 connect( view, SIGNAL(signalHideEvent()),
372 this, SLOT(slotHideEvent()) );
373 connect( header, SIGNAL( dateChanged( int, int ) ),
374 this, SLOT( dateChanged( int, int ) ) );
375 connect( tHide, SIGNAL( timeout() ),
376 lblDesc, SLOT( hide() ) );
377 connect( header->spinYear, SIGNAL(valueChanged(int)),
378 this, SLOT(slotYearChanged(int)) );
379 connect( qApp, SIGNAL(weekChanged(bool)),
380 this, SLOT(slotWeekChanged(bool)) );
381 connect( qApp, SIGNAL(clockChanged(bool)),
382 this, SLOT(slotClockChanged(bool)));
383 setDate(QDate::currentDate());
384
385}
386
387void DateBookWeek::keyPressEvent(QKeyEvent *e)
388{
389 switch(e->key()) {
390 case Key_Up:
391 view->scrollBy(0, -20);
392 break;
393 case Key_Down:
394 view->scrollBy(0, 20);
395 break;
396 case Key_Left:
397 setDate(date().addDays(-7));
398 break;
399 case Key_Right:
400 setDate(date().addDays(7));
401 break;
402 default:
403 e->ignore();
404 }
405}
406
407void DateBookWeek::showDay( int day )
408{
409 QDate d;
410 d = dateFromWeek( _week, year, bStartOnMonday );
411 day--;
412 d = d.addDays( day );
413 emit showDate( d.year(), d.month(), d.day() );
414}
415
416void DateBookWeek::setDate( int y, int m, int d )
417{
418 QDate date;
419 date.setYMD( y, m, d );
420 setDate(QDate(y, m, d));
421}
422
423void DateBookWeek::setDate(QDate date)
424{
425 dow = date.dayOfWeek();
426 int w, y;
427 calcWeek( date, w, y, bStartOnMonday );
428 header->setDate( y, w );
429}
430
431void DateBookWeek::dateChanged( int y, int w )
432{
433 year = y;
434 _week = w;
435 getEvents();
436}
437
438QDate DateBookWeek::date() const
439{
440 QDate d;
441 d = dateFromWeek( _week - 1, year, bStartOnMonday );
442 if ( bStartOnMonday )
443 d = d.addDays( 7 + dow - 1 );
444 else {
445 if ( dow == 7 )
446 d = d.addDays( dow );
447 else
448 d = d.addDays( 7 + dow );
449 }
450 return d;
451}
452
453void DateBookWeek::getEvents()
454{
455 QDate startWeek = weekDate();
456
457 QDate endWeek = startWeek.addDays( 6 );
458 QValueList<EffectiveEvent> eventList = db->getEffectiveEvents(startWeek,
459 endWeek);
460 view->showEvents( eventList );
461 view->moveToHour( startTime );
462}
463
464void DateBookWeek::slotShowEvent( const EffectiveEvent &ev )
465{
466 if ( tHide->isActive() )
467 tHide->stop();
468
469 // why would someone use "<"? Oh well, fix it up...
470 // I wonder what other things may be messed up...
471 QString strDesc = ev.description();
472 int where = strDesc.find( "<" );
473 while ( where != -1 ) {
474 strDesc.remove( where, 1 );
475 strDesc.insert( where, "&#60;" );
476 where = strDesc.find( "<", where );
477 }
478
479 QString strCat;
480 // ### FIX later...
481// QString strCat = ev.category();
482// where = strCat.find( "<" );
483// while ( where != -1 ) {
484 // strCat.remove( where, 1 );
485 // strCat.insert( where, "&#60;" );
486 // where = strCat.find( "<", where );
487// }
488
489 QString strNote = ev.notes();
490 where = strNote.find( "<" );
491 while ( where != -1 ) {
492 strNote.remove( where, 1 );
493 strNote.insert( where, "&#60;" );
494 where = strNote.find( "<", where );
495 }
496
497 QString str = "<b>" + strDesc + "</b><br>" + "<i>"
498 + strCat + "</i>"
499 + "<br>" + TimeString::longDateString( ev.date() )
500 + "<br><b>" + QObject::tr("Start") + "</b>: ";
501
502 if ( ev.startDate() != ev.date() ) {
503 // multi-day event. Show start date
504 str += TimeString::longDateString( ev.startDate() );
505 } else {
506 // Show start time.
507 str += TimeString::timeString(ev.start(), ampm, FALSE );
508 }
509
510 str += "<br><b>" + QObject::tr("End") + "</b>: ";
511 if ( ev.endDate() != ev.date() ) {
512 // multi-day event. Show end date
513 str += TimeString::longDateString( ev.endDate() );
514 } else {
515 // Show end time.
516 str += TimeString::timeString( ev.end(), ampm, FALSE );
517 }
518 str += "<br><br>" + strNote;
519
520 lblDesc->setText( str );
521 lblDesc->resize( lblDesc->sizeHint() );
522 // move the label so it is "centerd" horizontally...
523 lblDesc->move( QMAX(0,(width() - lblDesc->width()) / 2), 0 );
524 lblDesc->show();
525}
526
527void DateBookWeek::slotHideEvent()
528{
529 tHide->start( 2000, true );
530}
531
532void DateBookWeek::setStartViewTime( int startHere )
533{
534 startTime = startHere;
535 view->moveToHour( startTime );
536}
537
538int DateBookWeek::startViewTime() const
539{
540 return startTime;
541}
542
543void DateBookWeek::redraw()
544{
545 getEvents();
546}
547
548void DateBookWeek::slotYearChanged( int y )
549{
550 int totWeek;
551 QDate d( y, 12, 31 );
552 int throwAway;
553 calcWeek( d, totWeek, throwAway, bStartOnMonday );
554 while ( totWeek == 1 ) {
555 d = d.addDays( -1 );
556 calcWeek( d, totWeek, throwAway, bStartOnMonday );
557 }
558 if ( totWeek != totalWeeks() )
559 setTotalWeeks( totWeek );
560}
561
562
563void DateBookWeek::setTotalWeeks( int numWeeks )
564{
565 header->spinWeek->setMaxValue( numWeeks );
566}
567
568int DateBookWeek::totalWeeks() const
569{
570 return header->spinWeek->maxValue();
571}
572
573void DateBookWeek::slotWeekChanged( bool onMonday )
574{
575 bStartOnMonday = onMonday;
576 view->setStartOfWeek( bStartOnMonday );
577 header->setStartOfWeek( bStartOnMonday );
578 redraw();
579}
580
581void DateBookWeek::slotClockChanged( bool ap )
582{
583 ampm = ap;
584}
585
586// return the date at the beginning of the week...
587QDate DateBookWeek::weekDate() const
588{
589 return dateFromWeek( _week, year, bStartOnMonday );
590}
591
592// this used to only be needed by datebook.cpp, but now we need it inside
593// week view since
594// we need to be able to figure out our total number of weeks on the fly...
595// this is probably the best place to put it..
596
597// For Weeks that start on Monday... (EASY!)
598// At the moment we will use ISO 8601 method for computing
599// the week. Granted, other countries use other methods,
600// bet we aren't doing any Locale stuff at the moment. So,
601// this should pass. This Algorithim is public domain and
602// available at:
603// http://personal.ecu.edu/mccartyr/ISOwdALG.txt
604// the week number is return, and the year number is returned in year
605// for Instance 2001/12/31 is actually the first week in 2002.
606// There is a more mathematical definition, but I will implement it when
607// we are pass our deadline.
608
609// For Weeks that start on Sunday... (ahh... home rolled)
610// okay, if Jan 1 is on Friday or Saturday,
611// it will go to the pervious
612// week...
613
614bool calcWeek( const QDate &d, int &week, int &year,
615 bool startOnMonday = false )
616{
617 int weekNumber;
618 int yearNumber;
619
620 // remove a pesky warning, (Optimizations on g++)
621 weekNumber = -1;
622 int jan1WeekDay = QDate(d.year(), 1, 1).dayOfWeek();
623 int dayOfWeek = d.dayOfWeek();
624
625 if ( !d.isValid() )
626 return false;
627
628 if ( startOnMonday ) {
629 // find the Jan1Weekday;
630 if ( d.dayOfYear() <= ( 8 - jan1WeekDay) && jan1WeekDay > 4 ) {
631 yearNumber = d.year() - 1;
632 if ( jan1WeekDay == 5 || ( jan1WeekDay == 6 && QDate::leapYear(yearNumber) ) )
633 weekNumber = 53;
634 else
635 weekNumber = 52;
636 } else
637 yearNumber = d.year();
638 if ( yearNumber == d.year() ) {
639 int totalDays = 365;
640 if ( QDate::leapYear(yearNumber) )
641 totalDays++;
642 if ( ((totalDays - d.dayOfYear()) < (4 - dayOfWeek) )
643 || (jan1WeekDay == 7) && (totalDays - d.dayOfYear()) < 3) {
644 yearNumber++;
645 weekNumber = 1;
646 }
647 }
648 if ( yearNumber == d.year() ) {
649 int j = d.dayOfYear() + (7 - dayOfWeek) + ( jan1WeekDay - 1 );
650 weekNumber = j / 7;
651 if ( jan1WeekDay > 4 )
652 weekNumber--;
653 }
654 } else {
655 // it's better to keep these cases separate...
656 if ( d.dayOfYear() <= (7 - jan1WeekDay) && jan1WeekDay > 4
657 && jan1WeekDay != 7 ) {
658 yearNumber = d.year() - 1;
659 if ( jan1WeekDay == 6
660 || (jan1WeekDay == 7 && QDate::leapYear(yearNumber) ) ) {
661 weekNumber = 53;
662 }else
663 weekNumber = 52;
664 } else
665 yearNumber = d.year();
666 if ( yearNumber == d.year() ) {
667 int totalDays = 365;
668 if ( QDate::leapYear( yearNumber ) )
669 totalDays++;
670 if ( ((totalDays - d.dayOfYear()) < (4 - dayOfWeek % 7)) ) {
671 yearNumber++;
672 weekNumber = 1;
673 }
674 }
675 if ( yearNumber == d.year() ) {
676 int j = d.dayOfYear() + (7 - dayOfWeek % 7) + ( jan1WeekDay - 1 );
677 weekNumber = j / 7;
678 if ( jan1WeekDay > 4 ) {
679 weekNumber--;
680 }
681 }
682 }
683 year = yearNumber;
684 week = weekNumber;
685 return true;
686}
687
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef DATEBOOKWEEK
21#define DATEBOOKWEEK
22
23#include <qpe/event.h>
24
25#include <qlist.h>
26#include <qscrollview.h>
27#include <qstring.h>
28#include <qvaluelist.h>
29
30class DateBookDB;
31class DateBookWeekHeader;
32class QDate;
33class QLabel;
34class QResizeEvent;
35class QSpinBox;
36class QTimer;
37class QHeader;
38
39class DateBookWeekItem
40{
41public:
42 DateBookWeekItem( const EffectiveEvent e );
43
44 void setGeometry( int x, int y, int w, int h );
45 QRect geometry() const { return r; }
46
47 const QColor &color() const { return c; }
48 const EffectiveEvent event() const { return ev; }
49
50private:
51 const EffectiveEvent ev;
52 QRect r;
53 QColor c;
54};
55
56class DateBookWeekView : public QScrollView
57{
58 Q_OBJECT
59public:
60 DateBookWeekView( bool ampm, bool weekOnMonday, QWidget *parent = 0,
61 const char *name = 0 );
62
63 bool whichClock() const;
64 void showEvents( QValueList<EffectiveEvent> &ev );
65 void moveToHour( int h );
66 void setStartOfWeek( bool bOnMonday );
67
68signals:
69 void showDay( int d );
70 void signalShowEvent( const EffectiveEvent & );
71 void signalHideEvent();
72
73protected slots:
74 void keyPressEvent(QKeyEvent *);
75
76private slots:
77 void slotChangeClock( bool );
78 void alterDay( int );
79
80private:
81 void positionItem( DateBookWeekItem *i );
82 DateBookWeekItem *intersects( const DateBookWeekItem * );
83 void drawContents( QPainter *p, int cx, int cy, int cw, int ch );
84 void contentsMousePressEvent( QMouseEvent * );
85 void contentsMouseReleaseEvent( QMouseEvent * );
86 void resizeEvent( QResizeEvent * );
87 void initNames();
88
89private:
90 bool ampm;
91 bool bOnMonday;
92 QHeader *header;
93 QList<DateBookWeekItem> items;
94 int rowHeight;
95 bool showingEvent;
96};
97
98class DateBookWeek : public QWidget
99{
100 Q_OBJECT
101
102public:
103 DateBookWeek( bool ampm, bool weekOnMonday, DateBookDB *newDB,
104 QWidget *parent = 0, const char *name = 0 );
105 void setDate( int y, int m, int d );
106 void setDate( QDate d );
107 QDate date() const;
108 DateBookWeekView *weekView() const { return view; }
109 void setStartViewTime( int startHere );
110 int startViewTime() const;
111 int week() const { return _week; };
112 void setTotalWeeks( int totalWeeks );
113 int totalWeeks() const;
114 QDate weekDate() const;
115
116public slots:
117 void redraw();
118 void slotWeekChanged( bool bStartOnMonday );
119 void slotClockChanged( bool a );
120
121signals:
122 void showDate( int y, int m, int d );
123
124protected slots:
125 void keyPressEvent(QKeyEvent *);
126
127private slots:
128 void showDay( int day );
129 void dateChanged( int y, int w );
130 void slotShowEvent( const EffectiveEvent & );
131 void slotHideEvent();
132 void slotYearChanged( int );
133
134private:
135 void getEvents();
136 int year;
137 int _week;
138 int dow;
139 DateBookWeekHeader *header;
140 DateBookWeekView *view;
141 DateBookDB *db;
142 QLabel *lblDesc;
143 QTimer *tHide;
144 int startTime;
145 bool ampm;
146 bool bStartOnMonday;
147};
148
149
150bool calcWeek( const QDate &d, int &week, int &year,
151 bool startOnMonday = false );
152#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 @@
1<!DOCTYPE UI><UI>
2<class>DateBookWeekHeaderBase</class>
3<comment>*********************************************************************
4** Copyright (C) 2000 Trolltech AS. All rights reserved.
5**
6** This file is part of Qtopia Environment.
7**
8** This file may be distributed and/or modified under the terms of the
9** GNU General Public License version 2 as published by the Free Software
10** Foundation and appearing in the file LICENSE.GPL included in the
11** packaging of this file.
12**
13** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
14** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
15**
16** See http://www.trolltech.com/gpl/ for GPL licensing information.
17**
18** Contact info@trolltech.com if any conditions of this licensing are
19** not clear to you.
20**
21*********************************************************************</comment>
22<widget>
23 <class>QWidget</class>
24 <property stdset="1">
25 <name>name</name>
26 <cstring>DateBookWeekHeaderBase</cstring>
27 </property>
28 <property stdset="1">
29 <name>geometry</name>
30 <rect>
31 <x>0</x>
32 <y>0</y>
33 <width>281</width>
34 <height>30</height>
35 </rect>
36 </property>
37 <property stdset="1">
38 <name>caption</name>
39 <string>Form1</string>
40 </property>
41 <property>
42 <name>layoutMargin</name>
43 </property>
44 <property>
45 <name>layoutSpacing</name>
46 </property>
47 <hbox>
48 <property stdset="1">
49 <name>margin</name>
50 <number>0</number>
51 </property>
52 <property stdset="1">
53 <name>spacing</name>
54 <number>6</number>
55 </property>
56 <widget>
57 <class>QSpinBox</class>
58 <property stdset="1">
59 <name>name</name>
60 <cstring>spinYear</cstring>
61 </property>
62 <property stdset="1">
63 <name>sizePolicy</name>
64 <sizepolicy>
65 <hsizetype>0</hsizetype>
66 <vsizetype>0</vsizetype>
67 </sizepolicy>
68 </property>
69 <property stdset="1">
70 <name>prefix</name>
71 <string>Y: </string>
72 </property>
73 <property stdset="1">
74 <name>maxValue</name>
75 <number>2037</number>
76 </property>
77 <property stdset="1">
78 <name>minValue</name>
79 <number>1970</number>
80 </property>
81 <property stdset="1">
82 <name>value</name>
83 <number>2002</number>
84 </property>
85 </widget>
86 <widget>
87 <class>QSpinBox</class>
88 <property stdset="1">
89 <name>name</name>
90 <cstring>spinWeek</cstring>
91 </property>
92 <property stdset="1">
93 <name>sizePolicy</name>
94 <sizepolicy>
95 <hsizetype>0</hsizetype>
96 <vsizetype>0</vsizetype>
97 </sizepolicy>
98 </property>
99 <property stdset="1">
100 <name>prefix</name>
101 <string>W: </string>
102 </property>
103 <property stdset="1">
104 <name>maxValue</name>
105 <number>52</number>
106 </property>
107 <property stdset="1">
108 <name>minValue</name>
109 <number>1</number>
110 </property>
111 <property stdset="1">
112 <name>value</name>
113 <number>1</number>
114 </property>
115 </widget>
116 <widget>
117 <class>QLabel</class>
118 <property stdset="1">
119 <name>name</name>
120 <cstring>labelDate</cstring>
121 </property>
122 <property stdset="1">
123 <name>sizePolicy</name>
124 <sizepolicy>
125 <hsizetype>3</hsizetype>
126 <vsizetype>1</vsizetype>
127 </sizepolicy>
128 </property>
129 <property stdset="1">
130 <name>font</name>
131 <font>
132 <bold>1</bold>
133 </font>
134 </property>
135 <property stdset="1">
136 <name>text</name>
137 <string>00. Jan-00. Jan</string>
138 </property>
139 <property stdset="1">
140 <name>alignment</name>
141 <set>AlignCenter</set>
142 </property>
143 <property>
144 <name>hAlign</name>
145 </property>
146 </widget>
147 </hbox>
148</widget>
149<connections>
150 <connection>
151 <sender>spinYear</sender>
152 <signal>valueChanged(int)</signal>
153 <receiver>DateBookWeekHeaderBase</receiver>
154 <slot>yearChanged( int )</slot>
155 </connection>
156 <connection>
157 <sender>spinWeek</sender>
158 <signal>valueChanged(int)</signal>
159 <receiver>DateBookWeekHeaderBase</receiver>
160 <slot>weekChanged( int )</slot>
161 </connection>
162 <slot access="public">yearChanged( int )</slot>
163 <slot access="public">nextWeek()</slot>
164 <slot access="public">prevWeek()</slot>
165 <slot access="public">weekChanged( int )</slot>
166</connections>
167</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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#include "datebookweekheaderimpl.h"
21#include <qlabel.h>
22#include <qspinbox.h>
23#include <qdatetime.h>
24
25/*
26 * Constructs a DateBookWeekHeader which is a child of 'parent', with the
27 * name 'name' and widget flags set to 'f'
28 */
29DateBookWeekHeader::DateBookWeekHeader( bool startOnMonday, QWidget* parent,
30 const char* name, WFlags fl )
31 : DateBookWeekHeaderBase( parent, name, fl ),
32 bStartOnMonday( startOnMonday )
33{
34 setBackgroundMode( PaletteButton );
35 labelDate->setBackgroundMode( PaletteButton );
36}
37
38/*
39 * Destroys the object and frees any allocated resources
40 */
41DateBookWeekHeader::~DateBookWeekHeader()
42{
43 // no need to delete child widgets, Qt does it all for us
44}
45
46/*
47 * public slot
48 */
49void DateBookWeekHeader::yearChanged( int y )
50{
51 setDate( y, week );
52}
53/*
54 * public slot
55 */
56void DateBookWeekHeader::nextWeek()
57{
58 if ( week < 52 )
59 week++;
60 setDate( year, week );
61}
62/*
63 * public slot
64 */
65void DateBookWeekHeader::prevWeek()
66{
67 if ( week > 1 )
68 week--;
69 setDate( year, week );
70}
71/*
72 * public slot
73 */
74void DateBookWeekHeader::weekChanged( int w )
75{
76 setDate( year, w );
77}
78
79void DateBookWeekHeader::setDate( int y, int w )
80{
81 year = y;
82 week = w;
83 spinYear->setValue( y );
84 spinWeek->setValue( w );
85
86 QDate d = dateFromWeek( week, year, bStartOnMonday );
87
88 QString s = QString::number( d.day() ) + ". " + d.monthName( d.month() )
89 + "-";
90 d = d.addDays( 6 );
91 s += QString::number( d.day() ) + ". " + d.monthName( d.month() );
92 labelDate->setText( s );
93
94 emit dateChanged( y, w );
95}
96
97void DateBookWeekHeader::setStartOfWeek( bool onMonday )
98{
99 bStartOnMonday = onMonday;
100 setDate( year, week );
101}
102
103// dateFromWeek
104// compute the date from the week in the year
105
106QDate dateFromWeek( int week, int year, bool startOnMonday )
107{
108 QDate d;
109 d.setYMD( year, 1, 1 );
110 int dayOfWeek = d.dayOfWeek();
111 if ( startOnMonday ) {
112 if ( dayOfWeek <= 4 ) {
113 d = d.addDays( ( week - 1 ) * 7 - dayOfWeek + 1 );
114 } else {
115 d = d.addDays( (week) * 7 - dayOfWeek + 1 );
116 }
117 } else {
118 if ( dayOfWeek <= 4 || dayOfWeek == 7) {
119 d = d.addDays( ( week - 1 ) * 7 - dayOfWeek % 7 );
120 } else {
121 d = d.addDays( ( week ) * 7 - dayOfWeek % 7 );
122 }
123 }
124 return d;
125}
126
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef DATEBOOKDAYHEADER_H
21#define DATEBOOKDAYHEADER_H
22#include <qdatetime.h>
23#include "datebookweekheader.h"
24
25
26class DateBookWeekHeader : public DateBookWeekHeaderBase
27{
28 Q_OBJECT
29
30public:
31 DateBookWeekHeader( bool startOnMonday, QWidget* parent = 0,
32 const char* name = 0, WFlags fl = 0 );
33 ~DateBookWeekHeader();
34
35 void setDate( int y, int w );
36 void setStartOfWeek( bool onMonday );
37
38signals:
39 void dateChanged( int y, int w );
40
41public slots:
42 void yearChanged( int );
43 void nextWeek();
44 void prevWeek();
45 void weekChanged( int );
46
47protected slots:
48 void keyPressEvent(QKeyEvent *e)
49 {
50 e->ignore();
51 }
52
53private:
54 int year,
55 week;
56 bool bStartOnMonday;
57
58};
59
60QDate dateFromWeek( int week, int year, bool startOnMonday );
61
62#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 @@
1<!DOCTYPE UI><UI>
2<class>DateEntryBase</class>
3<comment>*********************************************************************
4** Copyright (C) 2000 Trolltech AS. All rights reserved.
5**
6** This file is part of Qtopia Environment.
7**
8** This file may be distributed and/or modified under the terms of the
9** GNU General Public License version 2 as published by the Free Software
10** Foundation and appearing in the file LICENSE.GPL included in the
11** packaging of this file.
12**
13** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
14** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
15**
16** See http://www.trolltech.com/gpl/ for GPL licensing information.
17**
18** Contact info@trolltech.com if any conditions of this licensing are
19** not clear to you.
20**
21** $Id$
22**
23*********************************************************************</comment>
24<widget>
25 <class>QWidget</class>
26 <property stdset="1">
27 <name>name</name>
28 <cstring>DateEntryBase</cstring>
29 </property>
30 <property stdset="1">
31 <name>geometry</name>
32 <rect>
33 <x>0</x>
34 <y>0</y>
35 <width>242</width>
36 <height>339</height>
37 </rect>
38 </property>
39 <property stdset="1">
40 <name>caption</name>
41 <string>New Event</string>
42 </property>
43 <property>
44 <name>layoutMargin</name>
45 </property>
46 <property>
47 <name>layoutSpacing</name>
48 </property>
49 <grid>
50 <property stdset="1">
51 <name>margin</name>
52 <number>0</number>
53 </property>
54 <property stdset="1">
55 <name>spacing</name>
56 <number>0</number>
57 </property>
58 <widget row="1" column="0" >
59 <class>QLabel</class>
60 <property stdset="1">
61 <name>name</name>
62 <cstring>TextLabel2</cstring>
63 </property>
64 <property stdset="1">
65 <name>frameShape</name>
66 <enum>MShape</enum>
67 </property>
68 <property stdset="1">
69 <name>frameShadow</name>
70 <enum>MShadow</enum>
71 </property>
72 <property stdset="1">
73 <name>text</name>
74 <string>Location</string>
75 </property>
76 </widget>
77 <widget row="2" column="0" >
78 <class>QLabel</class>
79 <property stdset="1">
80 <name>name</name>
81 <cstring>TextLabel2_2</cstring>
82 </property>
83 <property stdset="1">
84 <name>text</name>
85 <string>Category</string>
86 </property>
87 <property>
88 <name>buddy</name>
89 <cstring>comboPriority</cstring>
90 </property>
91 </widget>
92 <widget row="0" column="1" rowspan="1" colspan="3" >
93 <class>QComboBox</class>
94 <item>
95 <property>
96 <name>text</name>
97 <string>(None)</string>
98 </property>
99 </item>
100 <item>
101 <property>
102 <name>text</name>
103 <string>Meeting</string>
104 </property>
105 </item>
106 <item>
107 <property>
108 <name>text</name>
109 <string>Lunch</string>
110 </property>
111 </item>
112 <item>
113 <property>
114 <name>text</name>
115 <string>Dinner</string>
116 </property>
117 </item>
118 <item>
119 <property>
120 <name>text</name>
121 <string>Travel</string>
122 </property>
123 </item>
124 <property stdset="1">
125 <name>name</name>
126 <cstring>comboDescription</cstring>
127 </property>
128 <property stdset="1">
129 <name>sizePolicy</name>
130 <sizepolicy>
131 <hsizetype>7</hsizetype>
132 <vsizetype>0</vsizetype>
133 </sizepolicy>
134 </property>
135 <property stdset="1">
136 <name>editable</name>
137 <bool>true</bool>
138 </property>
139 <property stdset="1">
140 <name>currentItem</name>
141 <number>0</number>
142 </property>
143 <property stdset="1">
144 <name>duplicatesEnabled</name>
145 <bool>false</bool>
146 </property>
147 </widget>
148 <widget row="0" column="0" >
149 <class>QLabel</class>
150 <property stdset="1">
151 <name>name</name>
152 <cstring>TextLabel1</cstring>
153 </property>
154 <property stdset="1">
155 <name>text</name>
156 <string>Description:</string>
157 </property>
158 </widget>
159 <widget row="1" column="1" rowspan="1" colspan="3" >
160 <class>QComboBox</class>
161 <item>
162 <property>
163 <name>text</name>
164 <string>(Unknown)</string>
165 </property>
166 </item>
167 <item>
168 <property>
169 <name>text</name>
170 <string>Office</string>
171 </property>
172 </item>
173 <item>
174 <property>
175 <name>text</name>
176 <string>Home</string>
177 </property>
178 </item>
179 <property stdset="1">
180 <name>name</name>
181 <cstring>comboLocation</cstring>
182 </property>
183 <property stdset="1">
184 <name>sizePolicy</name>
185 <sizepolicy>
186 <hsizetype>7</hsizetype>
187 <vsizetype>0</vsizetype>
188 </sizepolicy>
189 </property>
190 <property stdset="1">
191 <name>editable</name>
192 <bool>true</bool>
193 </property>
194 <property stdset="1">
195 <name>currentItem</name>
196 <number>0</number>
197 </property>
198 <property stdset="1">
199 <name>duplicatesEnabled</name>
200 <bool>false</bool>
201 </property>
202 </widget>
203 <widget row="2" column="1" rowspan="1" colspan="3" >
204 <class>CategorySelect</class>
205 <property stdset="1">
206 <name>name</name>
207 <cstring>comboCategory</cstring>
208 </property>
209 </widget>
210 <widget row="3" column="0" >
211 <class>QLabel</class>
212 <property stdset="1">
213 <name>name</name>
214 <cstring>TextLabel3</cstring>
215 </property>
216 <property stdset="1">
217 <name>text</name>
218 <string>Start</string>
219 </property>
220 </widget>
221 <widget row="3" column="1" >
222 <class>QPushButton</class>
223 <property stdset="1">
224 <name>name</name>
225 <cstring>buttonStart</cstring>
226 </property>
227 <property stdset="1">
228 <name>text</name>
229 <string>Jan 02 00</string>
230 </property>
231 </widget>
232 <widget row="3" column="2" rowspan="1" colspan="2" >
233 <class>QComboBox</class>
234 <item>
235 <property>
236 <name>text</name>
237 <string>00:00</string>
238 </property>
239 </item>
240 <item>
241 <property>
242 <name>text</name>
243 <string>00:30</string>
244 </property>
245 </item>
246 <item>
247 <property>
248 <name>text</name>
249 <string>01:00</string>
250 </property>
251 </item>
252 <item>
253 <property>
254 <name>text</name>
255 <string>01:30</string>
256 </property>
257 </item>
258 <item>
259 <property>
260 <name>text</name>
261 <string>02:00</string>
262 </property>
263 </item>
264 <item>
265 <property>
266 <name>text</name>
267 <string>02:30</string>
268 </property>
269 </item>
270 <item>
271 <property>
272 <name>text</name>
273 <string>03:00</string>
274 </property>
275 </item>
276 <item>
277 <property>
278 <name>text</name>
279 <string>03:30</string>
280 </property>
281 </item>
282 <item>
283 <property>
284 <name>text</name>
285 <string>04:00</string>
286 </property>
287 </item>
288 <item>
289 <property>
290 <name>text</name>
291 <string>04:30</string>
292 </property>
293 </item>
294 <item>
295 <property>
296 <name>text</name>
297 <string>05:00</string>
298 </property>
299 </item>
300 <item>
301 <property>
302 <name>text</name>
303 <string>05:30</string>
304 </property>
305 </item>
306 <item>
307 <property>
308 <name>text</name>
309 <string>06:00</string>
310 </property>
311 </item>
312 <item>
313 <property>
314 <name>text</name>
315 <string>06:30</string>
316 </property>
317 </item>
318 <item>
319 <property>
320 <name>text</name>
321 <string>07:00</string>
322 </property>
323 </item>
324 <item>
325 <property>
326 <name>text</name>
327 <string>07:30</string>
328 </property>
329 </item>
330 <item>
331 <property>
332 <name>text</name>
333 <string>08:00</string>
334 </property>
335 </item>
336 <item>
337 <property>
338 <name>text</name>
339 <string>08:30</string>
340 </property>
341 </item>
342 <item>
343 <property>
344 <name>text</name>
345 <string>09:00</string>
346 </property>
347 </item>
348 <item>
349 <property>
350 <name>text</name>
351 <string>09:30</string>
352 </property>
353 </item>
354 <item>
355 <property>
356 <name>text</name>
357 <string>10:00</string>
358 </property>
359 </item>
360 <item>
361 <property>
362 <name>text</name>
363 <string>10:30</string>
364 </property>
365 </item>
366 <item>
367 <property>
368 <name>text</name>
369 <string>11:00</string>
370 </property>
371 </item>
372 <item>
373 <property>
374 <name>text</name>
375 <string>11:30</string>
376 </property>
377 </item>
378 <item>
379 <property>
380 <name>text</name>
381 <string>12:00</string>
382 </property>
383 </item>
384 <item>
385 <property>
386 <name>text</name>
387 <string>12:30</string>
388 </property>
389 </item>
390 <item>
391 <property>
392 <name>text</name>
393 <string>13:00</string>
394 </property>
395 </item>
396 <item>
397 <property>
398 <name>text</name>
399 <string>13:30</string>
400 </property>
401 </item>
402 <item>
403 <property>
404 <name>text</name>
405 <string>14:00</string>
406 </property>
407 </item>
408 <item>
409 <property>
410 <name>text</name>
411 <string>14:30</string>
412 </property>
413 </item>
414 <item>
415 <property>
416 <name>text</name>
417 <string>15:00</string>
418 </property>
419 </item>
420 <item>
421 <property>
422 <name>text</name>
423 <string>15:30</string>
424 </property>
425 </item>
426 <item>
427 <property>
428 <name>text</name>
429 <string>16:00</string>
430 </property>
431 </item>
432 <item>
433 <property>
434 <name>text</name>
435 <string>16:30</string>
436 </property>
437 </item>
438 <item>
439 <property>
440 <name>text</name>
441 <string>17:00</string>
442 </property>
443 </item>
444 <item>
445 <property>
446 <name>text</name>
447 <string>17:30</string>
448 </property>
449 </item>
450 <item>
451 <property>
452 <name>text</name>
453 <string>18:00</string>
454 </property>
455 </item>
456 <item>
457 <property>
458 <name>text</name>
459 <string>18:30</string>
460 </property>
461 </item>
462 <item>
463 <property>
464 <name>text</name>
465 <string>19:00</string>
466 </property>
467 </item>
468 <item>
469 <property>
470 <name>text</name>
471 <string>19:30</string>
472 </property>
473 </item>
474 <item>
475 <property>
476 <name>text</name>
477 <string>20:00</string>
478 </property>
479 </item>
480 <item>
481 <property>
482 <name>text</name>
483 <string>20:30</string>
484 </property>
485 </item>
486 <item>
487 <property>
488 <name>text</name>
489 <string>21:00</string>
490 </property>
491 </item>
492 <item>
493 <property>
494 <name>text</name>
495 <string>21:30</string>
496 </property>
497 </item>
498 <item>
499 <property>
500 <name>text</name>
501 <string>22:00</string>
502 </property>
503 </item>
504 <item>
505 <property>
506 <name>text</name>
507 <string>22:30</string>
508 </property>
509 </item>
510 <item>
511 <property>
512 <name>text</name>
513 <string>23:00</string>
514 </property>
515 </item>
516 <item>
517 <property>
518 <name>text</name>
519 <string>23:30</string>
520 </property>
521 </item>
522 <property stdset="1">
523 <name>name</name>
524 <cstring>comboStart</cstring>
525 </property>
526 <property stdset="1">
527 <name>editable</name>
528 <bool>true</bool>
529 </property>
530 <property stdset="1">
531 <name>duplicatesEnabled</name>
532 <bool>false</bool>
533 </property>
534 </widget>
535 <widget row="4" column="1" >
536 <class>QPushButton</class>
537 <property stdset="1">
538 <name>name</name>
539 <cstring>buttonEnd</cstring>
540 </property>
541 <property stdset="1">
542 <name>text</name>
543 <string>Jan 02 00</string>
544 </property>
545 </widget>
546 <widget row="4" column="2" rowspan="1" colspan="2" >
547 <class>QComboBox</class>
548 <item>
549 <property>
550 <name>text</name>
551 <string>00:00</string>
552 </property>
553 </item>
554 <item>
555 <property>
556 <name>text</name>
557 <string>00:30</string>
558 </property>
559 </item>
560 <item>
561 <property>
562 <name>text</name>
563 <string>01:00</string>
564 </property>
565 </item>
566 <item>
567 <property>
568 <name>text</name>
569 <string>01:30</string>
570 </property>
571 </item>
572 <item>
573 <property>
574 <name>text</name>
575 <string>02:00</string>
576 </property>
577 </item>
578 <item>
579 <property>
580 <name>text</name>
581 <string>02:30</string>
582 </property>
583 </item>
584 <item>
585 <property>
586 <name>text</name>
587 <string>03:00</string>
588 </property>
589 </item>
590 <item>
591 <property>
592 <name>text</name>
593 <string>03:30</string>
594 </property>
595 </item>
596 <item>
597 <property>
598 <name>text</name>
599 <string>04:00</string>
600 </property>
601 </item>
602 <item>
603 <property>
604 <name>text</name>
605 <string>04:30</string>
606 </property>
607 </item>
608 <item>
609 <property>
610 <name>text</name>
611 <string>05:00</string>
612 </property>
613 </item>
614 <item>
615 <property>
616 <name>text</name>
617 <string>05:30</string>
618 </property>
619 </item>
620 <item>
621 <property>
622 <name>text</name>
623 <string>06:00</string>
624 </property>
625 </item>
626 <item>
627 <property>
628 <name>text</name>
629 <string>06:30</string>
630 </property>
631 </item>
632 <item>
633 <property>
634 <name>text</name>
635 <string>07:00</string>
636 </property>
637 </item>
638 <item>
639 <property>
640 <name>text</name>
641 <string>07:30</string>
642 </property>
643 </item>
644 <item>
645 <property>
646 <name>text</name>
647 <string>08:00</string>
648 </property>
649 </item>
650 <item>
651 <property>
652 <name>text</name>
653 <string>08:30</string>
654 </property>
655 </item>
656 <item>
657 <property>
658 <name>text</name>
659 <string>09:00</string>
660 </property>
661 </item>
662 <item>
663 <property>
664 <name>text</name>
665 <string>09:30</string>
666 </property>
667 </item>
668 <item>
669 <property>
670 <name>text</name>
671 <string>10:00</string>
672 </property>
673 </item>
674 <item>
675 <property>
676 <name>text</name>
677 <string>10:30</string>
678 </property>
679 </item>
680 <item>
681 <property>
682 <name>text</name>
683 <string>11:00</string>
684 </property>
685 </item>
686 <item>
687 <property>
688 <name>text</name>
689 <string>11:30</string>
690 </property>
691 </item>
692 <item>
693 <property>
694 <name>text</name>
695 <string>12:00</string>
696 </property>
697 </item>
698 <item>
699 <property>
700 <name>text</name>
701 <string>12:30</string>
702 </property>
703 </item>
704 <item>
705 <property>
706 <name>text</name>
707 <string>13:00</string>
708 </property>
709 </item>
710 <item>
711 <property>
712 <name>text</name>
713 <string>13:30</string>
714 </property>
715 </item>
716 <item>
717 <property>
718 <name>text</name>
719 <string>14:00</string>
720 </property>
721 </item>
722 <item>
723 <property>
724 <name>text</name>
725 <string>14:30</string>
726 </property>
727 </item>
728 <item>
729 <property>
730 <name>text</name>
731 <string>15:00</string>
732 </property>
733 </item>
734 <item>
735 <property>
736 <name>text</name>
737 <string>15:30</string>
738 </property>
739 </item>
740 <item>
741 <property>
742 <name>text</name>
743 <string>16:00</string>
744 </property>
745 </item>
746 <item>
747 <property>
748 <name>text</name>
749 <string>16:30</string>
750 </property>
751 </item>
752 <item>
753 <property>
754 <name>text</name>
755 <string>17:00</string>
756 </property>
757 </item>
758 <item>
759 <property>
760 <name>text</name>
761 <string>17:30</string>
762 </property>
763 </item>
764 <item>
765 <property>
766 <name>text</name>
767 <string>18:00</string>
768 </property>
769 </item>
770 <item>
771 <property>
772 <name>text</name>
773 <string>18:30</string>
774 </property>
775 </item>
776 <item>
777 <property>
778 <name>text</name>
779 <string>19:00</string>
780 </property>
781 </item>
782 <item>
783 <property>
784 <name>text</name>
785 <string>19:30</string>
786 </property>
787 </item>
788 <item>
789 <property>
790 <name>text</name>
791 <string>20:00</string>
792 </property>
793 </item>
794 <item>
795 <property>
796 <name>text</name>
797 <string>20:30</string>
798 </property>
799 </item>
800 <item>
801 <property>
802 <name>text</name>
803 <string>21:00</string>
804 </property>
805 </item>
806 <item>
807 <property>
808 <name>text</name>
809 <string>21:30</string>
810 </property>
811 </item>
812 <item>
813 <property>
814 <name>text</name>
815 <string>22:00</string>
816 </property>
817 </item>
818 <item>
819 <property>
820 <name>text</name>
821 <string>22:30</string>
822 </property>
823 </item>
824 <item>
825 <property>
826 <name>text</name>
827 <string>23:00</string>
828 </property>
829 </item>
830 <item>
831 <property>
832 <name>text</name>
833 <string>23:30</string>
834 </property>
835 </item>
836 <property stdset="1">
837 <name>name</name>
838 <cstring>comboEnd</cstring>
839 </property>
840 <property stdset="1">
841 <name>editable</name>
842 <bool>true</bool>
843 </property>
844 <property stdset="1">
845 <name>duplicatesEnabled</name>
846 <bool>false</bool>
847 </property>
848 </widget>
849 <widget row="4" column="0" >
850 <class>QLabel</class>
851 <property stdset="1">
852 <name>name</name>
853 <cstring>TextLabel3_2</cstring>
854 </property>
855 <property stdset="1">
856 <name>text</name>
857 <string>End</string>
858 </property>
859 </widget>
860 <widget row="5" column="0" >
861 <class>QCheckBox</class>
862 <property stdset="1">
863 <name>name</name>
864 <cstring>checkAllDay</cstring>
865 </property>
866 <property stdset="1">
867 <name>text</name>
868 <string>All day</string>
869 </property>
870 </widget>
871 <widget row="6" column="0" >
872 <class>QLabel</class>
873 <property stdset="1">
874 <name>name</name>
875 <cstring>TextLabel3_2_2</cstring>
876 </property>
877 <property stdset="1">
878 <name>text</name>
879 <string>Time zone:</string>
880 </property>
881 </widget>
882 <widget row="6" column="1" rowspan="1" colspan="3" >
883 <class>TimeZoneSelector</class>
884 <property stdset="1">
885 <name>name</name>
886 <cstring>timezone</cstring>
887 </property>
888 </widget>
889 <widget row="7" column="0" >
890 <class>QCheckBox</class>
891 <property stdset="1">
892 <name>name</name>
893 <cstring>checkAlarm</cstring>
894 </property>
895 <property stdset="1">
896 <name>enabled</name>
897 <bool>true</bool>
898 </property>
899 <property stdset="1">
900 <name>autoMask</name>
901 <bool>false</bool>
902 </property>
903 <property stdset="1">
904 <name>text</name>
905 <string>&amp;Alarm</string>
906 </property>
907 <property stdset="1">
908 <name>checked</name>
909 <bool>false</bool>
910 </property>
911 </widget>
912 <widget row="7" column="1" rowspan="1" colspan="2" >
913 <class>QSpinBox</class>
914 <property stdset="1">
915 <name>name</name>
916 <cstring>spinAlarm</cstring>
917 </property>
918 <property stdset="1">
919 <name>enabled</name>
920 <bool>false</bool>
921 </property>
922 <property stdset="1">
923 <name>suffix</name>
924 <string> minutes</string>
925 </property>
926 <property stdset="1">
927 <name>maxValue</name>
928 <number>180</number>
929 </property>
930 <property stdset="1">
931 <name>minValue</name>
932 <number>0</number>
933 </property>
934 <property stdset="1">
935 <name>lineStep</name>
936 <number>5</number>
937 </property>
938 <property stdset="1">
939 <name>value</name>
940 <number>5</number>
941 </property>
942 </widget>
943 <widget row="7" column="3" >
944 <class>QComboBox</class>
945 <item>
946 <property>
947 <name>text</name>
948 <string>Silent</string>
949 </property>
950 </item>
951 <item>
952 <property>
953 <name>text</name>
954 <string>Loud</string>
955 </property>
956 </item>
957 <property stdset="1">
958 <name>name</name>
959 <cstring>comboSound</cstring>
960 </property>
961 <property stdset="1">
962 <name>enabled</name>
963 <bool>false</bool>
964 </property>
965 </widget>
966 <widget row="8" column="0" >
967 <class>QLabel</class>
968 <property stdset="1">
969 <name>name</name>
970 <cstring>lblRepeat</cstring>
971 </property>
972 <property stdset="1">
973 <name>text</name>
974 <string>Repeat</string>
975 </property>
976 </widget>
977 <widget row="8" column="1" rowspan="1" colspan="3" >
978 <class>QToolButton</class>
979 <property stdset="1">
980 <name>name</name>
981 <cstring>cmdRepeat</cstring>
982 </property>
983 <property stdset="1">
984 <name>focusPolicy</name>
985 <enum>TabFocus</enum>
986 </property>
987 <property stdset="1">
988 <name>text</name>
989 <string>No Repeat...</string>
990 </property>
991 </widget>
992 <widget row="9" column="0" rowspan="1" colspan="4" >
993 <class>QMultiLineEdit</class>
994 <property stdset="1">
995 <name>name</name>
996 <cstring>editNote</cstring>
997 </property>
998 </widget>
999 </grid>
1000</widget>
1001<customwidgets>
1002 <customwidget>
1003 <class>TimeZoneSelector</class>
1004 <header location="global">qpe/tzselect.h</header>
1005 <sizehint>
1006 <width>21</width>
1007 <height>10</height>
1008 </sizehint>
1009 <container>0</container>
1010 <sizepolicy>
1011 <hordata>7</hordata>
1012 <verdata>1</verdata>
1013 </sizepolicy>
1014 <pixmap>image0</pixmap>
1015 </customwidget>
1016 <customwidget>
1017 <class>CategorySelect</class>
1018 <header location="global">qpe/categoryselect.h</header>
1019 <sizehint>
1020 <width>-1</width>
1021 <height>-1</height>
1022 </sizehint>
1023 <container>0</container>
1024 <sizepolicy>
1025 <hordata>7</hordata>
1026 <verdata>1</verdata>
1027 </sizepolicy>
1028 <pixmap>image1</pixmap>
1029 </customwidget>
1030</customwidgets>
1031<images>
1032 <image>
1033 <name>image0</name>
1034 <data format="XPM.GZ" length="45">789cd3d7528808f055d0d2e72a2e492cc94c5648ce482c52d04a29cdcdad8c8eb5ade6523250004143a55a6b2e0026630c4f</data>
1035 </image>
1036 <image>
1037 <name>image1</name>
1038 <data format="XPM.GZ" length="646">789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758</data>
1039 </image>
1040</images>
1041<connections>
1042 <connection>
1043 <sender>checkAlarm</sender>
1044 <signal>toggled(bool)</signal>
1045 <receiver>spinAlarm</receiver>
1046 <slot>setEnabled(bool)</slot>
1047 </connection>
1048 <connection>
1049 <sender>comboEnd</sender>
1050 <signal>activated(const QString&amp;)</signal>
1051 <receiver>DateEntryBase</receiver>
1052 <slot>endTimeChanged( const QString &amp; )</slot>
1053 </connection>
1054 <connection>
1055 <sender>cmdRepeat</sender>
1056 <signal>clicked()</signal>
1057 <receiver>DateEntryBase</receiver>
1058 <slot>slotRepeat()</slot>
1059 </connection>
1060 <connection>
1061 <sender>comboStart</sender>
1062 <signal>activated(int)</signal>
1063 <receiver>DateEntryBase</receiver>
1064 <slot>startTimeChanged( int )</slot>
1065 </connection>
1066 <connection>
1067 <sender>checkAllDay</sender>
1068 <signal>toggled(bool)</signal>
1069 <receiver>comboEnd</receiver>
1070 <slot>setDisabled(bool)</slot>
1071 </connection>
1072 <connection>
1073 <sender>checkAlarm</sender>
1074 <signal>toggled(bool)</signal>
1075 <receiver>comboSound</receiver>
1076 <slot>setEnabled(bool)</slot>
1077 </connection>
1078 <connection>
1079 <sender>checkAllDay</sender>
1080 <signal>toggled(bool)</signal>
1081 <receiver>comboStart</receiver>
1082 <slot>setDisabled(bool)</slot>
1083 </connection>
1084 <slot access="public">endDateChanged( const QString &amp; )</slot>
1085 <slot access="public">endDateChanged( int, int, int )</slot>
1086 <slot access="public">endTimeChanged( const QString &amp; )</slot>
1087 <slot access="public">slotRepeat()</slot>
1088 <slot access="public">slotWait( int )</slot>
1089 <slot access="public">startDateChanged( const QString &amp; )</slot>
1090 <slot access="public">startDateChanged(int, int, int)</slot>
1091 <slot access="public">startTimeChanged( int )</slot>
1092 <slot access="public">typeChanged( const QString &amp; )</slot>
1093 <slot access="public">tzexecute(void)</slot>
1094</connections>
1095</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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "dateentryimpl.h"
22#include "repeatentry.h"
23
24#include <qpe/qpeapplication.h>
25#include <qpe/categoryselect.h>
26#include <qpe/datebookmonth.h>
27#include <qpe/global.h>
28#include <qpe/timeconversion.h>
29#include <qpe/timestring.h>
30#include <qpe/tzselect.h>
31
32#include <qcheckbox.h>
33#include <qcombobox.h>
34#include <qlayout.h>
35#include <qlineedit.h>
36#include <qmultilineedit.h>
37#include <qpopupmenu.h>
38#include <qscrollview.h>
39#include <qspinbox.h>
40#include <qtoolbutton.h>
41
42#include <stdlib.h>
43
44/*
45 * Constructs a DateEntry which is a child of 'parent', with the
46 * name 'name' and widget flags set to 'f'
47 *
48 * The dialog will by default be modeless, unless you set 'modal' to
49 * TRUE to construct a modal dialog.
50 */
51
52DateEntry::DateEntry( bool startOnMonday, const QDateTime &start,
53 const QDateTime &end, bool whichClock, QWidget* parent,
54 const char* name )
55 : DateEntryBase( parent, name ),
56 ampm( whichClock ),
57 startWeekOnMonday( startOnMonday )
58{
59 init();
60 setDates(start,end);
61}
62
63static void addOrPick( QComboBox* combo, const QString& t )
64{
65 for (int i=0; i<combo->count(); i++) {
66 if ( combo->text(i) == t ) {
67 combo->setCurrentItem(i);
68 return;
69 }
70 }
71 combo->setEditText(t);
72}
73
74DateEntry::DateEntry( bool startOnMonday, const Event &event, bool whichClock,
75 QWidget* parent, const char* name )
76 : DateEntryBase( parent, name ),
77 ampm( whichClock ),
78 startWeekOnMonday( startOnMonday )
79{
80 init();
81 setDates(event.start(),event.end());
82 comboCategory->setCategories( event.categories(), "Calendar", tr("Calendar") );
83 if(!event.description().isEmpty())
84 addOrPick( comboDescription, event.description() );
85 if(!event.location().isEmpty())
86 addOrPick( comboLocation, event.location() );
87 checkAlarm->setChecked( event.hasAlarm() );
88 checkAllDay->setChecked( event.type() == Event::AllDay );
89 if(!event.notes().isEmpty())
90 editNote->setText(event.notes());
91 spinAlarm->setValue(event.alarmTime());
92 if ( event.alarmSound() != Event::Silent )
93 comboSound->setCurrentItem( 1 );
94 if ( event.hasRepeat() ) {
95 rp = event.repeatPattern();
96 cmdRepeat->setText( tr("Repeat...") );
97 }
98 setRepeatLabel();
99}
100
101void DateEntry::setDates( const QDateTime& s, const QDateTime& e )
102{
103 int shour,
104 ehour;
105 QString strStart,
106 strEnd;
107 startDate = s.date();
108 endDate = e.date();
109 startTime = s.time();
110 endTime = e.time();
111 startDateChanged( s.date().year(), s.date().month(), s.date().day() );
112 if ( ampm ) {
113 shour = s.time().hour();
114 ehour = e.time().hour();
115 if ( shour >= 12 ) {
116 if ( shour > 12 )
117 shour -= 12;
118 strStart.sprintf( "%d:%02d PM", shour, s.time().minute() );
119 } else {
120 if ( shour == 0 )
121 shour = 12;
122 strStart.sprintf( "%d:%02d AM", shour, s.time().minute() );
123 }
124 if ( ehour == 24 && e.time().minute() == 0 ) {
125 strEnd = "11:59 PM"; // or "midnight"
126 } else if ( ehour >= 12 ) {
127 if ( ehour > 12 )
128 ehour -= 12;
129 strEnd.sprintf( "%d:%02d PM", ehour, e.time().minute() );
130 } else {
131 if ( ehour == 0 )
132 ehour = 12;
133 strEnd.sprintf( "%d:%02d AM", ehour, e.time().minute() );
134 }
135 } else {
136 strStart.sprintf( "%02d:%02d", s.time().hour(), s.time().minute() );
137 strEnd.sprintf( "%02d:%02d", e.time().hour(), e.time().minute() );
138 }
139 addOrPick(comboStart, strStart );
140 endDateChanged( e.date().year(), e.date().month(), e.date().day() );
141 addOrPick(comboEnd, strEnd );
142}
143
144void DateEntry::init()
145{
146 comboDescription->setInsertionPolicy(QComboBox::AtCurrent);
147 comboLocation->setInsertionPolicy(QComboBox::AtCurrent);
148
149 initCombos();
150 QPopupMenu *m1 = new QPopupMenu( this );
151 startPicker = new DateBookMonth( m1, 0, TRUE );
152 m1->insertItem( startPicker );
153 buttonStart->setPopup( m1 );
154 connect( startPicker, SIGNAL( dateClicked( int, int, int ) ),
155 this, SLOT( startDateChanged( int, int, int ) ) );
156
157 //Let start button change both start and end dates
158 connect( startPicker, SIGNAL( dateClicked( int, int, int ) ),
159 this, SLOT( endDateChanged( int, int, int ) ) );
160 connect( qApp, SIGNAL( clockChanged( bool ) ),
161 this, SLOT( slotChangeClock( bool ) ) );
162 connect( qApp, SIGNAL(weekChanged(bool)),
163 this, SLOT(slotChangeStartOfWeek(bool)) );
164
165 QPopupMenu *m2 = new QPopupMenu( this );
166 endPicker = new DateBookMonth( m2, 0, TRUE );
167 m2->insertItem( endPicker );
168 buttonEnd->setPopup( m2 );
169 connect( endPicker, SIGNAL( dateClicked( int, int, int ) ),
170 this, SLOT( endDateChanged( int, int, int ) ) );
171}
172
173/*
174 * Destroys the object and frees any allocated resources
175 */
176DateEntry::~DateEntry()
177{
178 // no need to delete child widgets, Qt does it all for us
179}
180
181/*
182 * public slot
183 */
184void DateEntry::endDateChanged( int y, int m, int d )
185{
186 endDate.setYMD( y, m, d );
187 if ( endDate < startDate ) {
188 endDate = startDate;
189 }
190
191 buttonEnd->setText( TimeString::shortDate( endDate ) );
192
193 endPicker->setDate( endDate.year(), endDate.month(), endDate.day() );
194}
195
196static QTime parseTime( const QString& s, bool ampm )
197{
198 QTime tmpTime;
199 QStringList l = QStringList::split( ':', s );
200 int hour = l[0].toInt();
201 if ( ampm ) {
202 int i=0;
203 while (i<int(l[1].length()) && l[1][i]>='0' && l[1][i]<='9')
204 i++;
205 QString digits = l[1].left(i);
206 if ( l[1].contains( "PM", FALSE ) ) {
207 if ( hour != 12 )
208 hour += 12;
209 } else {
210 if ( hour == 12 )
211 hour = 0;
212 }
213 l[1] = digits;
214 }
215 int minute = l[1].toInt();
216 if ( minute > 59 )
217 minute = 59;
218 else if ( minute < 0 )
219 minute = 0;
220 if ( hour > 23 ) {
221 hour = 23;
222 minute = 59;
223 } else if ( hour < 0 )
224 hour = 0;
225 tmpTime.setHMS( hour, minute, 0 );
226 return tmpTime;
227}
228
229/*
230 * public slot
231 */
232void DateEntry::endTimeChanged( const QString &s )
233{
234 QTime tmpTime = parseTime(s,ampm);
235 if ( endDate > startDate || tmpTime >= startTime ) {
236 endTime = tmpTime;
237 } else {
238 endTime = startTime;
239 comboEnd->setCurrentItem( comboStart->currentItem() );
240 }
241}
242
243/*
244 * public slot
245 */
246void DateEntry::startDateChanged( int y, int m, int d )
247{
248 QDate prev = startDate;
249 startDate.setYMD( y, m, d );
250 if ( rp.type == Event::Weekly &&
251 startDate.dayOfWeek() != prev.dayOfWeek() ) {
252 // if we change the start of a weekly repeating event
253 // set the repeating day appropriately
254 char mask = 1 << (prev.dayOfWeek()-1);
255 rp.days &= (~mask);
256 rp.days |= 1 << (startDate.dayOfWeek()-1);
257 }
258
259 buttonStart->setText( TimeString::shortDate( startDate ) );
260
261 // our pickers must be reset...
262 startPicker->setDate( y, m, d );
263 endPicker->setDate( y, m, d );
264}
265
266/*
267 * public slot
268 */
269void DateEntry::startTimeChanged( int index )
270{
271 startTime = parseTime(comboStart->text(index),ampm);
272 changeEndCombo( index );
273}
274/*
275 * public slot
276 */
277void DateEntry::typeChanged( const QString &s )
278{
279 bool b = s != "All Day";
280 buttonStart->setEnabled( b );
281 comboStart->setEnabled( b );
282 comboEnd->setEnabled( b );
283}
284/*
285 * public slot
286 */
287void DateEntry::changeEndCombo( int change )
288{
289 if ( change + 2 < comboEnd->count() )
290 change += 2;
291 comboEnd->setCurrentItem( change );
292 endTimeChanged( comboEnd->currentText() );
293}
294
295void DateEntry::slotRepeat()
296{
297 // Work around for compiler Bug..
298 RepeatEntry *e;
299
300 // it is better in my opinion to just grab this from the mother,
301 // since, this dialog doesn't need to keep track of it...
302 if ( rp.type != Event::NoRepeat )
303 e = new RepeatEntry( startWeekOnMonday, rp, startDate, this);
304 else
305 e = new RepeatEntry( startWeekOnMonday, startDate, this );
306
307#if defined(Q_WS_QWS) || defined(_WS_QWS_)
308 e->showMaximized();
309#endif
310 if ( e->exec() ) {
311 rp = e->repeatPattern();
312 setRepeatLabel();
313 }
314}
315
316void DateEntry::slotChangeStartOfWeek( bool onMonday )
317{
318 startWeekOnMonday = onMonday;
319}
320
321Event DateEntry::event()
322{
323 Event ev;
324 Event::SoundTypeChoice st;
325 ev.setDescription( comboDescription->currentText() );
326 ev.setLocation( comboLocation->currentText() );
327 ev.setCategories( comboCategory->currentCategories() );
328 ev.setType( checkAllDay->isChecked() ? Event::AllDay : Event::Normal );
329 if ( startDate > endDate ) {
330 QDate tmp = endDate;
331 endDate = startDate;
332 startDate = tmp;
333 }
334 startTime = parseTime( comboStart->currentText(), ampm );
335 endTime = parseTime( comboEnd->currentText(), ampm );
336 if ( startTime > endTime && endDate == startDate ) {
337 QTime tmp = endTime;
338 endTime = startTime;
339 startTime = tmp;
340 }
341 // don't set the time if theres no need too
342 if ( ev.type() == Event::AllDay ) {
343 startTime.setHMS( 0, 0, 0 );
344 endTime.setHMS( 23, 59, 59 );
345 }
346
347 // adjust start and end times based on timezone
348 QDateTime start( startDate, startTime );
349 QDateTime end( endDate, endTime );
350 time_t start_utc, end_utc;
351
352// qDebug( "tz: %s", timezone->currentZone().latin1() );
353
354 // get real timezone
355 QString realTZ;
356 realTZ = QString::fromLocal8Bit( getenv("TZ") );
357
358 // set timezone
359 if ( setenv( "TZ", timezone->currentZone(), true ) != 0 )
360 qWarning( "There was a problem setting the timezone." );
361
362 // convert to UTC based on selected TZ (calling tzset internally)
363 start_utc = TimeConversion::toUTC( start );
364 end_utc = TimeConversion::toUTC( end );
365
366 // done playing around... put it all back
367 unsetenv( "TZ" );
368 if ( !realTZ.isNull() )
369 if ( setenv( "TZ", realTZ, true ) != 0 )
370 qWarning( "There was a problem setting the timezone." );
371
372 // convert UTC to local time (calling tzset internally)
373 ev.setStart( TimeConversion::fromUTC( start_utc ) );
374 ev.setEnd( TimeConversion::fromUTC( end_utc ) );
375
376 // we only have one type of sound at the moment... LOUD!!!
377 if ( comboSound->currentItem() != 0 )
378 st = Event::Loud;
379 else
380 st = Event::Silent;
381 ev.setAlarm( checkAlarm->isChecked(), spinAlarm->value(), st );
382 if ( rp.type != Event::NoRepeat )
383 ev.setRepeat( TRUE, rp );
384 ev.setNotes( editNote->text() );
385 return ev;
386}
387
388void DateEntry::setRepeatLabel()
389{
390
391 switch( rp.type ) {
392 case Event::Daily:
393 cmdRepeat->setText( tr("Daily...") );
394 break;
395 case Event::Weekly:
396 cmdRepeat->setText( tr("Weekly...") );
397 break;
398 case Event::MonthlyDay:
399 case Event::MonthlyDate:
400 cmdRepeat->setText( tr("Monthly...") );
401 break;
402 case Event::Yearly:
403 cmdRepeat->setText( tr("Yearly...") );
404 break;
405 default:
406 cmdRepeat->setText( tr("No Repeat...") );
407 }
408}
409
410void DateEntry::setAlarmEnabled( bool alarmPreset, int presetTime, Event::SoundTypeChoice sound )
411{
412 checkAlarm->setChecked( alarmPreset );
413 spinAlarm->setValue( presetTime );
414 if ( sound != Event::Silent )
415 comboSound->setCurrentItem( 1 );
416 else
417 comboSound->setCurrentItem( 0 );
418}
419
420void DateEntry::initCombos()
421{
422 comboStart->clear();
423 comboEnd->clear();
424 if ( ampm ) {
425 for ( int i = 0; i < 24; i++ ) {
426 if ( i == 0 ) {
427 comboStart->insertItem( "12:00 AM" );
428 comboStart->insertItem( "12:30 AM" );
429 comboEnd->insertItem( "12:00 AM" );
430 comboEnd->insertItem( "12:30 AM" );
431 } else if ( i == 12 ) {
432 comboStart->insertItem( "12:00 PM" );
433 comboStart->insertItem( "12:30 PM" );
434 comboEnd->insertItem( "12:00 PM" );
435 comboEnd->insertItem( "12:30 PM" );
436 } else if ( i > 12 ) {
437 comboStart->insertItem( QString::number( i - 12 ) + ":00 PM" );
438 comboStart->insertItem( QString::number( i - 12 ) + ":30 PM" );
439 comboEnd->insertItem( QString::number( i - 12 ) + ":00 PM" );
440 comboEnd->insertItem( QString::number( i - 12 ) + ":30 PM" );
441 } else {
442 comboStart->insertItem( QString::number( i) + ":00 AM" );
443 comboStart->insertItem( QString::number( i ) + ":30 AM" );
444 comboEnd->insertItem( QString::number( i ) + ":00 AM" );
445 comboEnd->insertItem( QString::number( i ) + ":30 AM" );
446 }
447 }
448 } else {
449 for ( int i = 0; i < 24; i++ ) {
450 if ( i < 10 ) {
451 comboStart->insertItem( QString("0")
452 + QString::number(i) + ":00" );
453 comboStart->insertItem( QString("0")
454 + QString::number(i) + ":30" );
455 comboEnd->insertItem( QString("0")
456 + QString::number(i) + ":00" );
457 comboEnd->insertItem( QString("0")
458 + QString::number(i) + ":30" );
459 } else {
460 comboStart->insertItem( QString::number(i) + ":00" );
461 comboStart->insertItem( QString::number(i) + ":30" );
462 comboEnd->insertItem( QString::number(i) + ":00" );
463 comboEnd->insertItem( QString::number(i) + ":30" );
464 }
465 }
466 }
467}
468
469void DateEntry::slotChangeClock( bool whichClock )
470{
471 ampm = whichClock;
472 initCombos();
473 setDates( QDateTime( startDate, startTime ), QDateTime( endDate, endTime ) );
474}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef DATEENTRY_H
21#define DATEENTRY_H
22
23#include "dateentry.h"
24
25#include <qpe/event.h>
26
27#include <qdatetime.h>
28
29class DateBookMonth;
30
31class DateEntry : public DateEntryBase
32{
33 Q_OBJECT
34
35public:
36 DateEntry( bool startOnMonday, const QDateTime &start,
37 const QDateTime &end, bool whichClock = FALSE,
38 QWidget* parent = 0, const char* name = 0 );
39 DateEntry( bool startOnMonday, const Event &event, bool whichCLock = FALSE,
40 QWidget* parent = 0, const char* name = 0 );
41 ~DateEntry();
42
43 Event event();
44 void setAlarmEnabled( bool alarmPreset, int presetTime, Event::SoundTypeChoice );
45
46public slots:
47 void endDateChanged( int, int, int );
48 void endTimeChanged( const QString & );
49 void startDateChanged(int, int, int);
50 void startTimeChanged( int index );
51 void typeChanged( const QString & );
52 void changeEndCombo( int change );
53 void slotRepeat();
54 void slotChangeClock( bool );
55 void slotChangeStartOfWeek( bool );
56
57private:
58 void init();
59 void initCombos();
60 void setDates( const QDateTime& s, const QDateTime& e );
61 void setRepeatLabel();
62
63 DateBookMonth *startPicker, *endPicker;
64 QDate startDate, endDate;
65 QTime startTime, endTime;
66 Event::RepeatPattern rp;
67 bool ampm;
68 bool startWeekOnMonday;
69};
70
71#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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "datebook.h"
22#include <qpe/qpeapplication.h>
23
24
25int main( int argc, char **argv )
26{
27 QPEApplication a( argc, argv );
28
29 DateBook e;
30 QObject::connect( &a, SIGNAL( flush() ), &e, SLOT( flush() ) );
31 QObject::connect( &a, SIGNAL( reload() ), &e, SLOT( reload() ) );
32
33
34 e.setCaption( DateBook::tr("Calendar") );
35 a.showMainWidget(&e);
36
37 return a.exec();
38}
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 @@
1Files: bin/datebook apps/Applications/datebook.desktop
2Priority: optional
3Section: qpe/applications
4Maintainer: Warwick Allison <warwick@trolltech.com>
5Architecture: arm
6Version: $QPE_VERSION-3
7Depends: qpe-base ($QPE_VERSION)
8Description: A datebook/appointment manager
9 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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "repeatentry.h"
22
23#include <qpe/datebookmonth.h>
24#include <qpe/qpeapplication.h>
25#include <qpe/timestring.h>
26
27#include <qbuttongroup.h>
28#include <qlabel.h>
29#include <qpopupmenu.h>
30#include <qspinbox.h>
31#include <qtoolbutton.h>
32
33#include <time.h>
34
35// Global Templates for use in setting up the repeat label...
36const QString strDayTemplate = QObject::tr("Every");
37const QString strYearTemplate = QObject::tr("%1 %2 every ");
38const QString strMonthDateTemplate = QObject::tr("The %1 every ");
39const QString strMonthDayTemplate = QObject::tr("The %1 %1 of every");
40const QString strWeekTemplate = QObject::tr("Every ");
41const QString dayLabel[] = { QObject::tr("Monday"),
42 QObject::tr("Tuesday"),
43 QObject::tr("Wednesday"),
44 QObject::tr("Thursday"),
45 QObject::tr("Friday"),
46 QObject::tr("Saturday"),
47 QObject::tr("Sunday") };
48
49
50 static QString numberPlacing( int x );// return the proper word format for
51 // x (1st, 2nd, etc)
52static int week( const QDate &dt ); // what week in the month is dt?
53
54RepeatEntry::RepeatEntry( bool startOnMonday,
55 const QDate &newStart, QWidget *parent,
56 const char *name, bool modal, WFlags fl )
57 : RepeatEntryBase( parent, name, modal, fl ),
58 start( newStart ),
59 currInterval( NONE ),
60 startWeekOnMonday( startOnMonday )
61{
62 init();
63 fraType->setButton( currInterval );
64 chkNoEnd->setChecked( TRUE );
65 setupNone();
66}
67
68RepeatEntry::RepeatEntry( bool startOnMonday, const Event::RepeatPattern &rp,
69 const QDate &startDate,
70 QWidget *parent, const char *name, bool modal,
71 WFlags fl )
72 : RepeatEntryBase( parent, name, modal, fl ),
73 start( startDate ),
74 end( rp.endDate() ),
75 startWeekOnMonday( startOnMonday )
76{
77 // do some stuff with the repeat pattern
78 init();
79 switch ( rp.type ) {
80 default:
81 case Event::NoRepeat:
82 currInterval = NONE;
83 setupNone();
84 break;
85 case Event::Daily:
86 currInterval = DAY;
87 setupDaily();
88 break;
89 case Event::Weekly:
90 currInterval = WEEK;
91 setupWeekly();
92 int day, buttons;
93 for ( day = 0x01, buttons = 0; buttons < 7;
94 day = day << 1, buttons++ ) {
95 if ( rp.days & day ) {
96 if ( startWeekOnMonday )
97 fraExtra->setButton( buttons );
98 else {
99 if ( buttons == 7 )
100 fraExtra->setButton( 0 );
101 else
102 fraExtra->setButton( buttons + 1 );
103 }
104 }
105 }
106 slotWeekLabel();
107 break;
108 case Event::MonthlyDay:
109 currInterval = MONTH;
110 setupMonthly();
111 fraExtra->setButton( 0 );
112 slotMonthLabel( 0 );
113 break;
114 case Event::MonthlyDate:
115 currInterval = MONTH;
116 setupMonthly();
117 fraExtra->setButton( 1 );
118 slotMonthLabel( 1 );
119 break;
120 case Event::Yearly:
121 currInterval = YEAR;
122 setupYearly();
123 break;
124 }
125 fraType->setButton( currInterval );
126 spinFreq->setValue( rp.frequency );
127 if ( !rp.hasEndDate ) {
128 cmdEnd->setText( RepeatEntryBase::tr("No End Date") );
129 chkNoEnd->setChecked( TRUE );
130 } else
131 cmdEnd->setText( TimeString::shortDate( end ) );
132}
133
134RepeatEntry::~RepeatEntry()
135{
136}
137
138Event::RepeatPattern RepeatEntry::repeatPattern()
139{
140 QListIterator<QToolButton> it( listRTypeButtons );
141 QListIterator<QToolButton> itExtra( listExtra );
142 Event::RepeatPattern rpTmp;
143 int i;
144 for ( i = 0; *it; ++it, i++ ) {
145 if ( (*it)->isOn() ) {
146 switch ( i ) {
147 case NONE:
148 rpTmp.type = Event::NoRepeat;
149 break;
150 case DAY:
151 rpTmp.type = Event::Daily;
152 break;
153 case WEEK:
154 rpTmp.type = Event::Weekly;
155 rpTmp.days = 0;
156 int day;
157 for ( day = 1; *itExtra; ++itExtra, day = day << 1 ) {
158 if ( (*itExtra)->isOn() ) {
159 if ( startWeekOnMonday )
160 rpTmp.days |= day;
161 else {
162 if ( day == 1 )
163 rpTmp.days |= Event::SUN;
164 else
165 rpTmp.days |= day >> 1;
166 }
167 }
168 }
169 break;
170 case MONTH:
171 if ( cmdExtra1->isOn() )
172 rpTmp.type = Event::MonthlyDay;
173 else if ( cmdExtra2->isOn() )
174 rpTmp.type = Event::MonthlyDate;
175 // figure out the montly day...
176 rpTmp.position = week( start );
177 break;
178 case YEAR:
179 rpTmp.type = Event::Yearly;
180 break;
181 }
182 break; // no need to keep looking!
183 }
184 }
185 rpTmp.frequency = spinFreq->value();
186 rpTmp.hasEndDate = !chkNoEnd->isChecked();
187 if ( rpTmp.hasEndDate ) {
188 rpTmp.setEndDate( end );
189 }
190 // timestamp it...
191 rpTmp.createTime = time( NULL );
192 return rpTmp;
193}
194
195void RepeatEntry::slotSetRType( int rtype )
196{
197 // now call the right function based on the type...
198 currInterval = static_cast<repeatButtons>(rtype);
199 switch ( currInterval ) {
200 case NONE:
201 setupNone();
202 break;
203 case DAY:
204 setupDaily();
205 break;
206 case WEEK:
207 setupWeekly();
208 slotWeekLabel();
209 break;
210 case MONTH:
211 setupMonthly();
212 cmdExtra2->setOn( TRUE );
213 slotMonthLabel( 1 );
214 break;
215 case YEAR:
216 setupYearly();
217 break;
218 }
219}
220
221void RepeatEntry::setupNone()
222{
223 lblRepeat->setText( tr("No Repeat") );
224 lblVar1->hide();
225 lblVar2->hide();
226 hideExtras();
227 cmdEnd->hide();
228 lblFreq->hide();
229 lblEvery->hide();
230 lblFreq->hide();
231 spinFreq->hide();
232 lblEnd->hide();
233 lblWeekVar->hide();
234}
235
236void RepeatEntry::setupDaily()
237{
238 hideExtras();
239 lblWeekVar->hide();
240 spinFreq->setValue( 1 );
241 lblFreq->setText( tr("day(s)") );
242 lblVar2->show();
243 showRepeatStuff();
244 lblRepeat->setText( strDayTemplate );
245 setupRepeatLabel( 1 );
246}
247
248void RepeatEntry::setupWeekly()
249{
250 // reshow the buttons...
251 fraExtra->setTitle( RepeatEntryBase::tr("Repeat On") );
252 fraExtra->setExclusive( FALSE );
253 fraExtra->show();
254 if ( startWeekOnMonday ) {
255 cmdExtra1->setText( RepeatEntryBase::tr("Mon") );
256 cmdExtra2->setText( RepeatEntryBase::tr("Tue") );
257 cmdExtra3->setText( RepeatEntryBase::tr("Wed") );
258 cmdExtra4->setText( RepeatEntryBase::tr("Thu") );
259 cmdExtra5->setText( RepeatEntryBase::tr("Fri") );
260 cmdExtra6->setText( RepeatEntryBase::tr("Sat") );
261 cmdExtra7->setText( RepeatEntryBase::tr("Sun") );
262 } else {
263 cmdExtra1->setText( RepeatEntryBase::tr("Sun") );
264 cmdExtra2->setText( RepeatEntryBase::tr("Mon") );
265 cmdExtra3->setText( RepeatEntryBase::tr("Tue") );
266 cmdExtra4->setText( RepeatEntryBase::tr("Wed") );
267 cmdExtra5->setText( RepeatEntryBase::tr("Thu") );
268 cmdExtra6->setText( RepeatEntryBase::tr("Fri") );
269 cmdExtra7->setText( RepeatEntryBase::tr("Sat") );
270 }
271 // I hope clustering these improve performance....
272 cmdExtra1->setOn( FALSE );
273 cmdExtra2->setOn( FALSE );
274 cmdExtra3->setOn( FALSE );
275 cmdExtra4->setOn( FALSE );
276 cmdExtra5->setOn( FALSE );
277 cmdExtra6->setOn( FALSE );
278 cmdExtra7->setOn( FALSE );
279
280 cmdExtra1->show();
281 cmdExtra2->show();
282 cmdExtra3->show();
283 cmdExtra4->show();
284 cmdExtra5->show();
285 cmdExtra6->show();
286 cmdExtra7->show();
287
288 lblWeekVar->show();
289 spinFreq->setValue( 1 );
290 // might as well set the day too...
291 if ( startWeekOnMonday ) {
292 fraExtra->setButton( start.dayOfWeek() - 1 );
293 } else {
294 fraExtra->setButton( start.dayOfWeek() % 7 );
295 }
296 lblFreq->setText( tr("week(s)") );
297 lblVar2->show();
298 showRepeatStuff();
299 setupRepeatLabel( 1 );
300}
301
302void RepeatEntry::setupMonthly()
303{
304 hideExtras();
305 lblWeekVar->hide();
306 fraExtra->setTitle( tr("Repeat By") );
307 fraExtra->setExclusive( TRUE );
308 fraExtra->show();
309 cmdExtra1->setText( tr("Day") );
310 cmdExtra1->show();
311 cmdExtra2->setText( tr("Date") );
312 cmdExtra2->show();
313 spinFreq->setValue( 1 );
314 lblFreq->setText( tr("month(s)") );
315 lblVar2->show();
316 showRepeatStuff();
317 setupRepeatLabel( 1 );
318}
319
320void RepeatEntry::setupYearly()
321{
322 hideExtras();
323 lblWeekVar->hide();
324 spinFreq->setValue( 1 );
325 lblFreq->setText( tr("year(s)") );
326 lblFreq->show();
327 lblFreq->show();
328 showRepeatStuff();
329 lblVar2->show();
330 QString strEvery = strYearTemplate.arg( start.monthName(start.month()) ).arg( numberPlacing(start.day()) );
331 lblRepeat->setText( strEvery );
332 setupRepeatLabel( 1 );
333
334}
335
336void RepeatEntry::init()
337{
338 QPopupMenu *m1 = new QPopupMenu( this );
339 repeatPicker = new DateBookMonth( m1, 0, TRUE );
340 m1->insertItem( repeatPicker );
341 cmdEnd->setPopup( m1 );
342 cmdEnd->setPopupDelay( 0 );
343
344 QObject::connect( repeatPicker, SIGNAL(dateClicked(int, int, int)),
345 this, SLOT(endDateChanged(int, int, int)) );
346 QObject::connect( qApp, SIGNAL(weekChanged(bool)),
347 this, SLOT(slotChangeStartOfWeek(bool)) );
348
349 listRTypeButtons.setAutoDelete( TRUE );
350 listRTypeButtons.append( cmdNone );
351 listRTypeButtons.append( cmdDay );
352 listRTypeButtons.append( cmdWeek );
353 listRTypeButtons.append( cmdMonth );
354 listRTypeButtons.append( cmdYear );
355
356 listExtra.setAutoDelete( TRUE );
357 listExtra.append( cmdExtra1 );
358 listExtra.append( cmdExtra2 );
359 listExtra.append( cmdExtra3 );
360 listExtra.append( cmdExtra4 );
361 listExtra.append( cmdExtra5 );
362 listExtra.append( cmdExtra6 );
363 listExtra.append( cmdExtra7 );
364}
365
366void RepeatEntry::slotNoEnd( bool unused )
367{
368 // if the item was toggled, then go ahead and set it to the maximum date
369 if ( unused ) {
370 end.setYMD( 3000, 12, 31 );
371 cmdEnd->setText( RepeatEntryBase::tr("No End Date") );
372 } else {
373 end = start;
374 cmdEnd->setText( TimeString::shortDate(end) );
375 }
376}
377
378void RepeatEntry::endDateChanged( int y, int m, int d )
379{
380 end.setYMD( y, m, d );
381 if ( end < start )
382 end = start;
383 cmdEnd->setText( TimeString::shortDate( end ) );
384 repeatPicker->setDate( end.year(), end.month(), end.day() );
385}
386
387void RepeatEntry::setupRepeatLabel( const QString &s )
388{
389 lblVar1->setText( s );
390}
391
392void RepeatEntry::setupRepeatLabel( int x )
393{
394 // change the spelling based on the value of x
395 QString strVar2;
396
397 if ( x > 1 )
398 lblVar1->show();
399 else
400 lblVar1->hide();
401
402 switch ( currInterval ) {
403 case NONE:
404 break;
405 case DAY:
406 if ( x > 1 )
407 strVar2 = tr( "days" );
408 else
409 strVar2 = tr( "day" );
410 break;
411 case WEEK:
412 if ( x > 1 )
413 strVar2 = tr( "weeks" );
414 else
415 strVar2 = tr( "week" );
416 break;
417 case MONTH:
418 if ( x > 1 )
419 strVar2 = RepeatEntryBase::tr( "months" );
420 else
421 strVar2 = tr( "month" );
422 break;
423 case YEAR:
424 if ( x > 1 )
425 strVar2 = RepeatEntryBase::tr( "years" );
426 else
427 strVar2 = tr( "year" );
428 break;
429 }
430 if ( !strVar2.isNull() )
431 lblVar2->setText( strVar2 );
432}
433
434void RepeatEntry::showRepeatStuff()
435{
436 cmdEnd->show();
437 chkNoEnd->show();
438 lblFreq->show();
439 lblEvery->show();
440 lblFreq->show();
441 spinFreq->show();
442 lblEnd->show();
443 lblRepeat->setText( RepeatEntryBase::tr("Every") );
444}
445
446void RepeatEntry::slotWeekLabel()
447{
448 QString str;
449 QListIterator<QToolButton> it( listExtra );
450 unsigned int i;
451 unsigned int keepMe;
452 bool bNeedCarriage = FALSE;
453 // don't do something we'll regret!!!
454 if ( currInterval != WEEK )
455 return;
456
457 if ( startWeekOnMonday )
458 keepMe = start.dayOfWeek() - 1;
459 else
460 keepMe = start.dayOfWeek() % 7;
461
462 QStringList list;
463 for ( i = 0; *it; ++it, i++ ) {
464 // a crazy check, if you are repeating weekly, the current day
465 // must be selected!!!
466 if ( i == keepMe && !( (*it)->isOn() ) )
467 (*it)->setOn( TRUE );
468 if ( (*it)->isOn() ) {
469 if ( startWeekOnMonday )
470 list.append( dayLabel[i] );
471 else {
472 if ( i == 0 )
473 list.append( dayLabel[6] );
474 else
475 list.append( dayLabel[i - 1] );
476 }
477 }
478 }
479 QStringList::Iterator itStr;
480 for ( i = 0, itStr = list.begin(); itStr != list.end(); ++itStr, i++ ) {
481 if ( i == 3 )
482 bNeedCarriage = TRUE;
483 else
484 bNeedCarriage = FALSE;
485 if ( str.isNull() )
486 str = *itStr;
487 else if ( i == list.count() - 1 ) {
488 if ( i < 2 )
489 str += tr(" and ") + *itStr;
490 else {
491 if ( bNeedCarriage )
492 str += tr( ",\nand " ) + *itStr;
493 else
494 str += tr( ", and " ) + *itStr;
495 }
496 } else {
497 if ( bNeedCarriage )
498 str += ",\n" + *itStr;
499 else
500 str += ", " + *itStr;
501 }
502 }
503 str = str.prepend( "on " );
504 lblWeekVar->setText( str );
505}
506
507void RepeatEntry::slotMonthLabel( int type )
508{
509 QString str;
510 if ( currInterval != MONTH || type > 1 )
511 return;
512 if ( type == 1 )
513 str = strMonthDateTemplate.arg( numberPlacing(start.day()) );
514 else
515 str = strMonthDayTemplate.arg( numberPlacing(week(start)))
516 .arg( dayLabel[start.dayOfWeek() - 1] );
517 lblRepeat->setText( str );
518}
519
520void RepeatEntry::slotChangeStartOfWeek( bool onMonday )
521{
522 startWeekOnMonday = onMonday;
523 // we need to make this unintrusive as possible...
524 int saveSpin = spinFreq->value();
525 char days = 0;
526 int day;
527 QListIterator<QToolButton> itExtra( listExtra );
528 for ( day = 1; *itExtra; ++itExtra, day = day << 1 ) {
529 if ( (*itExtra)->isOn() ) {
530 if ( !startWeekOnMonday )
531 days |= day;
532 else {
533 if ( day == 1 )
534 days |= Event::SUN;
535 else
536 days |= day >> 1;
537 }
538 }
539 }
540 setupWeekly();
541 spinFreq->setValue( saveSpin );
542 int buttons;
543 for ( day = 0x01, buttons = 0; buttons < 7;
544 day = day << 1, buttons++ ) {
545 if ( days & day ) {
546 if ( startWeekOnMonday )
547 fraExtra->setButton( buttons );
548 else {
549 if ( buttons == 7 )
550 fraExtra->setButton( 0 );
551 else
552 fraExtra->setButton( buttons + 1 );
553 }
554 }
555 }
556 slotWeekLabel();
557}
558
559static int week( const QDate &start )
560{
561 // figure out the week...
562 int stop = start.day(),
563 sentinel = start.dayOfWeek(),
564 dayOfWeek = QDate( start.year(), start.month(), 1 ).dayOfWeek(),
565 week = 1,
566 i;
567 for ( i = 1; i < stop; i++ ) {
568 if ( dayOfWeek++ == sentinel )
569 week++;
570 if ( dayOfWeek > 7 )
571 dayOfWeek = 0;
572 }
573 return week;
574}
575
576static QString numberPlacing( int x )
577{
578 // I hope this works in other languages besides english...
579 QString str = QString::number( x );
580 switch ( x % 10 ) {
581 case 1:
582 str += QWidget::tr( "st" );
583 break;
584 case 2:
585 str += QWidget::tr( "nd" );
586 break;
587 case 3:
588 str += QWidget::tr( "rd" );
589 break;
590 default:
591 str += QWidget::tr( "th" );
592 break;
593 }
594 return str;
595}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#ifndef REPEATENTRY_H
22#define REPEATENTRY_H
23
24#include "repeatentrybase.h"
25
26#include <qpe/event.h>
27
28#include <qcheckbox.h>
29#include <qbuttongroup.h>
30#include <qdatetime.h>
31#include <qlist.h>
32#include <qtoolbutton.h>
33
34class DateBookMonth;
35
36class RepeatEntry : public RepeatEntryBase
37{
38 Q_OBJECT
39public:
40 RepeatEntry( bool startOnMonday,
41 const QDate &start, QWidget *parent = 0, const char *name = 0,
42 bool modal = TRUE, WFlags fl = 0 );
43 RepeatEntry( bool startOnMonday,
44 const Event::RepeatPattern &rp, const QDate &start,
45 QWidget *parent = 0, const char *name = 0, bool modal = TRUE,
46 WFlags fl = 0 );
47 ~RepeatEntry();
48
49 Event::RepeatPattern repeatPattern();
50 QDate endDate() { return end; };
51
52public slots:
53 void slotSetRType( int );
54 void endDateChanged( int, int, int );
55 void slotNoEnd( bool unused );
56
57private slots:
58 void setupRepeatLabel( const QString& );
59 void setupRepeatLabel( int );
60 void slotWeekLabel();
61 void slotMonthLabel( int );
62 void slotChangeStartOfWeek( bool onMonday );
63
64private:
65 void setupNone();
66 void setupDaily();
67 void setupWeekly();
68 void setupMonthly();
69 void setupYearly();
70
71 enum repeatButtons { NONE, DAY, WEEK, MONTH, YEAR };
72 void init();
73 inline void hideExtras();
74 void showRepeatStuff();
75
76 QList<QToolButton> listRTypeButtons;
77 QList<QToolButton> listExtra;
78 QDate start; // only used in one spot...
79 QDate end;
80 repeatButtons currInterval;
81 bool startWeekOnMonday;
82 DateBookMonth *repeatPicker;
83};
84
85inline void RepeatEntry::hideExtras()
86{
87 // hide the extra buttons...
88 fraExtra->hide();
89 chkNoEnd->hide();
90 QListIterator<QToolButton> it( listExtra );
91 for ( ; *it; ++it ) {
92 (*it)->hide();
93 (*it)->setOn( FALSE );
94 }
95
96}
97
98#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 @@
1<!DOCTYPE UI><UI>
2<class>RepeatEntryBase</class>
3<comment>*********************************************************************
4** Copyright (C) 2000 Trolltech AS. All rights reserved.
5**
6** This file is part of Qtopia Environment.
7**
8** This file may be distributed and/or modified under the terms of the
9** GNU General Public License version 2 as published by the Free Software
10** Foundation and appearing in the file LICENSE.GPL included in the
11** packaging of this file.
12**
13** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
14** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
15**
16** See http://www.trolltech.com/gpl/ for GPL licensing information.
17**
18** Contact info@trolltech.com if any conditions of this licensing are
19** not clear to you.
20**
21** $Id$
22**
23*********************************************************************</comment>
24<widget>
25 <class>QDialog</class>
26 <property stdset="1">
27 <name>name</name>
28 <cstring>RepeatEntryBase</cstring>
29 </property>
30 <property stdset="1">
31 <name>geometry</name>
32 <rect>
33 <x>0</x>
34 <y>0</y>
35 <width>250</width>
36 <height>309</height>
37 </rect>
38 </property>
39 <property stdset="1">
40 <name>caption</name>
41 <string>Repeating Event </string>
42 </property>
43 <property>
44 <name>layoutMargin</name>
45 </property>
46 <property>
47 <name>layoutSpacing</name>
48 </property>
49 <vbox>
50 <property stdset="1">
51 <name>margin</name>
52 <number>5</number>
53 </property>
54 <property stdset="1">
55 <name>spacing</name>
56 <number>1</number>
57 </property>
58 <widget>
59 <class>QButtonGroup</class>
60 <property stdset="1">
61 <name>name</name>
62 <cstring>fraType</cstring>
63 </property>
64 <property stdset="1">
65 <name>frameShape</name>
66 <enum>NoFrame</enum>
67 </property>
68 <property stdset="1">
69 <name>frameShadow</name>
70 <enum>Sunken</enum>
71 </property>
72 <property stdset="1">
73 <name>title</name>
74 <string></string>
75 </property>
76 <property stdset="1">
77 <name>exclusive</name>
78 <bool>true</bool>
79 </property>
80 <property>
81 <name>layoutMargin</name>
82 </property>
83 <property>
84 <name>layoutSpacing</name>
85 </property>
86 <hbox>
87 <property stdset="1">
88 <name>margin</name>
89 <number>5</number>
90 </property>
91 <property stdset="1">
92 <name>spacing</name>
93 <number>1</number>
94 </property>
95 <widget>
96 <class>QToolButton</class>
97 <property stdset="1">
98 <name>name</name>
99 <cstring>cmdNone</cstring>
100 </property>
101 <property stdset="1">
102 <name>text</name>
103 <string>None</string>
104 </property>
105 <property stdset="1">
106 <name>toggleButton</name>
107 <bool>true</bool>
108 </property>
109 <property stdset="1">
110 <name>toggleButton</name>
111 <bool>true</bool>
112 </property>
113 </widget>
114 <widget>
115 <class>QToolButton</class>
116 <property stdset="1">
117 <name>name</name>
118 <cstring>cmdDay</cstring>
119 </property>
120 <property stdset="1">
121 <name>text</name>
122 <string>Day</string>
123 </property>
124 <property stdset="1">
125 <name>toggleButton</name>
126 <bool>true</bool>
127 </property>
128 <property stdset="1">
129 <name>toggleButton</name>
130 <bool>true</bool>
131 </property>
132 </widget>
133 <widget>
134 <class>QToolButton</class>
135 <property stdset="1">
136 <name>name</name>
137 <cstring>cmdWeek</cstring>
138 </property>
139 <property stdset="1">
140 <name>sizePolicy</name>
141 <sizepolicy>
142 <hsizetype>1</hsizetype>
143 <vsizetype>0</vsizetype>
144 </sizepolicy>
145 </property>
146 <property stdset="1">
147 <name>text</name>
148 <string>Week</string>
149 </property>
150 <property stdset="1">
151 <name>toggleButton</name>
152 <bool>true</bool>
153 </property>
154 <property stdset="1">
155 <name>toggleButton</name>
156 <bool>true</bool>
157 </property>
158 </widget>
159 <widget>
160 <class>QToolButton</class>
161 <property stdset="1">
162 <name>name</name>
163 <cstring>cmdMonth</cstring>
164 </property>
165 <property stdset="1">
166 <name>sizePolicy</name>
167 <sizepolicy>
168 <hsizetype>1</hsizetype>
169 <vsizetype>0</vsizetype>
170 </sizepolicy>
171 </property>
172 <property stdset="1">
173 <name>text</name>
174 <string>Month</string>
175 </property>
176 <property stdset="1">
177 <name>toggleButton</name>
178 <bool>true</bool>
179 </property>
180 <property stdset="1">
181 <name>toggleButton</name>
182 <bool>true</bool>
183 </property>
184 </widget>
185 <widget>
186 <class>QToolButton</class>
187 <property stdset="1">
188 <name>name</name>
189 <cstring>cmdYear</cstring>
190 </property>
191 <property stdset="1">
192 <name>text</name>
193 <string>Year</string>
194 </property>
195 <property stdset="1">
196 <name>toggleButton</name>
197 <bool>true</bool>
198 </property>
199 <property stdset="1">
200 <name>toggleButton</name>
201 <bool>true</bool>
202 </property>
203 </widget>
204 </hbox>
205 </widget>
206 <widget>
207 <class>QLayoutWidget</class>
208 <property stdset="1">
209 <name>name</name>
210 <cstring>Layout4</cstring>
211 </property>
212 <hbox>
213 <property stdset="1">
214 <name>margin</name>
215 <number>0</number>
216 </property>
217 <property stdset="1">
218 <name>spacing</name>
219 <number>6</number>
220 </property>
221 <widget>
222 <class>QLabel</class>
223 <property stdset="1">
224 <name>name</name>
225 <cstring>lblEvery</cstring>
226 </property>
227 <property stdset="1">
228 <name>text</name>
229 <string>Every:</string>
230 </property>
231 </widget>
232 <widget>
233 <class>QSpinBox</class>
234 <property stdset="1">
235 <name>name</name>
236 <cstring>spinFreq</cstring>
237 </property>
238 <property stdset="1">
239 <name>minValue</name>
240 <number>1</number>
241 </property>
242 </widget>
243 <widget>
244 <class>QLabel</class>
245 <property stdset="1">
246 <name>name</name>
247 <cstring>lblFreq</cstring>
248 </property>
249 <property stdset="1">
250 <name>sizePolicy</name>
251 <sizepolicy>
252 <hsizetype>1</hsizetype>
253 <vsizetype>1</vsizetype>
254 </sizepolicy>
255 </property>
256 <property stdset="1">
257 <name>text</name>
258 <string>Frequency</string>
259 </property>
260 </widget>
261 </hbox>
262 </widget>
263 <widget>
264 <class>QLayoutWidget</class>
265 <property stdset="1">
266 <name>name</name>
267 <cstring>Layout8</cstring>
268 </property>
269 <hbox>
270 <property stdset="1">
271 <name>margin</name>
272 <number>0</number>
273 </property>
274 <property stdset="1">
275 <name>spacing</name>
276 <number>6</number>
277 </property>
278 <widget>
279 <class>QLabel</class>
280 <property stdset="1">
281 <name>name</name>
282 <cstring>lblEnd</cstring>
283 </property>
284 <property stdset="1">
285 <name>sizePolicy</name>
286 <sizepolicy>
287 <hsizetype>1</hsizetype>
288 <vsizetype>0</vsizetype>
289 </sizepolicy>
290 </property>
291 <property stdset="1">
292 <name>text</name>
293 <string>End On:</string>
294 </property>
295 </widget>
296 <widget>
297 <class>QToolButton</class>
298 <property stdset="1">
299 <name>name</name>
300 <cstring>cmdEnd</cstring>
301 </property>
302 <property stdset="1">
303 <name>text</name>
304 <string>No End Date</string>
305 </property>
306 </widget>
307 <widget>
308 <class>QCheckBox</class>
309 <property stdset="1">
310 <name>name</name>
311 <cstring>chkNoEnd</cstring>
312 </property>
313 <property stdset="1">
314 <name>text</name>
315 <string>No End Date</string>
316 </property>
317 </widget>
318 </hbox>
319 </widget>
320 <widget>
321 <class>QButtonGroup</class>
322 <property stdset="1">
323 <name>name</name>
324 <cstring>fraExtra</cstring>
325 </property>
326 <property stdset="1">
327 <name>sizePolicy</name>
328 <sizepolicy>
329 <hsizetype>7</hsizetype>
330 <vsizetype>7</vsizetype>
331 </sizepolicy>
332 </property>
333 <property stdset="1">
334 <name>frameShape</name>
335 <enum>Box</enum>
336 </property>
337 <property stdset="1">
338 <name>title</name>
339 <string>Repeat On</string>
340 </property>
341 <property>
342 <name>layoutMargin</name>
343 </property>
344 <property>
345 <name>layoutSpacing</name>
346 </property>
347 <hbox>
348 <property stdset="1">
349 <name>margin</name>
350 <number>5</number>
351 </property>
352 <property stdset="1">
353 <name>spacing</name>
354 <number>1</number>
355 </property>
356 <widget>
357 <class>QToolButton</class>
358 <property stdset="1">
359 <name>name</name>
360 <cstring>cmdExtra1</cstring>
361 </property>
362 <property stdset="1">
363 <name>text</name>
364 <string>Mon</string>
365 </property>
366 <property stdset="1">
367 <name>toggleButton</name>
368 <bool>true</bool>
369 </property>
370 <property stdset="1">
371 <name>toggleButton</name>
372 <bool>true</bool>
373 </property>
374 </widget>
375 <widget>
376 <class>QToolButton</class>
377 <property stdset="1">
378 <name>name</name>
379 <cstring>cmdExtra2</cstring>
380 </property>
381 <property stdset="1">
382 <name>text</name>
383 <string>Tue</string>
384 </property>
385 <property stdset="1">
386 <name>toggleButton</name>
387 <bool>true</bool>
388 </property>
389 <property stdset="1">
390 <name>toggleButton</name>
391 <bool>true</bool>
392 </property>
393 </widget>
394 <widget>
395 <class>QToolButton</class>
396 <property stdset="1">
397 <name>name</name>
398 <cstring>cmdExtra3</cstring>
399 </property>
400 <property stdset="1">
401 <name>text</name>
402 <string>Wed</string>
403 </property>
404 <property stdset="1">
405 <name>toggleButton</name>
406 <bool>true</bool>
407 </property>
408 <property stdset="1">
409 <name>toggleButton</name>
410 <bool>true</bool>
411 </property>
412 </widget>
413 <widget>
414 <class>QToolButton</class>
415 <property stdset="1">
416 <name>name</name>
417 <cstring>cmdExtra4</cstring>
418 </property>
419 <property stdset="1">
420 <name>text</name>
421 <string>Thu</string>
422 </property>
423 <property stdset="1">
424 <name>toggleButton</name>
425 <bool>true</bool>
426 </property>
427 <property stdset="1">
428 <name>toggleButton</name>
429 <bool>true</bool>
430 </property>
431 </widget>
432 <widget>
433 <class>QToolButton</class>
434 <property stdset="1">
435 <name>name</name>
436 <cstring>cmdExtra5</cstring>
437 </property>
438 <property stdset="1">
439 <name>text</name>
440 <string>Fri</string>
441 </property>
442 <property stdset="1">
443 <name>toggleButton</name>
444 <bool>true</bool>
445 </property>
446 <property stdset="1">
447 <name>toggleButton</name>
448 <bool>true</bool>
449 </property>
450 </widget>
451 <widget>
452 <class>QToolButton</class>
453 <property stdset="1">
454 <name>name</name>
455 <cstring>cmdExtra6</cstring>
456 </property>
457 <property stdset="1">
458 <name>text</name>
459 <string>Sat</string>
460 </property>
461 <property stdset="1">
462 <name>toggleButton</name>
463 <bool>true</bool>
464 </property>
465 <property stdset="1">
466 <name>toggleButton</name>
467 <bool>true</bool>
468 </property>
469 </widget>
470 <widget>
471 <class>QToolButton</class>
472 <property stdset="1">
473 <name>name</name>
474 <cstring>cmdExtra7</cstring>
475 </property>
476 <property stdset="1">
477 <name>text</name>
478 <string>Sun</string>
479 </property>
480 <property stdset="1">
481 <name>toggleButton</name>
482 <bool>true</bool>
483 </property>
484 <property stdset="1">
485 <name>toggleButton</name>
486 <bool>true</bool>
487 </property>
488 </widget>
489 </hbox>
490 </widget>
491 <widget>
492 <class>QFrame</class>
493 <property stdset="1">
494 <name>name</name>
495 <cstring>Frame3</cstring>
496 </property>
497 <property stdset="1">
498 <name>sizePolicy</name>
499 <sizepolicy>
500 <hsizetype>7</hsizetype>
501 <vsizetype>7</vsizetype>
502 </sizepolicy>
503 </property>
504 <property stdset="1">
505 <name>frameShape</name>
506 <enum>Box</enum>
507 </property>
508 <property stdset="1">
509 <name>frameShadow</name>
510 <enum>Sunken</enum>
511 </property>
512 <property>
513 <name>layoutMargin</name>
514 </property>
515 <property>
516 <name>layoutSpacing</name>
517 </property>
518 <vbox>
519 <property stdset="1">
520 <name>margin</name>
521 <number>5</number>
522 </property>
523 <property stdset="1">
524 <name>spacing</name>
525 <number>1</number>
526 </property>
527 <widget>
528 <class>QLayoutWidget</class>
529 <property stdset="1">
530 <name>name</name>
531 <cstring>Layout6</cstring>
532 </property>
533 <property>
534 <name>layoutSpacing</name>
535 </property>
536 <hbox>
537 <property stdset="1">
538 <name>margin</name>
539 <number>0</number>
540 </property>
541 <property stdset="1">
542 <name>spacing</name>
543 <number>0</number>
544 </property>
545 <widget>
546 <class>QLabel</class>
547 <property stdset="1">
548 <name>name</name>
549 <cstring>lblRepeat</cstring>
550 </property>
551 <property stdset="1">
552 <name>sizePolicy</name>
553 <sizepolicy>
554 <hsizetype>1</hsizetype>
555 <vsizetype>3</vsizetype>
556 </sizepolicy>
557 </property>
558 <property stdset="1">
559 <name>text</name>
560 <string>Every</string>
561 </property>
562 <property stdset="1">
563 <name>alignment</name>
564 <set>AlignTop|AlignLeft</set>
565 </property>
566 <property>
567 <name>hAlign</name>
568 </property>
569 <property>
570 <name>vAlign</name>
571 </property>
572 </widget>
573 <widget>
574 <class>QLabel</class>
575 <property stdset="1">
576 <name>name</name>
577 <cstring>lblVar1</cstring>
578 </property>
579 <property stdset="1">
580 <name>sizePolicy</name>
581 <sizepolicy>
582 <hsizetype>1</hsizetype>
583 <vsizetype>1</vsizetype>
584 </sizepolicy>
585 </property>
586 <property stdset="1">
587 <name>text</name>
588 <string>Var1</string>
589 </property>
590 <property stdset="1">
591 <name>alignment</name>
592 <set>AlignTop|AlignLeft</set>
593 </property>
594 <property>
595 <name>hAlign</name>
596 </property>
597 <property>
598 <name>vAlign</name>
599 </property>
600 </widget>
601 <widget>
602 <class>QLabel</class>
603 <property stdset="1">
604 <name>name</name>
605 <cstring>lblVar2</cstring>
606 </property>
607 <property stdset="1">
608 <name>sizePolicy</name>
609 <sizepolicy>
610 <hsizetype>4</hsizetype>
611 <vsizetype>1</vsizetype>
612 </sizepolicy>
613 </property>
614 <property stdset="1">
615 <name>text</name>
616 <string>Var 2</string>
617 </property>
618 <property stdset="1">
619 <name>alignment</name>
620 <set>AlignTop|AlignRight</set>
621 </property>
622 <property>
623 <name>hAlign</name>
624 </property>
625 <property>
626 <name>vAlign</name>
627 </property>
628 </widget>
629 </hbox>
630 </widget>
631 <widget>
632 <class>QLabel</class>
633 <property stdset="1">
634 <name>name</name>
635 <cstring>lblWeekVar</cstring>
636 </property>
637 <property stdset="1">
638 <name>sizePolicy</name>
639 <sizepolicy>
640 <hsizetype>1</hsizetype>
641 <vsizetype>7</vsizetype>
642 </sizepolicy>
643 </property>
644 <property stdset="1">
645 <name>text</name>
646 <string>WeekVar</string>
647 </property>
648 <property stdset="1">
649 <name>alignment</name>
650 <set>AlignTop|AlignHCenter</set>
651 </property>
652 <property>
653 <name>hAlign</name>
654 </property>
655 <property>
656 <name>vAlign</name>
657 </property>
658 </widget>
659 </vbox>
660 </widget>
661 </vbox>
662</widget>
663<connections>
664 <connection>
665 <sender>chkNoEnd</sender>
666 <signal>toggled(bool)</signal>
667 <receiver>cmdEnd</receiver>
668 <slot>setDisabled(bool)</slot>
669 </connection>
670 <connection>
671 <sender>chkNoEnd</sender>
672 <signal>toggled(bool)</signal>
673 <receiver>RepeatEntryBase</receiver>
674 <slot>slotNoEnd(bool)</slot>
675 </connection>
676 <connection>
677 <sender>spinFreq</sender>
678 <signal>valueChanged(int)</signal>
679 <receiver>lblVar1</receiver>
680 <slot>setNum(int)</slot>
681 </connection>
682 <connection>
683 <sender>spinFreq</sender>
684 <signal>valueChanged(int)</signal>
685 <receiver>RepeatEntryBase</receiver>
686 <slot>setupRepeatLabel( int )</slot>
687 </connection>
688 <connection>
689 <sender>fraType</sender>
690 <signal>clicked(int)</signal>
691 <receiver>RepeatEntryBase</receiver>
692 <slot>slotSetRType( int )</slot>
693 </connection>
694 <connection>
695 <sender>fraExtra</sender>
696 <signal>clicked(int)</signal>
697 <receiver>RepeatEntryBase</receiver>
698 <slot>slotMonthLabel( int )</slot>
699 </connection>
700 <connection>
701 <sender>fraExtra</sender>
702 <signal>clicked(int)</signal>
703 <receiver>RepeatEntryBase</receiver>
704 <slot>slotWeekLabel()</slot>
705 </connection>
706 <slot access="public">setupRepeatLabel( const QString &amp; )</slot>
707 <slot access="public">setupRepeatLabel( int )</slot>
708 <slot access="public">slotMonthLabel( int )</slot>
709 <slot access="public">slotNoEnd(bool)</slot>
710 <slot access="public">slotSetRType( int )</slot>
711 <slot access="public">slotWeekLabel()</slot>
712</connections>
713</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 @@
1moc_*
2Makefile
3todoentry.h
4todoentry.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 @@
1#############################################################################
2
3####### Compiler, tools and options
4
5 CXX =$(SYSCONF_CXX) $(QT_CXX_MT)
6 CXXFLAGS=$(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
7 CC =$(SYSCONF_CC) $(QT_C_MT)
8 CFLAGS =$(SYSCONF_CFLAGS)
9 INCPATH =-I$(QPEDIR)/include
10 LFLAGS =$(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
11 LIBS =$(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
12 MOC =$(SYSCONF_MOC)
13 UIC =$(SYSCONF_UIC)
14
15####### Target
16
17DESTDIR = $(QPEDIR)/bin/
18VER_MAJ = 1
19VER_MIN = 0
20VER_PATCH = 0
21 TARGET= todolist
22TARGET1 = lib$(TARGET).so.$(VER_MAJ)
23
24####### Files
25
26 HEADERS =mainwindow.h \
27 todotable.h \
28 todoentryimpl.h
29 SOURCES =main.cpp \
30 mainwindow.cpp \
31 todotable.cpp \
32 todoentryimpl.cpp
33 OBJECTS =main.o \
34 mainwindow.o \
35 todotable.o \
36 todoentryimpl.o \
37 todoentry.o
38INTERFACES = todoentry.ui
39UICDECLS = todoentry.h
40UICIMPLS = todoentry.cpp
41 SRCMOC =moc_mainwindow.cpp \
42 moc_todotable.cpp \
43 moc_todoentryimpl.cpp \
44 moc_todoentry.cpp
45 OBJMOC =moc_mainwindow.o \
46 moc_todotable.o \
47 moc_todoentryimpl.o \
48 moc_todoentry.o
49
50
51####### Implicit rules
52
53.SUFFIXES: .cpp .cxx .cc .C .c
54
55.cpp.o:
56 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
57
58.cxx.o:
59 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
60
61.cc.o:
62 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
63
64.C.o:
65 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
66
67.c.o:
68 $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
69
70####### Build rules
71
72
73all: $(DESTDIR)$(TARGET)
74
75$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
76 $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
77
78moc: $(SRCMOC)
79
80tmake:
81 tmake todo.pro
82
83clean:
84 -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
85 -rm -f *~ core
86 -rm -f allmoc.cpp
87
88####### Extension Modules
89
90listpromodules:
91 @echo
92
93listallmodules:
94 @echo
95
96listaddonpromodules:
97 @echo
98
99listaddonentmodules:
100 @echo
101
102
103REQUIRES=
104
105####### Sub-libraries
106
107
108###### Combined headers
109
110
111
112####### Compile
113
114main.o: main.cpp \
115 mainwindow.h \
116 $(QPEDIR)/include/qpe/qpeapplication.h
117
118mainwindow.o: mainwindow.cpp \
119 mainwindow.h \
120 todoentryimpl.h \
121 todoentry.h \
122 $(QPEDIR)/include/qpe/task.h \
123 $(QPEDIR)/include/qpe/palmtoprecord.h \
124 $(QPEDIR)/include/qpe/stringutil.h \
125 todotable.h \
126 $(QPEDIR)/include/qpe/categories.h \
127 $(QPEDIR)/include/qpe/qpeapplication.h \
128 $(QPEDIR)/include/qpe/config.h \
129 $(QPEDIR)/include/qpe/finddialog.h \
130 $(QPEDIR)/include/qpe/global.h \
131 $(QPEDIR)/include/qpe/ir.h \
132 $(QPEDIR)/include/qpe/qpemenubar.h \
133 $(QPEDIR)/include/qpe/qpemessagebox.h \
134 $(QPEDIR)/include/qpe/resource.h \
135 $(QPEDIR)/include/qpe/qpetoolbar.h
136
137todotable.o: todotable.cpp \
138 todotable.h \
139 $(QPEDIR)/include/qpe/categories.h \
140 $(QPEDIR)/include/qpe/task.h \
141 $(QPEDIR)/include/qpe/palmtoprecord.h \
142 $(QPEDIR)/include/qpe/stringutil.h \
143 $(QPEDIR)/include/qpe/categoryselect.h \
144 $(QPEDIR)/include/qpe/xmlreader.h
145
146todoentryimpl.o: todoentryimpl.cpp \
147 todoentryimpl.h \
148 todoentry.h \
149 $(QPEDIR)/include/qpe/task.h \
150 $(QPEDIR)/include/qpe/palmtoprecord.h \
151 $(QPEDIR)/include/qpe/stringutil.h \
152 $(QPEDIR)/include/qpe/categoryselect.h \
153 $(QPEDIR)/include/qpe/datebookmonth.h \
154 $(QPEDIR)/include/qpe/event.h \
155 $(QPEDIR)/include/qpe/global.h \
156 $(QPEDIR)/include/qpe/imageedit.h \
157 $(QPEDIR)/include/qpe/timestring.h
158
159todoentry.h: todoentry.ui
160 $(UIC) todoentry.ui -o $(INTERFACE_DECL_PATH)/todoentry.h
161
162todoentry.cpp: todoentry.ui
163 $(UIC) todoentry.ui -i todoentry.h -o todoentry.cpp
164
165todoentry.o: todoentry.cpp \
166 todoentry.h \
167 todoentry.ui
168
169moc_mainwindow.o: moc_mainwindow.cpp \
170 mainwindow.h
171
172moc_todotable.o: moc_todotable.cpp \
173 todotable.h \
174 $(QPEDIR)/include/qpe/categories.h \
175 $(QPEDIR)/include/qpe/task.h \
176 $(QPEDIR)/include/qpe/palmtoprecord.h \
177 $(QPEDIR)/include/qpe/stringutil.h
178
179moc_todoentryimpl.o: moc_todoentryimpl.cpp \
180 todoentryimpl.h \
181 todoentry.h \
182 $(QPEDIR)/include/qpe/task.h \
183 $(QPEDIR)/include/qpe/palmtoprecord.h \
184 $(QPEDIR)/include/qpe/stringutil.h
185
186moc_todoentry.o: moc_todoentry.cpp \
187 todoentry.h
188
189moc_mainwindow.cpp: mainwindow.h
190 $(MOC) mainwindow.h -o moc_mainwindow.cpp
191
192moc_todotable.cpp: todotable.h
193 $(MOC) todotable.h -o moc_todotable.cpp
194
195moc_todoentryimpl.cpp: todoentryimpl.h
196 $(MOC) todoentryimpl.h -o moc_todoentryimpl.cpp
197
198moc_todoentry.cpp: todoentry.h
199 $(MOC) todoentry.h -o moc_todoentry.cpp
200
201
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "mainwindow.h"
22
23#include <qpe/qpeapplication.h>
24
25int main( int argc, char **argv )
26{
27 QPEApplication a( argc, argv );
28
29 TodoWindow mw;
30 QObject::connect( &a, SIGNAL( flush() ), &mw, SLOT( flush() ) );
31 QObject::connect( &a, SIGNAL( reload() ), &mw, SLOT( reload() ) );
32
33 a.showMainWidget(&mw);
34
35 return a.exec();
36}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "mainwindow.h"
22#include "todoentryimpl.h"
23#include "todotable.h"
24
25#include <qpe/qpeapplication.h>
26#include <qpe/config.h>
27#include <qpe/finddialog.h>
28#include <qpe/global.h>
29#include <qpe/ir.h>
30#include <qpe/qpemenubar.h>
31#include <qpe/qpemessagebox.h>
32#include <qpe/resource.h>
33#include <qpe/task.h>
34#include <qpe/qpetoolbar.h>
35
36#include <qaction.h>
37#include <qarray.h>
38#include <qdatastream.h>
39#include <qdatetime.h>
40#include <qfile.h>
41#include <qmessagebox.h>
42#include <qpopupmenu.h>
43
44#include <sys/stat.h>
45#include <sys/types.h>
46#include <fcntl.h>
47#include <unistd.h>
48
49#include <stdlib.h>
50
51static QString todolistXMLFilename()
52{
53 return Global::applicationFileName("todolist","todolist.xml");
54}
55
56static QString categoriesXMLFilename()
57{
58 return Global::applicationFileName("todolist","categories.xml");
59}
60
61TodoWindow::TodoWindow( QWidget *parent, const char *name, WFlags f = 0 ) :
62 QMainWindow( parent, name, f ), syncing(FALSE)
63{
64// QTime t;
65// t.start();
66
67 setCaption( tr("Todo") );
68 QString str;
69 table = new TodoTable( this );
70 table->setColumnWidth( 2, 10 );
71 table->setPaintingEnabled( FALSE );
72 table->setUpdatesEnabled( FALSE );
73 table->viewport()->setUpdatesEnabled( FALSE );
74
75 {
76 str = todolistXMLFilename();
77 if ( str.isNull() )
78 QMessageBox::critical( this,
79 tr("Out of Space"),
80 tr("Unable to create startup files\n"
81 "Free up some space\n"
82 "before you enter any data") );
83 else
84 table->load( str );
85 }
86
87 // repeat for categories...
88 str = categoriesXMLFilename();
89 if ( str.isNull() )
90 QMessageBox::critical( this,
91 tr( "Out of Space" ),
92 tr( "Unable to create startup files\n"
93 "Free up some space\n"
94 "before you enter any data") );
95
96 setCentralWidget( table );
97 setToolBarsMovable( FALSE );
98
99// qDebug("after load: t=%d", t.elapsed() );
100
101 Config config( "todo" );
102 config.setGroup( "View" );
103 bool complete = config.readBoolEntry( "ShowComplete", true );
104 table->setShowCompleted( complete );
105 QString category = config.readEntry( "Category", QString::null );
106 table->setShowCategory( category );
107
108 QPEToolBar *bar = new QPEToolBar( this );
109 bar->setHorizontalStretchable( TRUE );
110
111 QPEMenuBar *mb = new QPEMenuBar( bar );
112
113 catMenu = new QPopupMenu( this );
114 QPopupMenu *edit = new QPopupMenu( this );
115 contextMenu = new QPopupMenu( this );
116
117 bar = new QPEToolBar( this );
118
119 QAction *a = new QAction( tr( "New Task" ), Resource::loadPixmap( "new" ),
120 QString::null, 0, this, 0 );
121 connect( a, SIGNAL( activated() ),
122 this, SLOT( slotNew() ) );
123 a->addTo( bar );
124 a->addTo( edit );
125 a = new QAction( tr( "Edit" ), Resource::loadIconSet( "edit" ),
126 QString::null, 0, this, 0 );
127 connect( a, SIGNAL( activated() ),
128 this, SLOT( slotEdit() ) );
129 a->addTo( bar );
130 a->addTo( edit );
131 a->addTo( contextMenu );
132 a->setEnabled( FALSE );
133 editAction = a;
134 a = new QAction( tr( "Delete" ), Resource::loadIconSet( "trash" ),
135 QString::null, 0, this, 0 );
136 connect( a, SIGNAL( activated() ),
137 this, SLOT( slotDelete() ) );
138 a->addTo( bar );
139 a->addTo( edit );
140 a->addTo( contextMenu );
141 a->setEnabled( FALSE );
142 deleteAction = a;
143
144 if ( Ir::supported() ) {
145 a = new QAction( tr( "Beam" ), Resource::loadPixmap( "beam" ),
146 QString::null, 0, this, 0 );
147 connect( a, SIGNAL( activated() ),
148 this, SLOT( slotBeam() ) );
149 a->addTo( edit );
150 a->addTo( bar );
151 }
152
153 a = new QAction( tr( "Find" ), Resource::loadIconSet( "mag" ),
154 QString::null, 0, this, 0 );
155 connect( a, SIGNAL( activated() ),
156 this, SLOT( slotFind() ) );
157 a->addTo( bar );
158 a->addTo( edit );
159 if ( table->numRows() )
160 a->setEnabled( TRUE );
161 else
162 a->setEnabled( FALSE );
163
164 //a->setEnabled( FALSE );
165 findAction = a;
166// qDebug("mainwindow #2: t=%d", t.elapsed() );
167
168 completedAction = new QAction( QString::null, tr("Completed tasks"), 0, this, 0, TRUE );
169
170 catMenu->setCheckable( true );
171 populateCategories();
172
173 mb->insertItem( tr( "Task" ), edit );
174 mb->insertItem( tr( "View" ), catMenu );
175
176 resize( 200, 300 );
177 if ( table->numRows() > 0 )
178 currentEntryChanged( 0, 0 );
179 connect( table, SIGNAL( signalEdit() ),
180 this, SLOT( slotEdit() ) );
181 connect( table, SIGNAL(signalShowMenu(const QPoint &)),
182 this, SLOT( slotShowPopup(const QPoint &)) );
183
184// qDebug("mainwindow #3: t=%d", t.elapsed() );
185 table->updateVisible();
186 table->setUpdatesEnabled( TRUE );
187 table->setPaintingEnabled( TRUE );
188 table->viewport()->setUpdatesEnabled( TRUE );
189
190 connect( completedAction, SIGNAL( toggled(bool) ), this, SLOT( showCompleted(bool) ) );
191 connect( catMenu, SIGNAL(activated(int)), this, SLOT(setCategory(int)) );
192 connect( table, SIGNAL( currentChanged( int, int ) ),
193 this, SLOT( currentEntryChanged( int, int ) ) );
194
195// qDebug("done: t=%d", t.elapsed() );
196}
197
198void TodoWindow::slotNew()
199{
200 if(syncing) {
201 QMessageBox::warning(this, tr("Todo"),
202 tr("Can not edit data, currently syncing"));
203 return;
204 }
205
206 int id;
207 id = -1;
208 QArray<int> ids;
209 ids = table->currentEntry().categories();
210 if ( ids.count() )
211 id = ids[0];
212 NewTaskDialog e( id, this, 0, TRUE );
213
214 Task todo;
215
216#if defined(Q_WS_QWS) || defined(_WS_QWS_)
217 e.showMaximized();
218#endif
219 int ret = e.exec();
220
221 if ( ret == QDialog::Accepted ) {
222 table->setPaintingEnabled( false );
223 todo = e.todoEntry();
224 todo.assignUid();
225 table->addEntry( todo );
226 table->setPaintingEnabled( true );
227 findAction->setEnabled( TRUE );
228 }
229 // I'm afraid we must call this every time now, otherwise
230 // spend expensive time comparing all these strings...
231 populateCategories();
232}
233
234TodoWindow::~TodoWindow()
235{
236}
237
238void TodoWindow::slotDelete()
239{
240 if(syncing) {
241 QMessageBox::warning(this, tr("Todo"),
242 tr("Can not edit data, currently syncing"));
243 return;
244 }
245
246 if ( table->currentRow() == -1 )
247 return;
248
249 QString strName = table->text( table->currentRow(), 2 ).left( 30 );
250
251 if ( !QPEMessageBox::confirmDelete( this, tr( "Todo" ), strName ) )
252 return;
253
254
255
256 table->setPaintingEnabled( false );
257 table->removeCurrentEntry();
258 table->setPaintingEnabled( true );
259
260 if ( table->numRows() == 0 ) {
261 currentEntryChanged( -1, 0 );
262 findAction->setEnabled( FALSE );
263 }
264}
265
266void TodoWindow::slotEdit()
267{
268 if(syncing) {
269 QMessageBox::warning(this, tr("Todo"),
270 tr("Can not edit data, currently syncing"));
271 return;
272 }
273
274 Task todo = table->currentEntry();
275
276 NewTaskDialog e( todo, this, 0, TRUE );
277 e.setCaption( tr( "Edit Task" ) );
278
279#if defined(Q_WS_QWS) || defined(_WS_QWS_)
280 e.showMaximized();
281#endif
282 int ret = e.exec();
283
284 if ( ret == QDialog::Accepted ) {
285 table->setPaintingEnabled( false );
286 todo = e.todoEntry();
287 table->replaceCurrentEntry( todo );
288 table->setPaintingEnabled( true );
289 }
290 populateCategories();
291
292}
293
294void TodoWindow::slotShowPopup( const QPoint &p )
295{
296 contextMenu->popup( p );
297}
298
299void TodoWindow::showCompleted( bool s )
300{
301 if ( !table->isUpdatesEnabled() )
302 return;
303 table->setPaintingEnabled( false );
304 table->setShowCompleted( s );
305 table->setPaintingEnabled( true );
306}
307
308void TodoWindow::currentEntryChanged( int r, int )
309{
310 if ( r != -1 && table->rowHeight( r ) > 0 ) {
311 editAction->setEnabled( TRUE );
312 deleteAction->setEnabled( TRUE );
313 } else {
314 editAction->setEnabled( FALSE );
315 deleteAction->setEnabled( FALSE );
316 }
317}
318
319void TodoWindow::setCategory( int c )
320{
321 if ( c <= 0 ) return;
322 if ( !table->isUpdatesEnabled() )
323 return;
324 table->setPaintingEnabled( false );
325 for ( unsigned int i = 1; i < catMenu->count(); i++ )
326 catMenu->setItemChecked( i, c == (int)i );
327 if ( c == 1 ) {
328 table->setShowCategory( QString::null );
329 setCaption( tr("Todo") + " - " + tr( "All" ) );
330 } else if ( c == (int)catMenu->count() - 1 ) {
331 table->setShowCategory( tr( "Unfiled" ) );
332 setCaption( tr("Todo") + " - " + tr( "Unfiled" ) );
333 } else {
334 QString cat = table->categories()[c - 2];
335 table->setShowCategory( cat );
336 setCaption( tr("Todo") + " - " + cat );
337 }
338 table->setPaintingEnabled( true );
339}
340
341void TodoWindow::populateCategories()
342{
343 catMenu->clear();
344
345 completedAction->addTo( catMenu );
346 completedAction->setOn( table->showCompleted() );
347
348 int id,
349 rememberId;
350 id = 1;
351 catMenu->insertItem( tr( "All" ), id++ );
352// catMenu->insertSeparator();
353 QStringList categories = table->categories();
354 categories.append( tr( "Unfiled" ) );
355 for ( QStringList::Iterator it = categories.begin();
356 it != categories.end(); ++it ) {
357 catMenu->insertItem( *it, id );
358 if ( *it == table->showCategory() )
359 rememberId = id;
360 ++id;
361 }
362 if ( table->showCategory().isEmpty() )
363 setCategory( 1 );
364 else
365 setCategory( rememberId );
366}
367
368void TodoWindow::reload()
369{
370 table->clear();
371 table->load( todolistXMLFilename() );
372 syncing = FALSE;
373}
374
375void TodoWindow::flush()
376{
377 syncing = TRUE;
378 table->save( todolistXMLFilename() );
379}
380
381void TodoWindow::closeEvent( QCloseEvent *e )
382{
383 if(syncing) {
384 /* no need to save if in the middle of syncing */
385 e->accept();
386 return;
387 }
388
389 if ( table->save( todolistXMLFilename() ) ) {
390 e->accept();
391 // repeat for categories...
392 // if writing configs fail, it will emit an
393 // error, but I feel that it is "ok" for us to exit
394 // espically since we aren't told if the write succeeded...
395 Config config( "todo" );
396 config.setGroup( "View" );
397 config.writeEntry( "ShowComplete", table->showCompleted() );
398 config.writeEntry( "Category", table->showCategory() );
399 } else {
400 if ( QMessageBox::critical( this, tr("Out of space"),
401 tr("Todo was unable\n"
402 "to save your changes.\n"
403 "Free up some space\n"
404 "and try again.\n"
405 "\nQuit Anyway?"),
406 QMessageBox::Yes|QMessageBox::Escape,
407 QMessageBox::No|QMessageBox::Default)
408 != QMessageBox::No )
409 e->accept();
410 else
411 e->ignore();
412 }
413}
414
415void TodoWindow::slotFind()
416{
417 // put everything back to view all for searching...
418 if ( !catMenu->isItemChecked( 0 ) )
419 setCategory( 0 );
420
421 FindDialog dlg( "Todo List", this );
422 QObject::connect( &dlg,
423 SIGNAL(signalFindClicked(const QString &,
424 bool, bool, int)),
425 table,
426 SLOT(slotDoFind(const QString&, bool, bool, int)) );
427 QObject::connect( table, SIGNAL(signalNotFound()), &dlg,
428 SLOT(slotNotFound()) );
429 QObject::connect( table, SIGNAL(signalWrapAround()), &dlg,
430 SLOT(slotWrapAround()) );
431 dlg.exec();
432 if ( table->numSelections() )
433 table->clearSelection();
434 table->clearFindRow();
435}
436
437
438void TodoWindow::setDocument( const QString &filename )
439{
440 if ( filename.find(".vcs") != int(filename.length()) - 4 ) return;
441
442 QValueList<Task> tl = Task::readVCalendar( filename );
443 for( QValueList<Task>::Iterator it = tl.begin(); it != tl.end(); ++it ) {
444 table->addEntry( *it );
445 }
446}
447
448static const char * beamfile = "/tmp/obex/todo.vcs";
449
450void TodoWindow::slotBeam()
451{
452 unlink( beamfile ); // delete if exists
453 Task c = table->currentEntry();
454 mkdir("/tmp/obex/", 0755);
455 Task::writeVCalendar( beamfile, c );
456 Ir *ir = new Ir( this );
457 connect( ir, SIGNAL( done( Ir * ) ), this, SLOT( beamDone( Ir * ) ) );
458 QString description = c.description();
459 ir->send( beamfile, description, "text/x-vCalendar" );
460}
461
462void TodoWindow::beamDone( Ir *ir )
463{
464 delete ir;
465 unlink( beamfile );
466}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#ifndef MAINWINDOW_H
22#define MAINWINDOW_H
23
24#include <qmainwindow.h>
25
26class TodoTable;
27class QAction;
28class QPopupMenu;
29class Ir;
30
31class TodoWindow : public QMainWindow
32{
33 Q_OBJECT
34
35public:
36 TodoWindow( QWidget *parent = 0, const char *name = 0, WFlags f = 0 );
37 ~TodoWindow();
38
39public slots:
40 void flush();
41 void reload();
42
43protected slots:
44 void slotNew();
45 void slotDelete();
46 void slotEdit();
47 void slotShowPopup( const QPoint & );
48 void showCompleted( bool );
49 void currentEntryChanged( int r, int c );
50 void setCategory( int );
51 void slotFind();
52 void setDocument( const QString & );
53 void slotBeam();
54 void beamDone( Ir * );
55
56protected:
57 void closeEvent( QCloseEvent *e );
58
59private:
60 void populateCategories();
61
62private:
63 TodoTable *table;
64 QAction *editAction,
65 *deleteAction,
66 *findAction,
67 * completedAction;
68 QPopupMenu *contextMenu, *catMenu;
69
70 bool syncing;
71};
72
73#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 @@
1Files: bin/todolist apps/Applications/todo.desktop
2Priority: optional
3Section: qpe/applications
4Maintainer: Warwick Allison <warwick@trolltech.com>
5Architecture: arm
6Version: $QPE_VERSION-3
7Depends: qpe-base ($QPE_VERSION)
8Description: TODO-list manager
9 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 @@
1 TEMPLATE= app
2 CONFIG = qt warn_on release
3 DESTDIR = $(QPEDIR)/bin
4 HEADERS= mainwindow.h \
5 todotable.h \
6 todoentryimpl.h
7 SOURCES= main.cpp \
8 mainwindow.cpp \
9 todotable.cpp \
10 todoentryimpl.cpp
11
12 INTERFACES= todoentry.ui
13
14 TARGET = todolist
15INCLUDEPATH += $(QPEDIR)/include
16 DEPENDPATH+= $(QPEDIR)/include
17LIBS += -lqpe
18
19TRANSLATIONS = ../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 @@
1<!DOCTYPE UI><UI>
2<class>NewTaskDialogBase</class>
3<comment>*********************************************************************
4** Copyright (C) 2000 Trolltech AS. All rights reserved.
5**
6** This file is part of Qtopia Environment.
7**
8** This file may be distributed and/or modified under the terms of the
9** GNU General Public License version 2 as published by the Free Software
10** Foundation and appearing in the file LICENSE.GPL included in the
11** packaging of this file.
12**
13** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
14** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
15**
16** See http://www.trolltech.com/gpl/ for GPL licensing information.
17**
18** Contact info@trolltech.com if any conditions of this licensing are
19** not clear to you.
20**
21*********************************************************************</comment>
22<widget>
23 <class>QDialog</class>
24 <property stdset="1">
25 <name>name</name>
26 <cstring>NewTaskDialogBase</cstring>
27 </property>
28 <property stdset="1">
29 <name>geometry</name>
30 <rect>
31 <x>0</x>
32 <y>0</y>
33 <width>249</width>
34 <height>321</height>
35 </rect>
36 </property>
37 <property stdset="1">
38 <name>caption</name>
39 <string>New Task</string>
40 </property>
41 <property>
42 <name>layoutMargin</name>
43 </property>
44 <property>
45 <name>layoutSpacing</name>
46 </property>
47 <vbox>
48 <property stdset="1">
49 <name>margin</name>
50 <number>0</number>
51 </property>
52 <property stdset="1">
53 <name>spacing</name>
54 <number>0</number>
55 </property>
56 <widget>
57 <class>QLayoutWidget</class>
58 <property stdset="1">
59 <name>name</name>
60 <cstring>Layout4</cstring>
61 </property>
62 <hbox>
63 <property stdset="1">
64 <name>margin</name>
65 <number>0</number>
66 </property>
67 <property stdset="1">
68 <name>spacing</name>
69 <number>6</number>
70 </property>
71 <widget>
72 <class>QLabel</class>
73 <property stdset="1">
74 <name>name</name>
75 <cstring>TextLabel2</cstring>
76 </property>
77 <property stdset="1">
78 <name>text</name>
79 <string>Priority:</string>
80 </property>
81 </widget>
82 <widget>
83 <class>QComboBox</class>
84 <item>
85 <property>
86 <name>text</name>
87 <string>1 - Very High</string>
88 </property>
89 </item>
90 <item>
91 <property>
92 <name>text</name>
93 <string>2 - High</string>
94 </property>
95 </item>
96 <item>
97 <property>
98 <name>text</name>
99 <string>3 - Normal</string>
100 </property>
101 </item>
102 <item>
103 <property>
104 <name>text</name>
105 <string>4 - Low</string>
106 </property>
107 </item>
108 <item>
109 <property>
110 <name>text</name>
111 <string>5 - Very Low</string>
112 </property>
113 </item>
114 <property stdset="1">
115 <name>name</name>
116 <cstring>comboPriority</cstring>
117 </property>
118 <property stdset="1">
119 <name>sizePolicy</name>
120 <sizepolicy>
121 <hsizetype>7</hsizetype>
122 <vsizetype>0</vsizetype>
123 </sizepolicy>
124 </property>
125 <property stdset="1">
126 <name>currentItem</name>
127 <number>2</number>
128 </property>
129 </widget>
130 </hbox>
131 </widget>
132 <widget>
133 <class>QLayoutWidget</class>
134 <property stdset="1">
135 <name>name</name>
136 <cstring>Layout3</cstring>
137 </property>
138 <hbox>
139 <property stdset="1">
140 <name>margin</name>
141 <number>0</number>
142 </property>
143 <property stdset="1">
144 <name>spacing</name>
145 <number>6</number>
146 </property>
147 <widget>
148 <class>QLabel</class>
149 <property stdset="1">
150 <name>name</name>
151 <cstring>TextLabel3</cstring>
152 </property>
153 <property stdset="1">
154 <name>frameShape</name>
155 <enum>NoFrame</enum>
156 </property>
157 <property stdset="1">
158 <name>text</name>
159 <string>Category:</string>
160 </property>
161 </widget>
162 <widget>
163 <class>CategorySelect</class>
164 <property stdset="1">
165 <name>name</name>
166 <cstring>comboCategory</cstring>
167 </property>
168 </widget>
169 </hbox>
170 </widget>
171 <widget>
172 <class>QLayoutWidget</class>
173 <property stdset="1">
174 <name>name</name>
175 <cstring>Layout4</cstring>
176 </property>
177 <hbox>
178 <property stdset="1">
179 <name>margin</name>
180 <number>0</number>
181 </property>
182 <property stdset="1">
183 <name>spacing</name>
184 <number>6</number>
185 </property>
186 <widget>
187 <class>QCheckBox</class>
188 <property stdset="1">
189 <name>name</name>
190 <cstring>checkCompleted</cstring>
191 </property>
192 <property stdset="1">
193 <name>text</name>
194 <string>&amp;Completed</string>
195 </property>
196 </widget>
197 <widget>
198 <class>QCheckBox</class>
199 <property stdset="1">
200 <name>name</name>
201 <cstring>checkDate</cstring>
202 </property>
203 <property stdset="1">
204 <name>text</name>
205 <string>D&amp;ue</string>
206 </property>
207 </widget>
208 <widget>
209 <class>QPushButton</class>
210 <property stdset="1">
211 <name>name</name>
212 <cstring>buttonDate</cstring>
213 </property>
214 <property stdset="1">
215 <name>enabled</name>
216 <bool>false</bool>
217 </property>
218 <property stdset="1">
219 <name>text</name>
220 <string>1 Jan 2001</string>
221 </property>
222 </widget>
223 </hbox>
224 </widget>
225 <widget>
226 <class>QMultiLineEdit</class>
227 <property stdset="1">
228 <name>name</name>
229 <cstring>txtTodo</cstring>
230 </property>
231 </widget>
232 </vbox>
233</widget>
234<customwidgets>
235 <customwidget>
236 <class>CategorySelect</class>
237 <header location="global">qpe/categoryselect.h</header>
238 <sizehint>
239 <width>-1</width>
240 <height>-1</height>
241 </sizehint>
242 <container>0</container>
243 <sizepolicy>
244 <hordata>7</hordata>
245 <verdata>1</verdata>
246 </sizepolicy>
247 <pixmap>image0</pixmap>
248 </customwidget>
249</customwidgets>
250<images>
251 <image>
252 <name>image0</name>
253 <data format="XPM.GZ" length="646">789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758</data>
254 </image>
255</images>
256<connections>
257 <connection>
258 <sender>checkDate</sender>
259 <signal>toggled(bool)</signal>
260 <receiver>buttonDate</receiver>
261 <slot>setEnabled(bool)</slot>
262 </connection>
263 <slot access="protected">dateChanged( const QString &amp; )</slot>
264 <slot access="protected">dateChanged( int, int, int )</slot>
265</connections>
266</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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "todoentryimpl.h"
22
23#include <qpe/categoryselect.h>
24#include <qpe/datebookmonth.h>
25#include <qpe/global.h>
26#include <qpe/imageedit.h>
27#include <qpe/task.h>
28#include <qpe/timestring.h>
29
30#include <qmessagebox.h>
31#include <qpopupmenu.h>
32#include <qtoolbutton.h>
33#include <qcombobox.h>
34#include <qcheckbox.h>
35#include <qlineedit.h>
36#include <qmultilineedit.h>
37#include <qlabel.h>
38#include <qtimer.h>
39#include <qapplication.h>
40
41
42NewTaskDialog::NewTaskDialog( const Task& task, QWidget *parent,
43 const char *name, bool modal, WFlags fl )
44 : NewTaskDialogBase( parent, name, modal, fl ),
45 todo( task )
46{
47 todo.setCategories( task.categories() );
48 if ( todo.hasDueDate() )
49 date = todo.dueDate();
50 else
51 date = QDate::currentDate();
52
53 init();
54 comboPriority->setCurrentItem( task.priority() - 1 );
55
56 checkCompleted->setChecked( task.isCompleted() );
57 checkDate->setChecked( task.hasDueDate() );
58 buttonDate->setText( TimeString::longDateString( date ) );
59
60 txtTodo->setText( task.description() );
61}
62
63/*
64 * Constructs a NewTaskDialog which is a child of 'parent', with the
65 * name 'name' and widget flags set to 'f'
66 *
67 * The dialog will by default be modeless, unless you set 'modal' to
68 * TRUE to construct a modal dialog.
69 */
70NewTaskDialog::NewTaskDialog( int id, QWidget* parent, const char* name, bool modal,
71 WFlags fl )
72 : NewTaskDialogBase( parent, name, modal, fl ),
73 date( QDate::currentDate() )
74{
75 if ( id != -1 ) {
76 QArray<int> ids( 1 );
77 ids[0] = id;
78 todo.setCategories( ids );
79 }
80 init();
81}
82
83void NewTaskDialog::init()
84{
85 QPopupMenu *m1 = new QPopupMenu( this );
86 picker = new DateBookMonth( m1, 0, TRUE );
87 m1->insertItem( picker );
88 buttonDate->setPopup( m1 );
89 comboCategory->setCategories( todo.categories(), "Todo List", tr("Todo List") );
90
91 connect( picker, SIGNAL( dateClicked( int, int, int ) ),
92 this, SLOT( dateChanged( int, int, int ) ) );
93
94 buttonDate->setText( TimeString::longDateString( date ) );
95 picker->setDate( date.year(), date.month(), date.day() );
96}
97
98/*
99 * Destroys the object and frees any allocated resources
100 */
101NewTaskDialog::~NewTaskDialog()
102{
103 // no need to delete child widgets, Qt does it all for us
104}
105void NewTaskDialog::dateChanged( int y, int m, int d )
106{
107 date = QDate( y, m, d );
108 buttonDate->setText( TimeString::longDateString( date ) );
109}
110
111/*!
112*/
113
114Task NewTaskDialog::todoEntry()
115{
116 todo.setDueDate( date, checkDate->isChecked() );
117 if ( comboCategory->currentCategory() != -1 ) {
118 todo.setCategories( comboCategory->currentCategories() );
119 }
120 todo.setPriority( comboPriority->currentItem() + 1 );
121 todo.setCompleted( checkCompleted->isChecked() );
122
123 todo.setDescription( txtTodo->text() );
124
125 return todo;
126}
127
128
129/*!
130
131*/
132
133void NewTaskDialog::accept()
134{
135 QString strText = txtTodo->text();
136 if ( !strText || strText == "") {
137 // hmm... just decline it then, the user obviously didn't care about it
138 QDialog::reject();
139 return;
140 }
141 QDialog::accept();
142}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#ifndef NEWTASKDIALOG_H
22#define NEWTASKDIALOG_H
23
24#include "todoentry.h"
25
26#include <qpe/task.h>
27
28#include <qdatetime.h>
29#include <qpalette.h>
30
31class QLabel;
32class QTimer;
33class DateBookMonth;
34
35class NewTaskDialog : public NewTaskDialogBase
36{
37 Q_OBJECT
38
39public:
40 NewTaskDialog( const Task &task, QWidget *parent = 0, const char* name = 0,
41 bool modal = FALSE, WFlags fl = 0 );
42 NewTaskDialog( int id, QWidget* parent = 0, const char* name = 0,
43 bool modal = FALSE, WFlags fl = 0 );
44 ~NewTaskDialog();
45
46 Task todoEntry();
47
48protected slots:
49 void dateChanged( int y, int m, int d );
50
51protected:
52 virtual void accept();
53
54private:
55 void init();
56 Task todo;
57 QDate date;
58 DateBookMonth *picker;
59};
60
61#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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "todotable.h"
22
23#include <qpe/categoryselect.h>
24#include <qpe/xmlreader.h>
25
26#include <qasciidict.h>
27#include <qcombobox.h>
28#include <qfile.h>
29#include <qpainter.h>
30#include <qtextcodec.h>
31#include <qtimer.h>
32#include <qdatetime.h>
33
34#include <qcursor.h>
35#include <qregexp.h>
36
37#include <errno.h>
38#include <stdlib.h>
39
40
41
42static bool taskCompare( const Task &task, const QRegExp &r, int category );
43
44static QString journalFileName();
45
46CheckItem::CheckItem( QTable *t, const QString &key )
47 : QTableItem( t, Never, "" ), checked( FALSE ), sortKey( key )
48{
49}
50
51QString CheckItem::key() const
52{
53 return sortKey;
54}
55
56void CheckItem::setChecked( bool b )
57{
58 checked = b;
59 table()->updateCell( row(), col() );
60}
61
62void CheckItem::toggle()
63{
64 TodoTable *parent = static_cast<TodoTable*>(table());
65 Task newTodo = parent->currentEntry();
66 checked = !checked;
67 newTodo.setCompleted( checked );
68 table()->updateCell( row(), col() );
69 parent->replaceCurrentEntry( newTodo, true );
70}
71
72bool CheckItem::isChecked() const
73{
74 return checked;
75}
76
77static const int BoxSize = 10;
78
79void CheckItem::paint( QPainter *p, const QColorGroup &cg, const QRect &cr,
80 bool )
81{
82 p->fillRect( 0, 0, cr.width(), cr.height(), cg.brush( QColorGroup::Base ) );
83
84 int marg = ( cr.width() - BoxSize ) / 2;
85 int x = 0;
86 int y = ( cr.height() - BoxSize ) / 2;
87 p->setPen( QPen( cg.text() ) );
88 p->drawRect( x + marg, y, BoxSize, BoxSize );
89 p->drawRect( x + marg+1, y+1, BoxSize-2, BoxSize-2 );
90 p->setPen( darkGreen );
91 x += 1;
92 y += 1;
93 if ( checked ) {
94 QPointArray a( 7*2 );
95 int i, xx, yy;
96 xx = x+1+marg;
97 yy = y+2;
98 for ( i=0; i<3; i++ ) {
99 a.setPoint( 2*i, xx, yy );
100 a.setPoint( 2*i+1, xx, yy+2 );
101 xx++; yy++;
102 }
103 yy -= 2;
104 for ( i=3; i<7; i++ ) {
105 a.setPoint( 2*i, xx, yy );
106 a.setPoint( 2*i+1, xx, yy+2 );
107 xx++; yy--;
108 }
109 p->drawLineSegments( a );
110 }
111}
112
113
114ComboItem::ComboItem( QTable *t, EditType et )
115 : QTableItem( t, et, "3" ), cb( 0 )
116{
117 setReplaceable( FALSE );
118}
119
120QWidget *ComboItem::createEditor() const
121{
122 QString txt = text();
123 ( (ComboItem*)this )->cb = new QComboBox( table()->viewport() );
124 cb->insertItem( "1" );
125 cb->insertItem( "2" );
126 cb->insertItem( "3" );
127 cb->insertItem( "4" );
128 cb->insertItem( "5" );
129 cb->setCurrentItem( txt.toInt() - 1 );
130 return cb;
131}
132
133void ComboItem::setContentFromEditor( QWidget *w )
134{
135 TodoTable *parent = static_cast<TodoTable*>(table());
136 Task newTodo = parent->currentEntry();
137
138 if ( w->inherits( "QComboBox" ) )
139 setText( ( (QComboBox*)w )->currentText() );
140 else
141 QTableItem::setContentFromEditor( w );
142 newTodo.setPriority( text().toInt() );
143 parent->replaceCurrentEntry( newTodo, true );
144}
145
146void ComboItem::setText( const QString &s )
147{
148 if ( cb )
149 cb->setCurrentItem( s.toInt() - 1 );
150 QTableItem::setText( s );
151}
152
153QString ComboItem::text() const
154{
155 if ( cb )
156 return cb->currentText();
157 return QTableItem::text();
158}
159
160
161
162TodoTable::TodoTable( QWidget *parent, const char *name )
163// #ifdef QT_QTABLE_NOHEADER_CONSTRUCTOR
164// : QTable( 0, 3, parent, name, TRUE ),
165// #else
166 : QTable( 0, 3, parent, name ),
167// #endif
168 showComp( true ),
169 enablePainting( true ),
170 mCat( 0 ),
171 currFindRow( -2 )
172{
173 mCat.load( categoryFileName() );
174 setSorting( TRUE );
175 setSelectionMode( NoSelection );
176 setColumnStretchable( 2, TRUE );
177 setColumnWidth( 0, 20 );
178 setColumnWidth( 1, 35 );
179 setLeftMargin( 0 );
180 verticalHeader()->hide();
181 horizontalHeader()->setLabel( 0, tr( "C." ) );
182 horizontalHeader()->setLabel( 1, tr( "Prior." ) );
183 horizontalHeader()->setLabel( 2, tr( "Description" ) );
184 connect( this, SIGNAL( clicked( int, int, int, const QPoint & ) ),
185 this, SLOT( slotClicked( int, int, int, const QPoint & ) ) );
186 connect( this, SIGNAL( pressed( int, int, int, const QPoint & ) ),
187 this, SLOT( slotPressed( int, int, int, const QPoint & ) ) );
188 connect( this, SIGNAL( valueChanged( int, int ) ),
189 this, SLOT( slotCheckPriority( int, int ) ) );
190 connect( this, SIGNAL( currentChanged( int, int ) ),
191 this, SLOT( slotCurrentChanged( int, int ) ) );
192
193 menuTimer = new QTimer( this );
194 connect( menuTimer, SIGNAL(timeout()), this, SLOT(slotShowMenu()) );
195}
196
197void TodoTable::addEntry( const Task &todo )
198{
199 int row = numRows();
200 setNumRows( row + 1 );
201 updateJournal( todo, ACTION_ADD );
202 insertIntoTable( new Task(todo), row );
203 setCurrentCell(row, currentColumn());
204 updateVisible();
205}
206
207void TodoTable::slotClicked( int row, int col, int, const QPoint &pos )
208{
209 if ( !cellGeometry( row, col ).contains(pos) )
210 return;
211 // let's switch on the column number...
212 switch ( col )
213 {
214 case 0: {
215 CheckItem *i = static_cast<CheckItem*>(item( row, col ));
216 if ( i ) {
217 int x = pos.x() - columnPos( col );
218 int y = pos.y() - rowPos( row );
219 int w = columnWidth( col );
220 int h = rowHeight( row );
221 if ( i && x >= ( w - BoxSize ) / 2 && x <= ( w - BoxSize ) / 2 + BoxSize &&
222 y >= ( h - BoxSize ) / 2 && y <= ( h - BoxSize ) / 2 + BoxSize ) {
223 i->toggle();
224 }
225 emit signalDoneChanged( i->isChecked() );
226 }
227 }
228 break;
229 case 1:
230 break;
231 case 2:
232 // may as well edit it...
233 menuTimer->stop();
234// emit signalEdit();
235 break;
236 }
237}
238
239void TodoTable::slotPressed( int row, int col, int, const QPoint &pos )
240{
241 if ( col == 2 && cellGeometry( row, col ).contains(pos) )
242 menuTimer->start( 750, TRUE );
243}
244
245void TodoTable::slotShowMenu()
246{
247 emit signalShowMenu( QCursor::pos() );
248}
249
250void TodoTable::slotCurrentChanged( int, int )
251{
252 menuTimer->stop();
253}
254
255void TodoTable::internalAddEntries( QList<Task> &list )
256{
257 setNumRows( list.count() );
258 int row = 0;
259 Task *it;
260 for ( it = list.first(); it; it = list.next() )
261 insertIntoTable( it, row++ );
262}
263
264
265Task TodoTable::currentEntry() const
266{
267 QTableItem *i = item( currentRow(), 0 );
268 if ( !i || rowHeight( currentRow() ) <= 0 )
269 return Task();
270 Task *todo = todoList[(CheckItem*)i];
271 todo->setCompleted( ( (CheckItem*)item( currentRow(), 0 ) )->isChecked() );
272 todo->setPriority( ( (ComboItem*)item( currentRow(), 1 ) )->text().toInt() );
273 return *todo;
274}
275
276void TodoTable::replaceCurrentEntry( const Task &todo, bool fromTableItem )
277{
278 int row = currentRow();
279 updateJournal( todo, ACTION_REPLACE, row );
280
281 if ( !fromTableItem ) {
282 journalFreeReplaceEntry( todo, row );
283 updateVisible();
284 }
285}
286
287void TodoTable::removeCurrentEntry()
288{
289 Task *oldTodo;
290 int row = currentRow();
291 CheckItem *chk;
292
293 chk = static_cast<CheckItem*>(item(row, 0 ));
294 if ( !chk )
295 return;
296 oldTodo = todoList[chk];
297 todoList.remove( chk );
298 oldTodo->setCompleted( chk->isChecked() );
299 oldTodo->setPriority( static_cast<ComboItem*>(item(row, 1))->text().toInt() );
300 realignTable( row );
301 updateVisible();
302 updateJournal( *oldTodo, ACTION_REMOVE, row );
303 delete oldTodo;
304}
305
306
307bool TodoTable::save( const QString &fn )
308{
309 QString strNewFile = fn + ".new";
310 QFile f( strNewFile );
311 if ( !f.open( IO_WriteOnly|IO_Raw ) )
312 return false;
313
314 QString buf("<!DOCTYPE Tasks>\n<Tasks>\n");
315 QCString str;
316 int total_written;
317
318 for ( QMap<CheckItem*, Task *>::Iterator it = todoList.begin();
319 it != todoList.end(); ++it ) {
320 if ( !item( it.key()->row(), 0 ) )
321 continue;
322 Task *todo = *it;
323 // sync item with table
324 todo->setCompleted( ((CheckItem*)item(it.key()->row(), 0))->isChecked() );
325 todo->setPriority( ((ComboItem*)item( it.key()->row(), 1))->text().toInt() );
326 buf += "<Task";
327 todo->save( buf );
328 buf += " />\n";
329 str = buf.utf8();
330 total_written = f.writeBlock( str.data(), str.length() );
331 if ( total_written != int(str.length()) ) {
332 f.close();
333 QFile::remove( strNewFile );
334 return false;
335 }
336 buf = "";
337 }
338
339 buf += "</Tasks>\n";
340 str = buf.utf8();
341 total_written = f.writeBlock( str.data(), str.length() );
342 if ( total_written != int(str.length()) ) {
343 f.close();
344 QFile::remove( strNewFile );
345 return false;
346 }
347 f.close();
348
349 // now do the rename
350 if ( ::rename( strNewFile, fn ) < 0 )
351 qWarning( "problem renaming file %s to %s errno %d",
352 strNewFile.latin1(), fn.latin1(), errno );
353
354 // remove the journal
355 QFile::remove( journalFileName() );
356 return true;
357}
358
359void TodoTable::load( const QString &fn )
360{
361 loadFile( fn, false );
362 if ( QFile::exists(journalFileName()) ) {
363 loadFile( journalFileName(), true );
364 save( fn );
365 }
366// QTable::sortColumn(2,TRUE,TRUE);
367// QTable::sortColumn(1,TRUE,TRUE);
368 QTable::sortColumn(0,TRUE,TRUE);
369 setCurrentCell( 0, 2 );
370}
371
372void TodoTable::updateVisible()
373{
374 if ( !isUpdatesEnabled() )
375 return;
376
377// qDebug("--> updateVisible!");
378
379 int visible = 0;
380 int id = mCat.id( "Todo List", showCat );
381 for ( int row = 0; row < numRows(); row++ ) {
382 CheckItem *ci = (CheckItem *)item( row, 0 );
383 Task *t = todoList[ci];
384 QArray<int> vlCats = t->categories();
385 bool hide = false;
386 if ( !showComp && ci->isChecked() )
387 hide = true;
388 if ( !showCat.isEmpty() ) {
389 if ( showCat == tr( "Unfiled" ) ) {
390 if ( vlCats.count() > 0 )
391 hide = true;
392 } else {
393 // do some comparing, we have to reverse our idea here...
394 if ( !hide ) {
395 hide = true;
396 for ( uint it = 0; it < vlCats.count(); ++it ) {
397 if ( vlCats[it] == id ) {
398 hide = false;
399 break;
400 }
401 }
402 }
403 }
404 }
405 if ( hide ) {
406 if ( currentRow() == row )
407 setCurrentCell( -1, 0 );
408 if ( rowHeight( row ) > 0 )
409 hideRow( row );
410 } else {
411 if ( rowHeight( row ) == 0 ) {
412 showRow( row );
413 adjustRow( row );
414 }
415 visible++;
416 }
417 }
418 if ( !visible )
419 setCurrentCell( -1, 0 );
420}
421
422void TodoTable::viewportPaintEvent( QPaintEvent *pe )
423{
424 if ( enablePainting )
425 QTable::viewportPaintEvent( pe );
426}
427
428void TodoTable::setPaintingEnabled( bool e )
429{
430 if ( e != enablePainting ) {
431 if ( !enablePainting ) {
432 enablePainting = true;
433 rowHeightChanged( 0 );
434 viewport()->update();
435 } else {
436 enablePainting = false;
437 }
438 }
439}
440
441void TodoTable::clear()
442{
443 for ( QMap<CheckItem*, Task *>::Iterator it = todoList.begin();
444 it != todoList.end(); ++it ) {
445 Task *todo = *it;
446 delete todo;
447 }
448 todoList.clear();
449 for ( int r = 0; r < numRows(); ++r ) {
450 for ( int c = 0; c < numCols(); ++c ) {
451 if ( cellWidget( r, c ) )
452 clearCellWidget( r, c );
453 clearCell( r, c );
454 }
455 }
456 setNumRows( 0 );
457}
458
459void TodoTable::sortColumn( int col, bool /*ascending*/, bool /*wholeRows*/ )
460{
461 // The default for wholeRows is false, however
462 // for this todo table we want to exchange complete
463 // rows when sorting. Also, we always want ascending, since
464 // the values have a logical order.
465 QTable::sortColumn( col, TRUE, TRUE );
466 updateVisible();
467}
468
469void TodoTable::slotCheckPriority(int row, int col )
470{
471 // kludgey work around to make forward along the updated priority...
472 if ( col == 1 ) {
473 // let everyone know!!
474 ComboItem* i = static_cast<ComboItem*>( item( row, col ) );
475 emit signalPriorityChanged( i->text().toInt() );
476 }
477}
478
479
480void TodoTable::updateJournal( const Task &todo, journal_action action, int row )
481{
482 QFile f( journalFileName() );
483 if ( !f.open(IO_WriteOnly|IO_Append) )
484 return;
485 QString buf;
486 QCString str;
487 buf = "<Task";
488 todo.save( buf );
489 buf += " Action=\"" + QString::number( int(action) ) + "\"";
490 buf += " Row=\"" + QString::number( row ) + "\"";
491 buf += "/>\n";
492 str = buf.utf8();
493 f.writeBlock( str.data(), str.length() );
494 f.close();
495}
496
497void TodoTable::rowHeightChanged( int row )
498{
499 if ( enablePainting )
500 QTable::rowHeightChanged( row );
501}
502
503void TodoTable::loadFile( const QString &strFile, bool fromJournal )
504{
505 QFile f( strFile );
506 if ( !f.open(IO_ReadOnly) )
507 return;
508
509 int action, row;
510 action = 0; row = 0;
511
512 enum Attribute {
513 FCompleted = 0,
514 FHasDate,
515 FPriority,
516 FCategories,
517 FDescription,
518 FDateYear,
519 FDateMonth,
520 FDateDay,
521 FUid,
522 FAction,
523 FRow
524 };
525
526 QAsciiDict<int> dict( 31 );
527 QList<Task> list;
528 dict.setAutoDelete( TRUE );
529 dict.insert( "Completed", new int(FCompleted) );
530 dict.insert( "HasDate", new int(FHasDate) );
531 dict.insert( "Priority", new int(FPriority) );
532 dict.insert( "Categories", new int(FCategories) );
533 dict.insert( "Description", new int(FDescription) );
534 dict.insert( "DateYear", new int(FDateYear) );
535 dict.insert( "DateMonth", new int(FDateMonth) );
536 dict.insert( "DateDay", new int(FDateDay) );
537 dict.insert( "Uid", new int(FUid) );
538 dict.insert( "Action", new int(FAction) );
539 dict.insert( "Row", new int(FRow) );
540
541 QByteArray ba = f.readAll();
542 f.close();
543 char* dt = ba.data();
544 int len = ba.size();
545 bool hasDueDate = FALSE;
546
547 action = ACTION_ADD;
548 int i = 0;
549 char *point;
550 while ( ( point = strstr( dt+i, "<Task " ) ) != NULL ) {
551 // new Task
552 i = point - dt;
553 Task *todo = new Task;
554 int dtY = 0, dtM = 0, dtD = 0;
555
556 i += 5;
557
558 while( 1 ) {
559 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') )
560 ++i;
561 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') )
562 break;
563 // we have another attribute, read it.
564 int j = i;
565 while ( j < len && dt[j] != '=' )
566 ++j;
567 char *attr = dt+i;
568 dt[j] = '\0';
569 i = ++j; // skip =
570 while ( i < len && dt[i] != '"' )
571 ++i;
572 j = ++i;
573 bool haveUtf = FALSE;
574 bool haveEnt = FALSE;
575 while ( j < len && dt[j] != '"' ) {
576 if ( ((unsigned char)dt[j]) > 0x7f )
577 haveUtf = TRUE;
578 if ( dt[j] == '&' )
579 haveEnt = TRUE;
580 ++j;
581 }
582 if ( i == j ) {
583 // empty value
584 i = j + 1;
585 continue;
586 }
587 QCString value( dt+i, j-i+1 );
588 i = j + 1;
589 int *lookup = dict[ attr ];
590 if ( !lookup ) {
591 todo->setCustomField(attr, value);
592 continue;
593 }
594 switch( *lookup ) {
595 case FCompleted:
596 todo->setCompleted( value.toInt() );
597 break;
598 case FHasDate:
599 // leave...
600 hasDueDate = value.toInt();
601 break;
602 case FPriority:
603 todo->setPriority( value.toInt() );
604 break;
605 case FCategories: {
606 //QString str = Qtopia::plainString( value );
607 todo->setCategories( Qtopia::Record::idsFromString( value ) );
608 break;
609 }
610 case FDescription:
611 {
612 QString str = (haveUtf ? QString::fromUtf8( value )
613 : QString::fromLatin1( value ) );
614 if ( haveEnt )
615 str = Qtopia::plainString( str );
616 todo->setDescription( str );
617 break;
618 }
619 case FDateYear:
620 dtY = value.toInt();
621 break;
622 case FDateMonth:
623 dtM = value.toInt();
624 break;
625 case FDateDay:
626 dtD = value.toInt();
627 break;
628 case FUid:
629 todo->setUid( value.toInt() );
630 break;
631 case FAction:
632 action = value.toInt();
633 break;
634 case FRow:
635 row = value.toInt();
636 break;
637 default:
638 qDebug( "huh??? missing enum? -- attr.: %s", attr );
639 break;
640 }
641 }
642
643 if ( dtY != 0 && dtM != 0 && dtD != 0 )
644 todo->setDueDate( QDate( dtY, dtM, dtD), hasDueDate );
645 else
646 todo->setHasDueDate( hasDueDate );
647
648// if ( categoryList.find( todo.category() ) == categoryList.end() )
649// categoryList.append( todo.category() );
650
651
652 // sadly we can't delay adding of items from the journal to get
653 // the proper effect, but then, the journal should _never_ be
654 // that huge
655
656 switch( action ) {
657 case ACTION_ADD:
658 if ( fromJournal ) {
659 int myrows = numRows();
660 setNumRows( myrows + 1 );
661 insertIntoTable( todo, myrows );
662 delete todo;
663 } else
664 list.append( todo );
665 break;
666 case ACTION_REMOVE:
667 journalFreeRemoveEntry( row );
668 break;
669 case ACTION_REPLACE:
670 journalFreeReplaceEntry( *todo, row );
671 delete todo;
672 break;
673 default:
674 break;
675 }
676 }
677// qDebug("parsing done=%d", t.elapsed() );
678 if ( list.count() > 0 ) {
679 internalAddEntries( list );
680 list.clear();
681 }
682// qDebug("loading done: t=%d", t.elapsed() );
683}
684
685void TodoTable::journalFreeReplaceEntry( const Task &todo, int row )
686{
687 QString strTodo;
688 strTodo = todo.description().left(40).simplifyWhiteSpace();
689 if ( row == -1 ) {
690 QMapIterator<CheckItem*, Task *> it;
691 for ( it = todoList.begin(); it != todoList.end(); ++it ) {
692 if ( *(*it) == todo ) {
693 row = it.key()->row();
694 it.key()->setChecked( todo.isCompleted() );
695 static_cast<ComboItem*>(item(row, 1))->setText( QString::number(todo.priority()) );
696 item( row, 2 )->setText( strTodo );
697 *(*it) = todo;
698 }
699 }
700 } else {
701 Task *t = todoList[static_cast<CheckItem*>(item(row, 0))];
702 todoList.remove( static_cast<CheckItem*>(item(row, 0)) );
703 delete t;
704 static_cast<CheckItem*>(item(row, 0))->setChecked( todo.isCompleted() );
705 static_cast<ComboItem*>(item(row, 1))->setText( QString::number(todo.priority()) );
706 item( row, 2 )->setText( strTodo );
707 todoList.insert( static_cast<CheckItem*>(item(row,0)), new Task(todo) );
708 }
709}
710
711void TodoTable::journalFreeRemoveEntry( int row )
712{
713 CheckItem *chk;
714 chk = static_cast<CheckItem*>(item(row, 0 ));
715 if ( !chk )
716 return;
717 todoList.remove( chk );
718
719 realignTable( row );
720}
721
722void TodoTable::keyPressEvent( QKeyEvent *e )
723{
724 if ( e->key() == Key_Space || e->key() == Key_Return ) {
725 switch ( currentColumn() ) {
726 case 0: {
727 CheckItem *i = static_cast<CheckItem*>(item(currentRow(),
728 currentColumn()));
729 if ( i )
730 i->toggle();
731 break;
732 }
733 case 1:
734 break;
735 case 2:
736 emit signalEdit();
737 default:
738 break;
739 }
740 } else {
741 QTable::keyPressEvent( e );
742 }
743}
744
745QStringList TodoTable::categories()
746{
747 // This is called seldom, so calling a load in here
748 // should be fine.
749 mCat.load( categoryFileName() );
750 QStringList categoryList = mCat.labels( "Todo List" );
751 return categoryList;
752}
753
754void TodoTable::slotDoFind( const QString &findString, bool caseSensitive,
755 bool backwards, int category )
756{
757 // we have to iterate through the table, this gives the illusion that
758 // sorting is actually being used.
759 if ( currFindRow < -1 )
760 currFindRow = currentRow() - 1;
761 clearSelection( TRUE );
762 int rows,
763 row;
764 CheckItem *chk;
765 QRegExp r( findString );
766
767 r.setCaseSensitive( caseSensitive );
768 rows = numRows();
769 static bool wrapAround = true;
770
771 if ( !backwards ) {
772 for ( row = currFindRow + 1; row < rows; row++ ) {
773 chk = static_cast<CheckItem*>( item(row, 0) );
774 if ( taskCompare(*(todoList[chk]), r, category) )
775 break;
776 }
777 } else {
778 for ( row = currFindRow - 1; row > -1; row-- ) {
779 chk = static_cast<CheckItem*>( item(row, 0) );
780 if ( taskCompare(*(todoList[chk]), r, category) )
781 break;
782 }
783 }
784 if ( row >= rows || row < 0 ) {
785 if ( row < 0 )
786 currFindRow = rows;
787 else
788 currFindRow = -1;
789 if ( wrapAround )
790 emit signalWrapAround();
791 else
792 emit signalNotFound();
793 wrapAround = !wrapAround;
794 } else {
795 currFindRow = row;
796 QTableSelection foundSelection;
797 foundSelection.init( currFindRow, 0 );
798 foundSelection.expandTo( currFindRow, numCols() - 1 );
799 addSelection( foundSelection );
800 setCurrentCell( currFindRow, numCols() - 1 );
801 // we should always be able to wrap around and find this again,
802 // so don't give confusing not found message...
803 wrapAround = true;
804 }
805}
806
807int TodoTable::showCategoryId() const
808{
809 int id;
810 id = -1;
811 // if allcategories are selected, you get unfiled...
812 if ( showCat != tr( "Unfiled" ) && showCat != tr( "All" ) )
813 id = mCat.id( "Todo List", showCat );
814 return id;
815}
816
817static bool taskCompare( const Task &task, const QRegExp &r, int category )
818{
819 bool returnMe;
820 QArray<int> cats;
821 cats = task.categories();
822
823 returnMe = false;
824 if ( (category == -1 && cats.count() == 0) || category == -2 )
825 returnMe = task.match( r );
826 else {
827 int i;
828 for ( i = 0; i < int(cats.count()); i++ ) {
829 if ( cats[i] == category ) {
830 returnMe = task.match( r );
831 break;
832 }
833 }
834 }
835 return returnMe;
836}
837
838static QString journalFileName()
839{
840 QString str;
841 str = getenv( "HOME" );
842 str += "/.todojournal";
843 return str;
844}
845
846// int TodoTable::rowHeight( int ) const
847// {
848// return 18;
849// }
850
851// int TodoTable::rowPos( int row ) const
852// {
853// return 18*row;
854// }
855
856// int TodoTable::rowAt( int pos ) const
857// {
858// return QMIN( pos/18, numRows()-1 );
859// }
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#ifndef TODOTABLE_H
22#define TODOTABLE_H
23
24#include <qpe/categories.h>
25#include <qpe/stringutil.h>
26#include <qpe/task.h>
27
28#include <qtable.h>
29#include <qmap.h>
30#include <qguardedptr.h>
31
32class Node;
33class QComboBox;
34class QTimer;
35
36class CheckItem : public QTableItem
37{
38public:
39 CheckItem( QTable *t, const QString &sortkey );
40
41 void setChecked( bool b );
42 void toggle();
43 bool isChecked() const;
44 void setKey( const QString &key ) { sortKey = key; }
45 QString key() const;
46
47 void paint( QPainter *p, const QColorGroup &cg, const QRect &cr, bool selected );
48
49private:
50 bool checked;
51 QString sortKey;
52};
53
54class ComboItem : public QTableItem
55{
56public:
57 ComboItem( QTable *t, EditType et );
58 QWidget *createEditor() const;
59 void setContentFromEditor( QWidget *w );
60 void setText( const QString &s );
61 int alignment() const { return Qt::AlignCenter; }
62
63 QString text() const;
64
65private:
66 QGuardedPtr<QComboBox> cb;
67
68};
69
70class TodoTextItem : public QTableItem
71{
72public:
73 TodoTextItem( QTable *t, const QString & str )
74 :QTableItem( t, QTableItem::Never, str ) {}
75
76 QString key () const { return Qtopia::buildSortKey( text() ); }
77};
78
79
80
81enum journal_action { ACTION_ADD, ACTION_REMOVE, ACTION_REPLACE };
82
83class TodoTable : public QTable
84{
85 Q_OBJECT
86
87public:
88 TodoTable( QWidget *parent = 0, const char * name = 0 );
89 void addEntry( const Task &todo );
90 void clearFindRow() { currFindRow = -2; }
91
92 Task currentEntry() const;
93 void replaceCurrentEntry( const Task &todo, bool fromTableItem = false );
94
95 QStringList categories();
96
97 void setShowCompleted( bool sc ) { showComp = sc; updateVisible(); }
98 bool showCompleted() const { return showComp; }
99
100 void setShowCategory( const QString &c ) { showCat = c; updateVisible(); }
101 const QString &showCategory() const { return showCat; }
102 int showCategoryId() const;
103
104 bool save( const QString &fn );
105 void load( const QString &fn );
106 void clear();
107 void removeCurrentEntry();
108
109 void setPaintingEnabled( bool e );
110
111 virtual void sortColumn( int col, bool ascending, bool /*wholeRows*/ );
112
113// int rowHeight( int ) const;
114// int rowPos( int row ) const;
115// virtual int rowAt( int pos ) const;
116
117signals:
118 void signalEdit();
119 void signalDoneChanged( bool b );
120 void signalPriorityChanged( int i );
121 void signalShowMenu( const QPoint & );
122 void signalNotFound();
123 void signalWrapAround();
124
125protected:
126 void keyPressEvent( QKeyEvent *e );
127
128private:
129 void updateVisible();
130 void viewportPaintEvent( QPaintEvent * );
131 void internalAddEntries( QList<Task> &list);
132 inline void insertIntoTable( Task *todo, int row );
133 void updateJournal( const Task &todo, journal_action action, int row = -1);
134 void mergeJournal();
135 void journalFreeReplaceEntry( const Task &todo, int row );
136 void journalFreeRemoveEntry( int row );
137 inline void realignTable( int row );
138 void loadFile( const QString &strFile, bool fromJournal = false );
139
140private slots:
141 void slotClicked( int row, int col, int button, const QPoint &pos );
142 void slotPressed( int row, int col, int button, const QPoint &pos );
143 void slotCheckPriority(int row, int col );
144 void slotCurrentChanged(int row, int col );
145 void slotDoFind( const QString &findString, bool caseSensetive,
146 bool backwards, int category );
147 void slotShowMenu();
148 void rowHeightChanged( int row );
149
150private:
151 friend class TodoWindow;
152
153 QMap<CheckItem*, Task *> todoList;
154 QStringList categoryList;
155 bool showComp;
156 QString showCat;
157 QTimer *menuTimer;
158 bool enablePainting;
159 Categories mCat;
160 int currFindRow;
161};
162
163
164inline void TodoTable::insertIntoTable( Task *todo, int row )
165{
166 QString sortKey = (char) ((todo->isCompleted() ? 'a' : 'A')
167 + todo->priority() )
168 + Qtopia::buildSortKey( todo->description() );
169 CheckItem *chk = new CheckItem( this, sortKey );
170 chk->setChecked( todo->isCompleted() );
171 ComboItem *cmb = new ComboItem( this, QTableItem::WhenCurrent );
172 cmb->setText( QString::number( todo->priority() ) );
173 QTableItem *ti = new TodoTextItem( this, todo->description().left(40).simplifyWhiteSpace() );
174 ti->setReplaceable( false );
175
176 setItem( row, 0, chk );
177 setItem( row, 1, cmb );
178 setItem( row, 2, ti );
179
180 todoList.insert( chk, todo );
181}
182
183inline void TodoTable::realignTable( int row )
184{
185 QTableItem *ti1,
186 *ti2,
187 *ti3;
188 int totalRows = numRows();
189 for ( int curr = row; curr < totalRows - 1; curr++ ) {
190 // this is bad, we must take the item out and then
191 // set it. In the end, it behaves no worse (time wise)
192 // then the old way of saving the entries to file, clearing
193 // the table re-reading in the file and resetting the table
194 ti1 = item( curr + 1, 0 );
195 ti2 = item( curr + 1, 1 );
196 ti3 = item( curr + 1, 2 );
197 takeItem( ti1 );
198 takeItem( ti2 );
199 takeItem( ti3 );
200 setItem( curr, 0, ti1 );
201 setItem( curr, 1, ti2 );
202 setItem( curr, 2, ti3 );
203 }
204 setNumRows( totalRows - 1 );
205}
206
207#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 @@
1moc_*
2*.moc
3Makefile
4citytimebase.cpp
5citytimebase.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 @@
1#############################################################################
2
3####### Compiler, tools and options
4
5 CXX =$(SYSCONF_CXX) $(QT_CXX_MT)
6 CXXFLAGS=$(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
7 CC =$(SYSCONF_CC) $(QT_C_MT)
8 CFLAGS =$(SYSCONF_CFLAGS)
9 INCPATH =-I$(QPEDIR)/include
10 LFLAGS =$(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
11 LIBS =$(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
12 MOC =$(SYSCONF_MOC)
13 UIC =$(SYSCONF_UIC)
14
15####### Target
16
17DESTDIR = $(QPEDIR)/bin/
18VER_MAJ = 1
19VER_MIN = 0
20VER_PATCH = 0
21 TARGET= citytime
22TARGET1 = lib$(TARGET).so.$(VER_MAJ)
23
24####### Files
25
26 HEADERS =citytime.h \
27 zonemap.h \
28 sun.h \
29 stylusnormalizer.h
30 SOURCES =citytime.cpp \
31 zonemap.cpp \
32 main.cpp \
33 sun.c \
34 stylusnormalizer.cpp
35 OBJECTS =citytime.o \
36 zonemap.o \
37 main.o \
38 sun.o \
39 stylusnormalizer.o \
40 citytimebase.o
41INTERFACES = citytimebase.ui
42UICDECLS = citytimebase.h
43UICIMPLS = citytimebase.cpp
44 SRCMOC =moc_citytime.cpp \
45 moc_zonemap.cpp \
46 moc_stylusnormalizer.cpp \
47 moc_citytimebase.cpp
48 OBJMOC =moc_citytime.o \
49 moc_zonemap.o \
50 moc_stylusnormalizer.o \
51 moc_citytimebase.o
52
53
54####### Implicit rules
55
56.SUFFIXES: .cpp .cxx .cc .C .c
57
58.cpp.o:
59 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
60
61.cxx.o:
62 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
63
64.cc.o:
65 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
66
67.C.o:
68 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
69
70.c.o:
71 $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
72
73####### Build rules
74
75
76all: $(DESTDIR)$(TARGET)
77
78$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
79 $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
80
81moc: $(SRCMOC)
82
83tmake:
84 tmake citytime.pro
85
86clean:
87 -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
88 -rm -f *~ core
89 -rm -f allmoc.cpp
90
91####### Extension Modules
92
93listpromodules:
94 @echo
95
96listallmodules:
97 @echo
98
99listaddonpromodules:
100 @echo
101
102listaddonentmodules:
103 @echo
104
105
106REQUIRES=
107
108####### Sub-libraries
109
110
111###### Combined headers
112
113
114
115####### Compile
116
117citytime.o: citytime.cpp \
118 zonemap.h \
119 stylusnormalizer.h \
120 citytime.h \
121 citytimebase.h \
122 $(QPEDIR)/include/qpe/qpeapplication.h \
123 $(QPEDIR)/include/qpe/config.h \
124 $(QPEDIR)/include/qpe/timestring.h \
125 $(QPEDIR)/include/qpe/tzselect.h \
126 $(QPEDIR)/include/qpe/qcopenvelope_qws.h
127
128zonemap.o: zonemap.cpp \
129 sun.h \
130 zonemap.h \
131 stylusnormalizer.h \
132 $(QPEDIR)/include/qpe/resource.h \
133 $(QPEDIR)/include/qpe/timestring.h \
134 $(QPEDIR)/include/qpe/qpeapplication.h
135
136main.o: main.cpp \
137 citytime.h \
138 citytimebase.h \
139 $(QPEDIR)/include/qpe/qpeapplication.h
140
141sun.o: sun.c \
142 sun.h \
143 $(QPEDIR)/include/qpe/qmath.h
144
145stylusnormalizer.o: stylusnormalizer.cpp \
146 stylusnormalizer.h
147
148citytimebase.h: citytimebase.ui
149 $(UIC) citytimebase.ui -o $(INTERFACE_DECL_PATH)/citytimebase.h
150
151citytimebase.cpp: citytimebase.ui
152 $(UIC) citytimebase.ui -i citytimebase.h -o citytimebase.cpp
153
154citytimebase.o: citytimebase.cpp \
155 citytimebase.h \
156 citytimebase.ui
157
158moc_citytime.o: moc_citytime.cpp \
159 citytime.h \
160 citytimebase.h
161
162moc_zonemap.o: moc_zonemap.cpp \
163 zonemap.h \
164 stylusnormalizer.h
165
166moc_stylusnormalizer.o: moc_stylusnormalizer.cpp \
167 stylusnormalizer.h
168
169moc_citytimebase.o: moc_citytimebase.cpp \
170 citytimebase.h
171
172moc_citytime.cpp: citytime.h
173 $(MOC) citytime.h -o moc_citytime.cpp
174
175moc_zonemap.cpp: zonemap.h
176 $(MOC) zonemap.h -o moc_zonemap.cpp
177
178moc_stylusnormalizer.cpp: stylusnormalizer.h
179 $(MOC) stylusnormalizer.h -o moc_stylusnormalizer.cpp
180
181moc_citytimebase.cpp: citytimebase.h
182 $(MOC) citytimebase.h -o moc_citytimebase.cpp
183
184
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "zonemap.h"
22#include "citytime.h"
23
24#include <qpe/qpeapplication.h>
25#include <qpe/config.h>
26#include <qpe/timestring.h>
27#include <qpe/tzselect.h>
28#if ( defined Q_WS_QWS || defined(_WS_QWS_) ) && !defined(QT_NO_COP)
29#include <qpe/qcopenvelope_qws.h>
30#endif
31
32
33#include <qdir.h>
34#include <qfile.h>
35#include <qlabel.h>
36#include <qmessagebox.h>
37#include <qregexp.h>
38#include <qtextstream.h>
39#include <qtoolbutton.h>
40
41#include <stdlib.h>
42
43CityTime::CityTime( QWidget *parent, const char* name,
44 WFlags fl )
45 : CityTimeBase( parent, name, fl ),
46 strRealTz(0),
47 bAdded(false)
48{
49 Config config( "qpe" );
50 bWhichClock = config.readBoolEntry( "AMPM", TRUE );
51 frmMap->changeClock( bWhichClock );
52
53 char *pEnv;
54 pEnv = NULL;
55 pEnv = getenv("TZ");
56 if ( pEnv )
57 strRealTz = pEnv;
58 pEnv = NULL;
59 pEnv = getenv("HOME");
60 if ( pEnv )
61 strHome = pEnv;
62 // append the labels to their respective lists...
63 listCities.setAutoDelete( true );
64 listTimes.setAutoDelete( true );
65
66 listCities.append( cmdCity1 );
67 listCities.append( cmdCity2 );
68 listCities.append( cmdCity3 );
69
70 listTimes.append( lblCTime1 );
71 listTimes.append( lblCTime2 );
72 listTimes.append( lblCTime3 );
73
74
75 // kludgy way of getting the screen size so we don't have to depend
76 // on a resize event...
77 QWidget *d = QApplication::desktop();
78 if ( d->width() < d->height() ) {
79 // append for that 4 down look
80
81 listCities.append( cmdCity4 );
82 listCities.append( cmdCity5 );
83 listCities.append( cmdCity6 );
84 listTimes.append( lblCTime4 );
85 listTimes.append( lblCTime5 );
86 listTimes.append( lblCTime6 );
87 lblCTime7->hide();
88 lblCTime8->hide();
89 lblCTime9->hide();
90 cmdCity7->hide();
91 cmdCity8->hide();
92 cmdCity9->hide();
93 } else {
94 listCities.append( cmdCity7 );
95 listCities.append( cmdCity8 );
96 listCities.append( cmdCity9 );
97 listTimes.append( lblCTime7 );
98 listTimes.append( lblCTime8 );
99 listTimes.append( lblCTime9 );
100 lblCTime4->hide();
101 lblCTime5->hide();
102 lblCTime6->hide();
103 cmdCity4->hide();
104 cmdCity5->hide();
105 cmdCity6->hide();
106 }
107 bAdded = true;
108 readInTimes();
109 changed = FALSE;
110 QObject::connect( qApp, SIGNAL( clockChanged(bool) ),
111 this, SLOT( changeClock(bool) ) );
112 // now start the timer so we can update the time quickly every second
113 timerEvent( 0 );
114}
115
116CityTime::~CityTime()
117{
118 if ( changed ) {
119 Config cfg("CityTime");
120 cfg.setGroup("TimeZones");
121 QListIterator<QToolButton> itCity( listCities );
122 int i;
123 bool realTzWritten = FALSE;
124 for ( i = 0, itCity.toFirst(); i < CITIES; i++, ++itCity ) {
125 if ( !strCityTz[i].isNull() ) {
126 cfg.writeEntry("Zone"+QString::number(i), strCityTz[i]);
127 cfg.writeEntry("ZoneName"+QString::number(i), itCity.current()->text());
128 if ( strCityTz[i] == strRealTz )
129 realTzWritten = TRUE;
130 }
131 }
132 if ( realTzWritten ) {
133 cfg.removeEntry("Zone"+QString::number(CITIES));
134 cfg.removeEntry("ZoneName"+QString::number(CITIES));
135 } else {
136 cfg.writeEntry("Zone"+QString::number(CITIES), strRealTz);
137 if ( nameRealTz.isEmpty() ) {
138 int i = strRealTz.find( '/' );
139 nameRealTz = strRealTz.mid( i+1 );
140 }
141 cfg.writeEntry("ZoneName"+QString::number(CITIES), nameRealTz);
142 }
143 QCopEnvelope ( "QPE/System", "timeZoneListChange()" );
144
145 changed = FALSE;
146 }
147 // restore the timezone, just in case we messed with it and
148 // are destroyed at an inoppurtune moment
149 if ( !strRealTz.isNull() ) {
150 // this should be checked, but there is not much that can done at this
151 //point if it fails
152 setenv( "TZ", strRealTz, true );
153 }
154}
155
156void CityTime::timerEvent( QTimerEvent *e )
157{
158 if ( e )
159 killTimer( timerId );
160 // change the time again!!
161 showTime();
162 int ms = 1000 - QTime::currentTime().msec();
163 timerId = startTimer( ms );
164}
165
166void CityTime::mousePressEvent( QMouseEvent * )
167{
168 // DEBUG enable this to get a look at the zone information DEBUG
169// frmMap->showZones();
170}
171
172void CityTime::showTime( void )
173{
174 int i;
175 QListIterator<QLabel> itTime(listTimes);
176
177 // traverse the list...
178 for ( i = 0, itTime.toFirst(); i < CITIES; i++, ++itTime) {
179 if ( !strCityTz[i].isNull() ) {
180 if ( setenv( "TZ", strCityTz[i], true ) == 0 ) {
181 itTime.current()->setText( TimeString::shortTime(bWhichClock) );
182 } else {
183 QMessageBox::critical( this, tr( "Time Changing" ),
184 tr( "There was a problem setting timezone %1" )
185 .arg( QString::number( i + 1 ) ) );
186 }
187 }
188 }
189 // done playing around... put it all back
190 unsetenv( "TZ" );
191 if ( !strRealTz.isNull() ) {
192 if ( setenv( "TZ", strRealTz, true ) != 0 ) {
193 QMessageBox::critical( this, tr( "Restore Time Zone" ),
194 tr( "There was a problem setting your timezone."
195 "Your time may be wrong now..." ) );
196 }
197 }
198}
199
200void CityTime::beginNewTz()
201{
202 frmMap->setFocus();
203}
204
205void CityTime::slotNewTz( const QString & strNewCountry,
206 const QString & strNewCity )
207{
208 // determine what to do based on what putton is pressed...
209 QListIterator<QToolButton> itCity(listCities);
210 int i;
211 // go through the list and make adjustments based on which button is on
212 for ( i = 0, itCity.toFirst(); itCity.current(), i < CITIES; i++, ++itCity ) {
213 QToolButton *cmdTmp = itCity.current();
214 if ( cmdTmp->isOn() ) {
215 strCityTz[i] = strNewCountry + strNewCity;
216 QString s = strNewCity;
217 cmdTmp->setText( s.replace( QRegExp("_"), " " ) );
218 cmdTmp->toggle();
219 // we can actually break, since there is only one button
220 // that is ever pressed!
221 changed = TRUE;
222 break;
223 }
224 }
225 showTime();
226}
227
228void CityTime::readInTimes( void )
229{
230 Config cfg("CityTime");
231 cfg.setGroup("TimeZones");
232 QListIterator<QToolButton> itCity( listCities );
233 int i=0;
234 nameRealTz = QString::null;
235 QString zn;
236 for ( ; i < CITIES ; i++ ) {
237 zn = cfg.readEntry("Zone"+QString::number(i), QString::null);
238 if ( zn.isNull() )
239 break;
240 QString nm = cfg.readEntry("ZoneName"+QString::number(i));
241 strCityTz[i] = zn;
242 itCity.current()->setText(nm);
243 if ( zn == strRealTz )
244 nameRealTz = nm;
245 ++itCity;
246 }
247 if ( i == 0 ) {
248 // write in our own in a shameless self promotion and some humor
249 QStringList list = timezoneDefaults();
250 int i;
251 QStringList::Iterator it = list.begin();
252 for ( i = 0, itCity.toFirst(); i < CITIES && itCity.current();
253 i++, ++itCity ) {
254 strCityTz[i] = *it++;
255 itCity.current()->setText( *it++ );
256 }
257 }
258 if ( nameRealTz.isEmpty() ) {
259 //remember the current time zone even if we don't have room
260 //to show it.
261 zn = cfg.readEntry("Zone"+QString::number(CITIES), QString::null);
262 if ( zn == strRealTz )
263 nameRealTz = cfg.readEntry("ZoneName"+QString::number(CITIES));
264 i++;
265 }
266}
267
268void CityTime::changeClock( bool newClock )
269{
270 bWhichClock = newClock;
271 showTime();
272}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#ifndef TIMEWIDGETIMPL_H
22#define TIMEWIDGETIMPL_H
23
24#include <qlist.h>
25#include <qwidget.h>
26
27#include "citytimebase.h"
28
29const int CITIES = 6; // the number of cities...
30
31class ZoneMap;
32
33class CityTime : public CityTimeBase
34{
35 Q_OBJECT
36public:
37 CityTime(QWidget* parent = 0, const char *name = 0, WFlags fl = 0);
38 ~CityTime();
39
40public slots:
41 void beginNewTz();
42 void slotNewTz( const QString& strNewCountry, const QString& strNewCity );
43 void changeClock( bool newClock );
44
45protected:
46 void timerEvent( QTimerEvent* );
47 void mousePressEvent( QMouseEvent* event );
48
49private:
50 void showTime( void ); // get and show the time for various places...
51 void readInTimes( void ); // a method to get information from the config
52 QString strRealTz; // save the TZ var
53 QString nameRealTz; // and what it is called
54 QString strHome; // the home variable...
55 bool bAdded; // a flag to indicate things have been added...
56 bool bWhichClock;
57 int timerId;
58
59 // a spot to hold the time zone for each city
60 QString strCityTz[CITIES];
61 QList<QToolButton> listCities;
62 QList<QLabel> listTimes;
63 bool changed;
64};
65
66#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 @@
1# $Id$
2CONFIG += qt warn_on release
3TEMPLATE = app
4DESTDIR = $(QPEDIR)/bin
5INTERFACES = citytimebase.ui
6HEADERS = citytime.h zonemap.h sun.h stylusnormalizer.h
7SOURCES = citytime.cpp zonemap.cpp main.cpp sun.c stylusnormalizer.cpp
8TARGET = citytime
9INCLUDEPATH += $(QPEDIR)/include
10DEPENDPATH += $(QPEDIR)/include
11LIBS += -lqpe
12
13TRANSLATIONS = ../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 @@
1<!DOCTYPE UI><UI>
2<class>CityTimeBase</class>
3<comment>*********************************************************************
4** Copyright (C) 2001 Trolltech AS. All rights reserved.
5**
6** This file is part of Qtopia Environment.
7**
8** This file may be distributed and/or modified under the terms of the
9** GNU General Public License version 2 as published by the Free Software
10** Foundation and appearing in the file LICENSE.GPL included in the
11** packaging of this file.
12**
13** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
14** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
15**
16** See http://www.trolltech.com/gpl/ for GPL licensing information.
17**
18** Contact info@trolltech.com if any conditions of this licensing are
19** not clear to you.
20**
21** $Id$
22**
23*********************************************************************</comment>
24<author>Trenton Schulz</author>
25<widget>
26 <class>QWidget</class>
27 <property stdset="1">
28 <name>name</name>
29 <cstring>CityTimeBase</cstring>
30 </property>
31 <property stdset="1">
32 <name>geometry</name>
33 <rect>
34 <x>0</x>
35 <y>0</y>
36 <width>289</width>
37 <height>359</height>
38 </rect>
39 </property>
40 <property stdset="1">
41 <name>caption</name>
42 <string>City Time</string>
43 </property>
44 <property>
45 <name>layoutMargin</name>
46 </property>
47 <property>
48 <name>layoutSpacing</name>
49 </property>
50 <vbox>
51 <property stdset="1">
52 <name>margin</name>
53 <number>0</number>
54 </property>
55 <property stdset="1">
56 <name>spacing</name>
57 <number>3</number>
58 </property>
59 <widget>
60 <class>ZoneMap</class>
61 <property stdset="1">
62 <name>name</name>
63 <cstring>frmMap</cstring>
64 </property>
65 <property stdset="1">
66 <name>sizePolicy</name>
67 <sizepolicy>
68 <hsizetype>7</hsizetype>
69 <vsizetype>7</vsizetype>
70 </sizepolicy>
71 </property>
72 </widget>
73 <widget>
74 <class>QLayoutWidget</class>
75 <property stdset="1">
76 <name>name</name>
77 <cstring>Layout2</cstring>
78 </property>
79 <property>
80 <name>layoutMargin</name>
81 </property>
82 <property>
83 <name>layoutSpacing</name>
84 </property>
85 <grid>
86 <property stdset="1">
87 <name>margin</name>
88 <number>4</number>
89 </property>
90 <property stdset="1">
91 <name>spacing</name>
92 <number>3</number>
93 </property>
94 <widget row="0" column="2" >
95 <class>QToolButton</class>
96 <property stdset="1">
97 <name>name</name>
98 <cstring>cmdCity7</cstring>
99 </property>
100 <property stdset="1">
101 <name>sizePolicy</name>
102 <sizepolicy>
103 <hsizetype>5</hsizetype>
104 <vsizetype>1</vsizetype>
105 </sizepolicy>
106 </property>
107 <property stdset="1">
108 <name>font</name>
109 <font>
110 <bold>1</bold>
111 </font>
112 </property>
113 <property stdset="1">
114 <name>focusPolicy</name>
115 <enum>TabFocus</enum>
116 </property>
117 <property stdset="1">
118 <name>text</name>
119 <string>&lt;location 4&gt;</string>
120 </property>
121 <property stdset="1">
122 <name>toggleButton</name>
123 <bool>true</bool>
124 </property>
125 <property stdset="1">
126 <name>toggleButton</name>
127 <bool>true</bool>
128 </property>
129 </widget>
130 <widget row="2" column="3" >
131 <class>QLabel</class>
132 <property stdset="1">
133 <name>name</name>
134 <cstring>lblCTime9</cstring>
135 </property>
136 <property stdset="1">
137 <name>sizePolicy</name>
138 <sizepolicy>
139 <hsizetype>5</hsizetype>
140 <vsizetype>1</vsizetype>
141 </sizepolicy>
142 </property>
143 <property stdset="1">
144 <name>font</name>
145 <font>
146 <pointsize>10</pointsize>
147 </font>
148 </property>
149 <property stdset="1">
150 <name>text</name>
151 <string>&lt;CITY 6 TIME&gt;</string>
152 </property>
153 <property stdset="1">
154 <name>alignment</name>
155 <set>AlignVCenter|AlignRight</set>
156 </property>
157 <property>
158 <name>hAlign</name>
159 </property>
160 </widget>
161 <widget row="1" column="2" >
162 <class>QToolButton</class>
163 <property stdset="1">
164 <name>name</name>
165 <cstring>cmdCity8</cstring>
166 </property>
167 <property stdset="1">
168 <name>sizePolicy</name>
169 <sizepolicy>
170 <hsizetype>5</hsizetype>
171 <vsizetype>1</vsizetype>
172 </sizepolicy>
173 </property>
174 <property stdset="1">
175 <name>font</name>
176 <font>
177 <bold>1</bold>
178 </font>
179 </property>
180 <property stdset="1">
181 <name>focusPolicy</name>
182 <enum>TabFocus</enum>
183 </property>
184 <property stdset="1">
185 <name>text</name>
186 <string>&lt;location 5&gt;</string>
187 </property>
188 <property stdset="1">
189 <name>toggleButton</name>
190 <bool>true</bool>
191 </property>
192 <property stdset="1">
193 <name>toggleButton</name>
194 <bool>true</bool>
195 </property>
196 </widget>
197 <widget row="1" column="0" >
198 <class>QToolButton</class>
199 <property stdset="1">
200 <name>name</name>
201 <cstring>cmdCity2</cstring>
202 </property>
203 <property stdset="1">
204 <name>font</name>
205 <font>
206 <bold>1</bold>
207 </font>
208 </property>
209 <property stdset="1">
210 <name>focusPolicy</name>
211 <enum>TabFocus</enum>
212 </property>
213 <property stdset="1">
214 <name>text</name>
215 <string>&lt;location 2&gt;</string>
216 </property>
217 <property stdset="1">
218 <name>toggleButton</name>
219 <bool>true</bool>
220 </property>
221 <property stdset="1">
222 <name>toggleButton</name>
223 <bool>true</bool>
224 </property>
225 </widget>
226 <widget row="5" column="1" >
227 <class>QLabel</class>
228 <property stdset="1">
229 <name>name</name>
230 <cstring>lblCTime6</cstring>
231 </property>
232 <property stdset="1">
233 <name>font</name>
234 <font>
235 <pointsize>10</pointsize>
236 </font>
237 </property>
238 <property stdset="1">
239 <name>text</name>
240 <string>&lt;CITY 6 TIME&gt;</string>
241 </property>
242 <property stdset="1">
243 <name>alignment</name>
244 <set>AlignVCenter|AlignRight</set>
245 </property>
246 <property>
247 <name>hAlign</name>
248 </property>
249 </widget>
250 <widget row="5" column="0" >
251 <class>QToolButton</class>
252 <property stdset="1">
253 <name>name</name>
254 <cstring>cmdCity6</cstring>
255 </property>
256 <property stdset="1">
257 <name>sizePolicy</name>
258 <sizepolicy>
259 <hsizetype>5</hsizetype>
260 <vsizetype>1</vsizetype>
261 </sizepolicy>
262 </property>
263 <property stdset="1">
264 <name>font</name>
265 <font>
266 <bold>1</bold>
267 </font>
268 </property>
269 <property stdset="1">
270 <name>focusPolicy</name>
271 <enum>TabFocus</enum>
272 </property>
273 <property stdset="1">
274 <name>text</name>
275 <string>&lt;location 6&gt;</string>
276 </property>
277 <property stdset="1">
278 <name>toggleButton</name>
279 <bool>true</bool>
280 </property>
281 <property stdset="1">
282 <name>toggleButton</name>
283 <bool>true</bool>
284 </property>
285 </widget>
286 <widget row="3" column="0" >
287 <class>QToolButton</class>
288 <property stdset="1">
289 <name>name</name>
290 <cstring>cmdCity4</cstring>
291 </property>
292 <property stdset="1">
293 <name>sizePolicy</name>
294 <sizepolicy>
295 <hsizetype>5</hsizetype>
296 <vsizetype>1</vsizetype>
297 </sizepolicy>
298 </property>
299 <property stdset="1">
300 <name>font</name>
301 <font>
302 <bold>1</bold>
303 </font>
304 </property>
305 <property stdset="1">
306 <name>focusPolicy</name>
307 <enum>TabFocus</enum>
308 </property>
309 <property stdset="1">
310 <name>text</name>
311 <string>&lt;location 4&gt;</string>
312 </property>
313 <property stdset="1">
314 <name>toggleButton</name>
315 <bool>true</bool>
316 </property>
317 <property stdset="1">
318 <name>toggleButton</name>
319 <bool>true</bool>
320 </property>
321 </widget>
322 <widget row="4" column="1" >
323 <class>QLabel</class>
324 <property stdset="1">
325 <name>name</name>
326 <cstring>lblCTime5</cstring>
327 </property>
328 <property stdset="1">
329 <name>font</name>
330 <font>
331 <pointsize>10</pointsize>
332 </font>
333 </property>
334 <property stdset="1">
335 <name>text</name>
336 <string>&lt;CITY 5 TIME&gt;</string>
337 </property>
338 <property stdset="1">
339 <name>alignment</name>
340 <set>AlignVCenter|AlignRight</set>
341 </property>
342 <property>
343 <name>hAlign</name>
344 </property>
345 </widget>
346 <widget row="1" column="1" >
347 <class>QLabel</class>
348 <property stdset="1">
349 <name>name</name>
350 <cstring>lblCTime2</cstring>
351 </property>
352 <property stdset="1">
353 <name>sizePolicy</name>
354 <sizepolicy>
355 <hsizetype>1</hsizetype>
356 <vsizetype>1</vsizetype>
357 </sizepolicy>
358 </property>
359 <property stdset="1">
360 <name>font</name>
361 <font>
362 <pointsize>10</pointsize>
363 </font>
364 </property>
365 <property stdset="1">
366 <name>text</name>
367 <string>&lt;CITY 2 TIME&gt;</string>
368 </property>
369 <property stdset="1">
370 <name>alignment</name>
371 <set>AlignVCenter|AlignRight</set>
372 </property>
373 <property>
374 <name>hAlign</name>
375 </property>
376 </widget>
377 <widget row="0" column="1" >
378 <class>QLabel</class>
379 <property stdset="1">
380 <name>name</name>
381 <cstring>lblCTime1</cstring>
382 </property>
383 <property stdset="1">
384 <name>sizePolicy</name>
385 <sizepolicy>
386 <hsizetype>1</hsizetype>
387 <vsizetype>1</vsizetype>
388 </sizepolicy>
389 </property>
390 <property stdset="1">
391 <name>font</name>
392 <font>
393 <pointsize>10</pointsize>
394 </font>
395 </property>
396 <property stdset="1">
397 <name>text</name>
398 <string>&lt;CITY 1 TIME&gt;</string>
399 </property>
400 <property stdset="1">
401 <name>alignment</name>
402 <set>AlignVCenter|AlignRight</set>
403 </property>
404 <property>
405 <name>hAlign</name>
406 </property>
407 </widget>
408 <widget row="2" column="0" >
409 <class>QToolButton</class>
410 <property stdset="1">
411 <name>name</name>
412 <cstring>cmdCity3</cstring>
413 </property>
414 <property stdset="1">
415 <name>sizePolicy</name>
416 <sizepolicy>
417 <hsizetype>5</hsizetype>
418 <vsizetype>1</vsizetype>
419 </sizepolicy>
420 </property>
421 <property stdset="1">
422 <name>font</name>
423 <font>
424 <bold>1</bold>
425 </font>
426 </property>
427 <property stdset="1">
428 <name>focusPolicy</name>
429 <enum>TabFocus</enum>
430 </property>
431 <property stdset="1">
432 <name>text</name>
433 <string>&lt;location 3&gt;</string>
434 </property>
435 <property stdset="1">
436 <name>toggleButton</name>
437 <bool>true</bool>
438 </property>
439 <property stdset="1">
440 <name>toggleButton</name>
441 <bool>true</bool>
442 </property>
443 </widget>
444 <widget row="1" column="3" >
445 <class>QLabel</class>
446 <property stdset="1">
447 <name>name</name>
448 <cstring>lblCTime8</cstring>
449 </property>
450 <property stdset="1">
451 <name>sizePolicy</name>
452 <sizepolicy>
453 <hsizetype>5</hsizetype>
454 <vsizetype>1</vsizetype>
455 </sizepolicy>
456 </property>
457 <property stdset="1">
458 <name>font</name>
459 <font>
460 <pointsize>10</pointsize>
461 </font>
462 </property>
463 <property stdset="1">
464 <name>text</name>
465 <string>&lt;CITY 5 TIME&gt;</string>
466 </property>
467 <property stdset="1">
468 <name>alignment</name>
469 <set>AlignVCenter|AlignRight</set>
470 </property>
471 <property>
472 <name>hAlign</name>
473 </property>
474 </widget>
475 <widget row="0" column="0" >
476 <class>QToolButton</class>
477 <property stdset="1">
478 <name>name</name>
479 <cstring>cmdCity1</cstring>
480 </property>
481 <property stdset="1">
482 <name>sizePolicy</name>
483 <sizepolicy>
484 <hsizetype>5</hsizetype>
485 <vsizetype>1</vsizetype>
486 </sizepolicy>
487 </property>
488 <property stdset="1">
489 <name>font</name>
490 <font>
491 <bold>1</bold>
492 </font>
493 </property>
494 <property stdset="1">
495 <name>focusPolicy</name>
496 <enum>TabFocus</enum>
497 </property>
498 <property stdset="1">
499 <name>text</name>
500 <string>&lt;location 1&gt;</string>
501 </property>
502 <property stdset="1">
503 <name>toggleButton</name>
504 <bool>true</bool>
505 </property>
506 <property stdset="1">
507 <name>toggleButton</name>
508 <bool>true</bool>
509 </property>
510 </widget>
511 <widget row="0" column="3" >
512 <class>QLabel</class>
513 <property stdset="1">
514 <name>name</name>
515 <cstring>lblCTime7</cstring>
516 </property>
517 <property stdset="1">
518 <name>sizePolicy</name>
519 <sizepolicy>
520 <hsizetype>5</hsizetype>
521 <vsizetype>1</vsizetype>
522 </sizepolicy>
523 </property>
524 <property stdset="1">
525 <name>font</name>
526 <font>
527 <pointsize>10</pointsize>
528 </font>
529 </property>
530 <property stdset="1">
531 <name>text</name>
532 <string>&lt;CITY 3 TIME&gt;</string>
533 </property>
534 <property stdset="1">
535 <name>alignment</name>
536 <set>AlignVCenter|AlignRight</set>
537 </property>
538 <property>
539 <name>hAlign</name>
540 </property>
541 </widget>
542 <widget row="3" column="1" >
543 <class>QLabel</class>
544 <property stdset="1">
545 <name>name</name>
546 <cstring>lblCTime4</cstring>
547 </property>
548 <property stdset="1">
549 <name>font</name>
550 <font>
551 <pointsize>10</pointsize>
552 </font>
553 </property>
554 <property stdset="1">
555 <name>text</name>
556 <string>&lt;CITY 4 TIME&gt;</string>
557 </property>
558 <property stdset="1">
559 <name>alignment</name>
560 <set>AlignVCenter|AlignRight</set>
561 </property>
562 <property>
563 <name>hAlign</name>
564 </property>
565 </widget>
566 <widget row="4" column="0" >
567 <class>QToolButton</class>
568 <property stdset="1">
569 <name>name</name>
570 <cstring>cmdCity5</cstring>
571 </property>
572 <property stdset="1">
573 <name>sizePolicy</name>
574 <sizepolicy>
575 <hsizetype>5</hsizetype>
576 <vsizetype>1</vsizetype>
577 </sizepolicy>
578 </property>
579 <property stdset="1">
580 <name>font</name>
581 <font>
582 <bold>1</bold>
583 </font>
584 </property>
585 <property stdset="1">
586 <name>focusPolicy</name>
587 <enum>TabFocus</enum>
588 </property>
589 <property stdset="1">
590 <name>text</name>
591 <string>&lt;location 5&gt;</string>
592 </property>
593 <property stdset="1">
594 <name>toggleButton</name>
595 <bool>true</bool>
596 </property>
597 <property stdset="1">
598 <name>toggleButton</name>
599 <bool>true</bool>
600 </property>
601 </widget>
602 <widget row="2" column="1" >
603 <class>QLabel</class>
604 <property stdset="1">
605 <name>name</name>
606 <cstring>lblCTime3</cstring>
607 </property>
608 <property stdset="1">
609 <name>font</name>
610 <font>
611 <pointsize>10</pointsize>
612 </font>
613 </property>
614 <property stdset="1">
615 <name>text</name>
616 <string>&lt;CITY 3 TIME&gt;</string>
617 </property>
618 <property stdset="1">
619 <name>alignment</name>
620 <set>AlignVCenter|AlignRight</set>
621 </property>
622 <property>
623 <name>hAlign</name>
624 </property>
625 </widget>
626 <widget row="2" column="2" >
627 <class>QToolButton</class>
628 <property stdset="1">
629 <name>name</name>
630 <cstring>cmdCity9</cstring>
631 </property>
632 <property stdset="1">
633 <name>sizePolicy</name>
634 <sizepolicy>
635 <hsizetype>5</hsizetype>
636 <vsizetype>1</vsizetype>
637 </sizepolicy>
638 </property>
639 <property stdset="1">
640 <name>font</name>
641 <font>
642 <bold>1</bold>
643 </font>
644 </property>
645 <property stdset="1">
646 <name>focusPolicy</name>
647 <enum>TabFocus</enum>
648 </property>
649 <property stdset="1">
650 <name>text</name>
651 <string>&lt;location 6&gt;</string>
652 </property>
653 <property stdset="1">
654 <name>toggleButton</name>
655 <bool>true</bool>
656 </property>
657 <property stdset="1">
658 <name>toggleButton</name>
659 <bool>true</bool>
660 </property>
661 </widget>
662 </grid>
663 </widget>
664 </vbox>
665</widget>
666<customwidgets>
667 <customwidget>
668 <class>ZoneMap</class>
669 <header location="local">zonemap.h</header>
670 <sizehint>
671 <width>200</width>
672 <height>400</height>
673 </sizehint>
674 <container>0</container>
675 <sizepolicy>
676 <hordata>7</hordata>
677 <verdata>7</verdata>
678 </sizepolicy>
679 <pixmap>image0</pixmap>
680 <signal>signalTz(const QString &amp;, const QString &amp;)</signal>
681 <slot access="public">slotIllum(bool)</slot>
682 <slot access="public">slotZoom(bool)</slot>
683 </customwidget>
684</customwidgets>
685<images>
686 <image>
687 <name>image0</name>
688 <data format="XPM.GZ" length="197524">789cc4bdd772e34ab6ae7bbf9ea263e16ec5096c7973712e442f2fca5066c7be8025e8404f82da2f7f3273fcff20c45255cd9ea64f7760b23e024c9fc36526f4bffee75f6f0fb7fffa9ffff55ff345b0e845ff8ab260f6afff8997a3d1e67fff9ffff7fffed77f1fededfdebc05e07e707ff3af8efffe7bffe3b4aff15fdcbdb33ffdb3fb39c2ec887fb96e3087cb4bf67793c201f9c5b0e1ec1677bee7ed822cbf3c944d9a53f69930fdcfda8098ee4f7d991b27b3ede9025bd75872cf9373fc887529e27e1fd3d492f682bbbf4bc2a59ca138cc9529ec903f9c8d57fd8051fa17e4db2fcdeab91e5f7f1a7b22b4f780d46fbaca660d47790081fa0bc9f6764f9fde6068cfc0728cf01d2f39ec892ffec108cf4d7f8fde19eb45f9a3b36bd23fddbe8928f02777f4e3e76e363d604b33e9760f4e7ea992cf7177b64e98f690f8cfecb1764793e2f844dfd5c7af33159ee8ff03cebbb7e5576cf0f62b294675903a3feab1659f29f3c29bbe73f376469bfd695f021c6c700ed7188feaef7c128cf12e53f42ffad0330faabf96ed98eb63475edb10023bff12959fa231b9065fccd2ac21c0fe10559da773e25cbf3f13518e3d1e3efcf24fd8b5b30f20f5fc8727f3e5496fc9ec952fe7e57f810e5f944fdd83e9f8764493fe7f3ecaf09599eaf8ec892de2a07a3bffaa9f011e6e7ba0d46fbe7efca2ebd9a3c6f66c3e9a14b9f7c24e37b5a05637c0613b2dccfdec1189fe32159daa7be4796f6a8497f9af122ed9f57c018bffd108cfa0d911feb37dd234bfdfad764997f952559f29b838fd0fee34730e64f2f26a3fd5fc148bf3e5696fe43fb1c433e3402f0b1b46ffd982cf7ab48eff85ceea72e3d333ad1bec3028cf64c783f121e84e41357bfe041f810fd9be56469efe0932ceddb7c261fbbf4ba2bb2b44fbc00531eef9125bde246d9d5bf9290a5bd7bfb60c8d3f4912cbfcf3764298fd75076e5194dc9529ee0058cf65f307d8ca7f5a9b28cff0959d25f5f90a57cc5bb30e743109025bd694bd9a5d778214b79d2148cf1d9bb214bf93fd11f47d0df692c7c8cfc8673f0b1ccdf06ca777c8ef183f63f8ee57ed7c97f636ea03d920e18f5a92f850fa17fa615b28c8f469f7c1abaf6be071f49fb2443b28c87ca2df9c4716345167910cfc1d45763b2b4d7724096f4e76f6429afa7bf97fc965764296ff64a96fa2e593ef46fb343c6f8699225fdd654d9a5df3f163ec2fc5c4cc8f2fbe593b28c3f94ef08f65ad12523ff6bb2fcbef1a42cf9dd90a53eb31a18f2ba774686feb852167db422cb78acf695657cdf9225bf794696fa2f781ff269b8244b7a9348d9ddaf2664496f21f3e99ce375ec298bbc8cc892deb04686bd575576e9e523f031e4694a96df8f7df039e4d70559ee2f36e018f213e3e9e45ce475712e7cba0ff93d134e53e1aeebbfc3fd038c87e642f8d09820aeff7a60f457f3802ce33d3922cb78ec6560b47fccdf9fc9fc5adc81393f6365994f73b2e4e7cd94ddfdc93359f2ef2564c97fd817e678adf864c9ef739f8cf46a60c86faf4e467b5c9131ff3c30c65fda5076fd9f1d93213f06ca529e53b294273d5076f7eb73b2d4a7f108e6780dc892df22254b7e41ae2cf9b13e68ef0998e377345376e9ad33b2a47fd1274bfa953d6599cf9a1ef41bea67c6b3fbfdac4796f45a3764c8939c8cfe417b1f9fcbfd469b2ced93a3fec7b1a47f714686be8dc852de02e3f3641ff3e95d599eef8031ffe647cad21e0f60e89f5ea82cfaa94ac6fc7d5376bfaf3f81313febe7caeef7eb3a19f6d38bf0e9bedc1fd7c89087b7c2692adc75f2ffd0e803990ff501f9cccdb7f10959c653510163fe345265f7bcbf20cbfcf77365b93f23c31e92f960f403f469a6ecfaabda214b7ed95059d28bc8925ffd5159f4f10359f28b0a30f489774896fc2f5acaee7e5127e3f70918f3353a26cbf84a3fc992defc4359c6fb9c2cf52998df9994bfb55076e59f0664c827b60fe667d6274bfee303b2e4df3f54167b94e9a1ff9257b2a4df45ff72be365f9545de5d9165be6dfaca222f5ec8927f0fe5e1fc1d256449ef624096f2ccf6c0e7f2fca64186ffd2264bfea39ab2f4e70519f56f29bbfb338c17cefff11d19f6fc5059fcaf902cf9d76e94c51eec90e10f15cae24fe8f3529e96a687f120f3f99cf265305576f90f32b2e43fa82b4b7f60bc51fe2c7d65b117f97bd80353f4c709da735e5116fb84e9419e64ca529e19fad7c813493f06c3de6ebd9111af5a2b8b3cc4f3690a7b2d22c37eba5096fafb64296fd821cb78f5ddf83b52fded4f8439ff570559eed7d760d81f9b800cf9b15276bfafb7c9f2fb0519f3797c44167994be9191de81b2cce70bf2f991931f6764497f7d09c67cee75c9327e8a3b65773f9c9325bd6241867f5711e67c0d2e94c53ea99125fd68ac2cfed63359d20b1be063e98ff11919f6415559e6db3b19f6fa8c2ced5f63798e215fd17f9cdff3736597de8af9637e7fde288b7ec778e07ccde7ca321f3d32cadb5196f938254bfae395b2d8a34b61ced7a44f96fcb25365f77ce09125bfe158d9ddaf1d91211f6aca521ffe1ef2334dc892dfa2af2cf2e8810c7ffc4559ee0fc8925f88f63b813f508c945d7e454496fcaa17caa2efeec8925fb65096faf5c0901f0b65941ff99fa23d1b7764dc477a942721ef439ed53d32e4f3abb2f8bf28ff29ecab75830cfbee130c79d77a5516fbeb830cf98cf97c06f9d728c8682ff4ff19e4dde6168cf6ad67c2947f2b9f0cfff3932ce51b6dc8323f2ea4fd02da0fdd3e18fabc9b9345fea4cf64f8fb32bf8263d853e92b599e8ffbca4e5ec55db2c897fe800c797a0fc678eb0f95c57e3b204b7e8b4765977ed5274bfaa9fe5ed2ff9c81319e3653b2cc0faf45467d06ca2efda5fe5eeab7395476f7d72cffb9e41fb3bc9017930a59eab79a298bfdb221cb7caa9c2bcbfcd7fb90779a3ee2455764c86bf417e5c5c5882ce9e72d65d13f7db2a49f2f955dfa952332ec79948ff2242ec8f0bfb62cf3774e96fc070fca62efb13ce8df55872cf569be80212f862bb2e4d77d55167d744b96fc96e7caa20ff5bee4d7bf5276f59b37c0e8afe05559d23f25e3f7b7caeef7b9d80701e55174a1ecda6b724b863d365616fdb44f86bff948867fd3204bfe6106a67df44696fc860b32fcdd2332c6c7842ce94f1230fcc70ad3873c9f9c9225bdd93119f67b0886bcfb8cc9f2fce6832ccf17d7c26768af39e6f319e4f30afd734679ef7e7f7c40f9d198828fcf23371e7db2dccfc660daef2119f264a0ecfa2f699065be2f4e9445deec9131df47ca2eff5a420edcfd614e86fd47c6fc4eeec8884f0dc9927f559f477e3159d2abd684399fd73919f6e4922ce9559e9445be8dc958bfcbc098bf69932ce363b165e94ffe1ef3f7f34859f2bf2023ff4f32e2f57530e6737caa2cfaf78d0cf91129cbf89990a1bf9ec9925f7eaf2cf26c4396f66c0dc8909f7c1ef37fd65296f9f94e86bd7ba52cfe34f3877c182d955dfe337d5ecab7667ba07f9be764f4475ff814f27c3e5296fe3921233e9829cb7c5f91a53cd33765579ecd0359daa77946c6fa1fc623e547af4586bc3f5716793f204b79aa7a1ff36f4996f2788fcae26f8dc9982f183fb4b7364b65f15f5ec9529eda87b2e85f9607e3e7e25459fab34746fbec2b4b7bd4c9d23e39e637e5d9f89a8c78c6bdb2c4ff597e8c9751ac2ce3fb4098f65f744b467b42be511e7ebe29cbfa668d2ce5a956c8529efc058cf6fa44f9cf604fafe764c8f38ef039ca5393f632f64de0e45b3d25433fdf8363699f2823cb785ee8fde8d8f11319f25bca63ec0bf89ff7ca2ebfe69a2cf2343e2363bded018cf157dc92a53fd71365917715b2ccbfd11559f2af8d94459ec764c9bf182bbbfb594a0e63371ffb64c427f7c1187f714886bdc1fa425e5d44cae2efcfc952beea89b2cb7f7c48c6fa47074cff735f59fc4fb60fe4d35cef4b79c6ac1fe453b05696fb6c4ff4efe7b5b22bcfe0890cf92ee353ed99784286fddd264b79962365975fff8e2ce5496e95ddfd6e932ce5493e955d79d26b32fae3088cf991f9ca323f981fe4d7aaa22cf6679d2ce51d9e2a4b79591f8eaf1b65b11f94a5bcf90319f27e09c67cdd4464c46753b2946f5a288bfed7df637dca53167dccfc31ded62d6577bfc7fad35ec17ca33c9b4ec9f0ff1f9525fec1f6c4f80ab62cfa86ed83f155cf95a57d1a64699f19cb83f19443bea8bfac0cfd744c96fe1d0764c47b06cae27fbd91a5bc83a5b22bcf28224b799ba8ff19e3057b64c85b5f59f4cb0119f6f5bbb2c4933664c9af1882195f6d91e11f27cad2dfb764d8479fcaa27faa60f4d76757f81cf37189fccf519f02f3f71cfaa1e1daeb44edcd2e98f6e5a2410e45debf2b3b79d8d4fb22ffe77a1ff27f0386bc5d4ec990f7e7caeefea24a96fc92bab2cb2f5c9325bfe69db2bbefcfc918df2330edfd0765d1ff4db28cc75eaaeccab362f961efa7beb2bbef6bfa689f58d99567119151de7d65773fbe27c39f617a984f9f4f64297ff74c59e2032159ca3f59288bbfc4f689a5fcd3a6b2e8fb822ce5f79f9545dfb1bd313ee24361cafbfa0319f18c2a19f19696b2f85f4f64e89f4259ea9392a53e5e57d995b7abbf97fa7c2e94dd7d2f21c3be45ff51be476b32ca575516f9f84a96f279c7ca222ff479f817a9b2cb3fbf234bf95667caee7e634c96f6f65664ec8f63f930ffb31e19fe4740863dbb5176e50b876429ffa0adecee5fccc9d0efbeb22b5fa2e9617ebe91111f3c01435f041d32f4c54059fc17f61ff4457aa5ecca93bd90a5bcfd4cd9dd1f3c92115fbc57167b44d3837db4274cfd30ed92a57c9b2b65f11feec8586f4d94653c7e92a1ef7d6569cf942ce51b5c2bcb789890614fe760fa5727ca629f0fc8f0f72265f1173a64e8ff6b65d1bf0b32e2bbb7caee7eed812ce56d7864d827187fd43f459f8cf5ea6b65f13f0332e27b4365591fbb20c3bf7a22a3bfa03fce389e6232f469ae2cfaac49867ff9ac2cfe25db13e3677a4f46fb63fe9d233e57bf5116fb4b19ebc785b2dc0fc9d0b71565b137347dac5723ff73ee4f6992e14f8e94459e7e92b11f0aed7f8ef8dc6c4ac6fafe868c78df5259ec872119e31ff2ec1ceddd833c08b85e74a5eceeb7d0bee101f6fbc87c54ff6e5113a63db0e890e10fd6c1d0dff1982cf7fd776577bfd620c7723f234b7e5e0f0c79b578258bbcaa2e94453f4fc9d06f89b2d80b2959cae3dd2acbfd980c7fb405863caa9d28bbfca29c2ce5f1c7ca529e908cf204ca2ebf19eb0f7fba3e5596f27864acf748ffa8ffe46564ac1ff7945dfed543b2946f73a12cfee63119e57b50167baf4a46ff0dc9529ecd040c79345c9361bf7c288b7c8dc9b05f96caa28f4ec852de40ef4b79bb7a1ffa342263bfff080cf914337fe8c7d99bb294e7920cfb63a9ecf26bb17e186f599d2cf9a70519fdc3f683fc5a35c9588fd9b2c42f72b2946fd85396f5b657b2942f7c5276e59b6dc852bee64c59eca30519f6bed8dfea1fcd2e9545ffde93e14f46cae26f1e92a19f17ca2ebf8b0a59ca53cb9525bed225a3bf8ec0908fd1a1b2c8bb3732f6ef1c288b3f3423233eeb298b3ed0fbd0e70365f1cf347da9cf455d59e2452c2fc6e3469f97f95163fbd19e9b83e9df2764ac575d90a5bc514b59eccd2119f37bad2ce395fd87f1ba0a945d79e737649407e353f52dfb13e3336a90113f4a95c53ede90a53c134f59f4ef0719f379cbae3c9fec2fea0f945ff5e9a9b2ec476b91a53ce38eb28ccf828cf97ca32cf6c73559ca9355c8680ff417f5ef608f8cf5d40365b1770ec9d81f74a22cf615cb8bf17571ac2cf18f902cf9afd0bed4e7d11d19fb95efc9386f72a82cf1a39c2ce5b9785196f6d907237ebd7e57167b93ed037b6b33579678d83319e977c9904f6db2d46782f60c604f557232f253c6fa41a12cf61dc67710c03e86fe0b12c4cbf07c7880fdbc536591aff764ec97417b8427d80fff41c67905e8b33080bd83f998a6287f4c867de6c6ffe9e1c939ec932e19f6491f0cf9bb08c9d0a797caa2cf0764d84bcf64a4df23c35e06535f0f876449af1f90613fe87d496f9190b17f6209867cebc664493fb9244bf9c38db2d87b6f64c92fce94a57e1764d807cc1fe3b3fa4286ff14288bbc5d93a53dbb756589ff3e91a17f3d6597fff2992ce54b6764ec4f5980195f7953167f7a4c96f275dbca22cf5a64295f63a62ce55b91a57c9f7bcaae7c05cb87fecf3a64d89b5361eadfc140d9956ff242c6faf1908c78cf4859e26f0bb29467d55676e519b6c8b05fd0fed4a7d14a59ec910a19f6c93b59cab33c5596f1744396f2f59764ec1fac8121efd6a9b2c4ef1b64d8733332f4e389b2c4cfcec9d08fb1b22bcf94e5c3f81a4f95a5ff8ec8d8dfcefb5c0f7e24637f7ca82ceb056332faef4c59e21f4f6429df66a62cf67a44863d3750967852872ce59ba17ef4579b2b32ca1b92117fd1e7a57cabb5b2bbdfa893d19ffbca127fd1f4a57cad3bb28ca7cd1319faf6100c7d9ab6c988cfaf95453eb4c8d03737ca626f7864d89f97ca62affb64c4e34ec9523eaf20437fb13e187f514d59f407eb8ff1377a5616fbe89e8cfd1d81b2c48b347dc49bc9184f3dd61fe36978a22ce399e9613c5d1c294b7c654cc678bf264bfdd790bfd4c7618f8c784b5759f4ed862ce5697acae2dfbd93610f1e80113fc823b2e8dbf05e59e26f2959f2af79ca627f3c90913fe445007d1db23eb017ea1d65b127987e80fd627c1ef6c46245c6f9bdb5b2d8eb4f649407cc78c8649f8cdf1f2bcb7ada1159f2af8f94253e73053e91f84bf4a82ce59b91b15fada52cfdf349463c13fd4f7b66caf2a27d366b6591a7e88f10edf13927e3f92365292fca43fb68b626a3fe736529ff1119e759dfc9d89f25fa23a43d525d81313fbb1118fa7cea93e3c4c98f7732d6a32760c8c7e48a2cfaae3b5276e97d5e92612f1d2abbfbf92d59d21fa1bcf46f932659e657724d96fcf20b6597dee88d2cf9452764e8bf1c0cf9d57f2763fde94559e46f9f2cf9d526ca22dfeec892fee0030c79145f91213ff53eecaf4f32e21d7a5ff2afec9325ffca48d9e53f1892a5be3dd61ffdf5790c867c4b2fc9224f6a2fcaa24ff7c858ffdf90b15e31509678c7940cff3c224b793ed97ee8df3eea437f336f90a53cd1a5b2ec975892a5fd46afca92ff2959ca57a9298bfed6f4a4fd96b7cad27ee764d8631918f2721393b1be169011df4895c55e9c93b1feaee94979d75532ecc7576529ef1119e57d274bf95a981fd4876bd617fab03f5196fd1d2f64294fe54e59daef8c8c78cbb3b294674496f6aa0ec9d84fd003733fdfa7b2aca7b0bda06f972b65991f6c0feee7f395459f2fc88817bd2bcbfce4f8c1785ced91e17f883c0da98fb31332ec812619eb67a7caa2ef5764f82f1d6569df828cfd455565579e4d9d0cffe58a0c79fa00c6781b3595257ed423633dea52d9e51f307d8cc7eabbb2b41febcf785b9b8cf982f6a57e5f1c92717e305796f274c9d89fb2a72cf613db23c07eff9ab2ec77c07ca63dd08a94c59e66fd12e8f389b2c4abf43eec43d63fc17ed567658917a1feb4278a1519f652a42cf65448c679af4765193ff764d88f7a1ff14f8c2fda13cb5059c6db822ce90f67caa2cfafc992fe04ed4bfb6271a92cf649858cf35dac1ffa6780fe547b03f23742fd2ece95a57d30de687f4c4664d84797ca62afdd91b1bfb950167b668f8cf5cb6332cedb7e2a4bfbb9fe3e53ffba9b91451ed6bb6489b75c3c91b11f810cfd3cf5c8a28fba21599eaff03ee45da28c78cc4cd9a5179d9325bdea3559ca130764c4936a60c8abfa1919f6c64859fc65a60f7baaea298b7edd274bfe69870c799708533ff61fc9b02fce95451f55c888575495653dea842cf6daf2958cfddea81ff561ff4959e2c3fb64913fd3908cfaeb7dc44fcec8883765ca2eff16eb87fe5cadc838bf3805433f161f64ec7f7c54167b88e5817eecce945d7946ef64c8cb0b65590f5a90a5bc9b336529ef2559cadbd4fca43d9b5db28c9f44d387bd8ef940fd387f5496fd552d32eccb95b2e8f70d19e729f69565ff04db8bf6fb5ad995af32264bf9f32119fb95303ea84fa31919ef0b682bcbfee63a19fb93de95c59eb923e33cdab1b2b4f72d19feb6de97fa046f64c41bd01fd4a70b8f2ce5aba4ca128fec93a57cbda1b2c41f3ec958efa892d1be15b2e43fc6f8537dd9571679774d86fe3a5616ff7f8f8cf8edadb2c45f3232e2e1e84feacf755f59e4fb920cfd79ab2cf67641c67993a6b2c48bd89f09f6678d9565bf00ca437db9689161ff7595c55ef8244b7ed32b6577bf35244b7ef51e18fa74fe42c67ac4a3b2c4173664bc2fe34c59e60fd33f813e823ca53e0d4ec8d0a735b23cbf84bc0fd19e4bd4274279466d32f6933d83a18f43c803f5e7bb64f847556589c7f5c9189f0fca325e3ec838cf2eed13aafebb2763ff68050c7934fd24239eb80786bc985c9325bd7a5559f4d3922cf26c7d424e4edcfc1f91b19e83f4e9df855332fc8f2519eb0d2f64c97f38529678c30759e217b52a3911be22a7ae3cb34459e4ed06ccf59a1a19f6c85859f67ff2f7d057515f59f6e3a464e8eb9eb2bb9f9c92a5bd86976429af7744c67ac51c0c7d54c4ca529e0e59cad31c298bbfabf7a53cb5736559dff2c8529e4a43d995a7d1244bf93e5764ec7760ff41fff4d85fd03fb3bab2d85b8764296f7fa62cfa4759cadb8a95ddfdc60159ca9b56c8d84f89fea0fe594564c4132664eccfc9c8b0bf1e94255e35234b79066fcad27e4db29467d35176ed35d1f2c05e5980a18fb203658937b4c988d7acc8d2bec323b2947f744d46f93f95653d8ce5c378ac687e684fd617e3b1b1afecca3ff4c868df4730f455fd990cfdd4204bff8fee9425fea58cf973ad2cf3794896fc830118faa9c6e7a18f2a5b96f4efc9583fa92b4b7f633c515ff54664e8837b65f127dfc9d87f7345c67ee99c2ce51fa3bda97ffa1764e88f076549ff8c8cfa1c2bbbfc8a13b2e47781fe08e97fd7c958afd823e37c18fa23843d50f92043ffb7c9586f785396f39fac2fdabb1991218fd03ff427375d32f66ff860e8c7f10519fb1f301e23d46701a67f99e764ec9f8994657f6e8f0cfb527f2fe5dfbc90e1ffb9fadad747897ebaa881795e600286fe5a56c988272f858d7e71f7c385b21baf714e167d130d94455e3e80313f9367b2ccbfd92759d2f7af945dfad1902ce98785b2e8d77d30f48577a02ce397cf435f5c74c8220faafa7b294f375176f9872bb2942f592abbfb498d2ce5f38f94c55f6d81a10f821959e45372ae2ce725a664294f76a3ecf21bb0fdd05f4955d9dd9f4fc8529ede4059e2f73d61ea832c214bfb142959cad77f5376e5ebf964f873156597ff6c4ec6783a5276f72ff4f752beee9db2ecef60fe5cffdf23a37c3365d1f7af6429efa8a52cfa2a274b790797caae3c59832ce54d0332e22dac3fe47d764646fbed93b13f235216f9c8fc02295f3653167d744a867de42bbbf2f51ec952bec689b2bb5f1c93e1af9221efc22a59e4c5e79a8cf3496c3fe88b569f2cf5199e2bbbf2663532ec83a6b2bbbfee9211bfca955d79bbecdf04fb0d503eeaa3bcae2cfb0b6ec9d0b73d32e21567ca32dfa76429ffbcab2cfaf6950cfbfa4259ee9f90a5fca33119eb3bbc0ffd56657ed05fe32bb2946ffeaa2cf12a65d80337ca321ef43eda93f99f487922b617e3cf0365b1ff6a64c44bd6ca120f3b224b79aafa7b29cf7aa12cf1408c67fa7f8d0f65d177ec2ffad37d32fcd92b65592fb826c35e867e88d0ffcb0b65d9bf7a4c863e0e94e5fcf7848cfdfb4d65d9bfba0143ff6e86ca52fe3e19f1a71365b10794e1bf613c517f176b32eca95c59e23d900f11ec91568b8cf7e7bc9271de15fd17239e30817c8ae1ef579fc8386f84f68d196f91f112a9bf7a284c7d9d7f9245fe0e07caa24f8760c8cfe61159e4cfea5c59e453950cfdf7aa2ce97960e8d35a850c7dbfafeceefb7532d26b2b8b3db107e67eb71659e647fd5559ec934732f2d3e791df0d19f93595c51f15f91251ff250b32e2e16d65b1074664e477af2cf9adc9c8afaa2cf6d82518fa2cbb5696fc5764e88b86b2ec67f8204bfede5859fced9c8cfc5f94a5be2c2fe441ab20c3bfdf5396fd012c1ff5d781b2e437214b79bac7cae22f866494e74c59fcaf0e18fa69c5e7a99f9acab2dfe3882ce55d2e95657fe22159cabbbc5316ffef930c7bf952d9ddefb3bd1394f75459f623a03d19cf9b1f90b1ffae5096f8cb928cf589b9b2c4d7db64a9cf7aa52cfae2980c7fd65796f8c5882cf5691e2a4b7d1ec8187fbc0ff9b7627d20ffaa4b6589570764c8df2b65a91feb037d37b95776e59fe8efa57e17b1b2d4ef8d8cf17546c67e06f417f561dc5216ff8aed017db80894c5dfd4fb58bfbe5696fdb95532e6c35c59ec2165297fe3990cf983f94efd387e25e3fd0e97ca521e8f0c7f3b5416fb82e5c1f8dfe8efb13f08fd4dfd39fd204b7e6bbd2ff9550ec9f08fb62cfb2f3330f4e3e8932ce98dbbcad25e6332e25f3d30faa772af2cf1ef1919e59982d15e2d9697f18f7765d1efe2bf44d497f30e19f93d90719e0df9c7d0ffb3828cf533cc57ead3cf5b32ec2df44f0c7ba82ff64594c0ffbf70e32b50fff4e2044c7df6a62cf1b15330f493e72b8bbed823e3f73565895fdf0a53ff783764e89f4f65496f49467a1565594fe2efa16f8a07b2a4ef9f9391fe9db2dcdf9091feb5b2e8ef7730e64b75ae2cf91d90a15f5f94653eb13cd427fa3ce2114f64e47fa22cfe78138cf935e07de8871edb03fa21592b8b7ecfc9927ffcac2cfa83f5877e882f9445be5e09539e77f7c9925f912b8b7f3a254b7e595359e2012f64c96fd55596f58f1618f3b15e21633df45059fc697d1ef1990b65a97f4196f2543f94ddfdd12519e313fd45f91ab33e90a7d51e59dabfb2224bfed51919faf851d9e5573d2643ffb6c19097d32159f21bb1bdd0df9b7332ec1fcc4fcacb6843c6f9c36365592fcac09087ab4459d677f6c858ef3927239e3157167d1781210fe757648cd791b2f83ffc3de395a9b2946f46863fda5416ffaf4b867d119271be0cfd4f793a8cc890ff6b65896fed93b1ffef4559f417e415e56db1a72cfbbd1232ec8db1b2e8871b32fcc71365a90fcb03791d85cab2bebd24637de4942ce94d30be13d477b352167fb44146ff4ec028ef27da37c17aea6ca22cebcb4764fcfd12942f813ed9ec29cb7ac30919ed75a92cfa1ded9142ffb4d6643c8ff19b32febca72ce5b923e3f94259ce6f407fa4287f6b45c6f9815730e2d3d35b32fe3e83c817f5dfa63918faacdb50167921e5d9fa471fcae24f8ec0d4378f64c8bb180cf9d0ef9125bd60a12cef733806437ecf07643c3f5596f8a9e82fb5cfe70bb2c8a77ca02cf9f7c9a8cfb1b2c4e7f93ce4e9f2902ccfd72f95a5bc4f60e8c3594a46fdc53e30f61bf69b77c0f87de3168cf13ead29cb7a92de17f93446fb45186fc52119fb839ec9d80f22f233e2fcaf5c2a4bfcae4b86bf93298b3c7e24633d3400637e5d3494259ef64cc6fadb81b2c88353b2e4377b5596785f878cf833c61fe5c3f05659e41bcb8bf69b1f2b8b7cab90e19fde8369ff6f59e2435332d6afdaca12aff3c8927e21f222a27c5a3f2a4bff74c888ffc5caa22f3232fa674dc67903fe9ef1af2e19fec3b5b2accfeaf3925edd5796f640ff50de8581b2f89798cf946f832365799f418b8cfebf27233fa497c2fe8fde9465bd6f4ec6fee64f65592f3b25e3bc39fa93f232ae2bcb7af53e19fe42aa2cf24f19fa6002863e481265492f2323bdaeb2f8276764b4ff81b2c443d0ffdc8fba6279b17ed88f9465fffe1119f1f65365293feb9f227e112bbbfc7c977fa8fec7c5b5b0c68f8ec19047bd3e18f2a1910b53fead6ec0987fb5028cdf77ab60fcfe2211a67c4b6660cce7cd3b19fb39eb60ccc78b1b65896fbe91112f1d9345beae9fc992df300463fc5d0cc9f8fda330e5df305596fd9fd764f8efafcaeef7171f64496fd40363be4ddfc9b09f6332f6bb64ca120f5b90b15fea098cf1b4ba5316fb6a42463ce45059ca7f4f463cc45316ff8df5817fd75a92a11fd0ff31daafd75616f97441c67ee837658917a17d29efd60519e75146ca223fd7649cffa82acbf98a3b32d68b4ec1b43f1f9545df54c8d0370fcad23f3119f27f0ac67caebc9125fde05459ecfd1e19fbb1ae9445ff34c8d21e6bf40fe567f55e59dedf9092b1bff25859eaf342c6786e2a8b7c3922a3bf1f94e57d43283fe5eff45259f6675c91b1df62a32cf6784086fc8d95257eb447c6f95b4d1ff1b90b32c6cb2d18f27b5e5396fdb9af64f8077bcab25eba4f46ff687a58df6b90b1df06f389f27d5c5796fc5ec8d07fe7cae2efb07de88fec2b8b7d3526435f431e51de4f2664e4c7f240be47efca72ff838cf63e5496f1c7f2a788e70ac711e39b4365d9ff7749867d2af339a63c5bde80299f0fc890574d65777ff506467d9b9f60c63f5b64e9efc65a59e2070119fbb9a5ff63ceefd6b5b27bbefe4e86be40f939df7b8764bc6fa0a62ce393bfc77c0f3e9465bd81f9a13f93900cfd9028cb7e822519f18a3365d99f7744c6fa06f3c37c1fbf90b15e992abbf4c30732ecff3b65912fc764d88387ca32dffb64c97f8efae8fc1e2acb78f3c888173c28cbfac0868cfd3b6fcab2bfbf43c6fb5c3f94c5fffa24a33d301e39bf477bca32bf591eaee71e298b3dfb4ac679923b65699f2619fb4fd17f9cefeb3332ecd985b2ccf76b32f23f5096fe6179e99f1d2a8b7ed1fcb05e3f5096f9c3e7290f9ec990070fcad21ea76494c75716fd5090616f1f29cbfc70f2263ae6fccef6c8886f2fc15c9fb8204b7ff5de95c51eab90b1df2116e6fc9df494a5ff03b2a4378d94451e0cc9581f6e80d19fa33e19fee84259ca7b4e96f427beb2ccef2b32f68f7964f1e7d72c2fd79bf6c9381f74a62cf6c82919efa3fb501679552763fee5ca623f56c9a8ef1d18f3bffa4c863ceb284b7b303fceff1b65b127597ff45ff75659da9bf9a3ff5a1b61cefff999b29ccfb926a33dce95ddfdf49e0c7998294b7d4332f4c99665fdf4968cf5842618f33d7c27431e1f2bcb7c4fc992ffa0a22cfdff46c67ac6a5b29c37780463fe8f3fc9b02fce9565be55c9781f40a42cf2e9858cf6385196f1caf6c2f898b0be900715961ff2205b298bbce89011fff695a53d6ec8789fe299b2ecbfda27e37ca1e417737ef79ec988ef4b7faafebdb820cbfd6943d9f963cd4730da7bd95096fd767b64aca754c9f03f6fc068cfde0719f1a1aeb2f81be764f4e71919fb078ec1982fab0765b1cf9b64d82327ca22ef7c32e6abf4b7eabfa84296f47b47ca22ff9ec8d82ff2a02cfaba4d46fbf5c890cf0760cc87fc9c0cfbfa912cf94febcad29f5764ecbf5c2b4bf9fa64ac27697ef0f7311e38ded7e7ca220f7332ea5f5796f68bc992ff67a62cf547fb6a7c6345c6f9b6b5b2ccbf4f32fcd389b2d82b1764f4f74059fcff1a59ca131c294bbcd1b57f6cf585f4c70d19f6f30318e36bbd1166ffc62b30fae3d32323fed026e37c46138cf6a89e91a15ff7c1a8efec4959d68f5ec9902f7a1fe7a39cbeb2e623f6433bf994a687fc7b9e9f60fc7dd3e61e187f8f74b60fc6df0f1c8f848ff0f7bfa32e19f1a04730d2db8460a417d6c1fcfba4488f7f0f6c81f2f17d7bfe1318f12cff5698ef93497c30d7af4fc17c5f5f00e679af8130cf6b072b30cfef1e81f1fb10e5e37efb654f98efdb0a2764a43707f3fd8f4b30de2fe577c8c88fcfe37d157e838cfaa27c5c5f096330deb73454c6fb8f3c6549af20a33f5ac2f407ab684fae0f143561c6bfd2088cf1df457d192faaa0fc317e1fdf0827905f33b427fdb5f1828cf5894732f46548c678dc80217f669eb2c4bbe664e8ff0b32e2917760f85ba34765c97f4896f4c3b6b2f837ef64a43f23a3fe180ff4afe6cfca12ef0fc888f79f298b3dd725239e74a32ce5fb20c3de7c21633f08fa93fed3e4848cfd4b67ca223f4fc9a8ef87b2d4f7958cfa56c9e8ff6b30fca7f14c59fc15e647ffe95859f425db03fd19be294b7ca34d86be3f2763fc62bef3efd7171764fcfdda3365f73ef5b94796f76fad3f94e5fd59cc0fef97984c95e57d1b0519e77f626589e73f91b17ea0f7f17e943b32fc3bcd0fef676a90d15e27ca62ff1e92a1efc6caee7e5c234b7bb5176469aff6c2f7cc15fcc39f21ae089ff6fbd85c49e9b9f89bdfa5f87ef7332971b7f43d7f97949e0b713fc3bf7b7edf1f80839df492d2efbf2b97fdfdb0549fd1ceef83d2bddd72ecd637ff4d7b8d4b57f84dfdbd523ebf6affdd76297f4e7ed35f7f24fdf137ed1deee4bf5bff292ef79c3f73cfcd7ff1fc3f3d3eede7e2bbfc9d8e5cfa2b7f6dae7feeb370d7c6fcfbd3bf3057612eb95fc1fddde7d7ee372bbf8aefed674d9fdf5ef6fbbadf70df37bffc5eeed7c072bfe1b75c190affd27dd7f8925605d715d2bb362db4c13337e6f3c6a56feb51987f4b7d58cea596bfd06bb9736f7b15a61cf6f7b7fe1d9e633ae5fadb72dee3b35cc6efdae177fd50be6a680f9bcf9de98f1fdb7fa5e5bfff52aeef3e0bedcf8abfedcffb9dfefbd5657fffe09e6ffce4996d7b7efff9d7c66745fb93fdf1257fe891ca7fe86a62ced6c0b5d2bfffc8f5b367af77f2a8eedcaf969ebb0657f16c7327fd72d9da25661e6d5cfcee71a75cb5f61faf57f0933afebbd75fe913ef37f9fed17ef9ee77fcf76e7fec3ecb3e68fe0df5f92bd777fd51717a84f3ff9fba6aa57f37fda7bf31ed0232a0e1744913df55dd2532ac82cfaa2f7aa6897f3f9b675ebe2927afb6fbae81ef1b861bf8ae70f71ffd8eff6a3edfcc67ed17e97cdf1e52eea5b131a8e37ef6fb1af2fff1bb5fe7f1abab59fab72dc3aff3fe23fddbf8f2ecee6fd91f3faba7fd77fab78d893f333e7fd91fd0237f4676fdd9ebfd1f9493d4212fedadae28eb107e36db5f75c9ae6c2beb865a296d7bb54bdf7ffc442efe4e27f07ef69be7fe48fdff6c3f5066277f639a3f6b8bea6f2eb66dadbdd5ddffc9eb97fdf11fd32394174d3ffed3f2ef67d79e91637bf02f6efcd50f3a64cf5f397bd97eb69ddc6f38b9b5814ff1639a0dc89595bfef6ceb95b3af37ed057c11eb03d9fc3a4eb7ecca5dfa5fbb32767b15f88c55a6ffba3d98def6f3cfb4ffae6e123dd22b95f7df4bf7bbfeddcd8f3e5455afe287ebab1ef9b1bd7e97f7dfa147e492fed8c9ff3fa447ca7333fe66feeecaca5fc9e3b2cce17560ae433cfbf84dde1fa5ebed9b72354b97956b47f83c36d789b94ecd75d6deea277e5fd6477f468fa43fa9ff77bfffbb64fd6e9af1df90f6aecefe553b7ca747fea89cff27dae067fdf1558f70eefc539fb4e1a94776e76a59e6574abf235316d397a8224d2bdbcffdc2f3cde57981177a91177b89979acf2eaecc5c3dbfebf5bd813734cf8ddcf32b3f94dfbadfe7a56bdc5e78137fe54dbd9937f716ded25b796baff0367ec3fbf42ebc8a57f56a5edd6b784df3df9677e95d79c67af3c6b0b96d393f4d3a37285fb5549ff225df79dfd67fb71dfeeae7aff4c89ee98fea5f4c9ffaa11c8b2cc7debeaf7bd94f6c78b7ae8f79fd7a7cfcddedb4db1fdfeb91ff44ccc0cadc6bccd51afe6d3f1f71bf1c43aa959ea7bfc0989491dfde9db94c3adebdf7e099df798fde93f76c3e8d9cf73ae67a3597d1179ef17d3ca33bbc3d73ed9bcbe81bcfe81bcfe8096f692ea30f3c9b9ed1139ed113de797b11f8e6f2822008cd67642e23670363b30726bfa06b2e63b3063d73f5cd3530d730180579300e269089a68cc1d45c3329abd6f3bbeb3b195e29d5b91c437bdcf9aeec5ffdaeed77f32dfb54ec8f721ffd913477cb5bee2ffebb9cd775a9dcd7edaf7dfb3bbdb0fb1c7ffff8cdbd3f73edf6c7171de3f4c83fa943c4de6e409758fbddf3afcdbfad1ddfb69fc1dc7f7431a9225848ecc87c16fabb1b534a895d17c1325805eba00836c16770115402332203634706c637081ae6dfa6b5825670195c994f3b52cd6f83dbe02eb80f1e8276f0183c05cfc14bd0098c7f11bc066f819941819941819941c17e701098d91398d91398991398d11d9899139899139899139a99137ae60ac2308cc2384c82bbd08caeb01b6661cf2fc27e380887e128ccbdbb701c4ec2a9df0967de4338f77fee13548c0ca74d5c928da6fe2bdb53a1fdb4b2f9daef04263d7f6dbe3333db5fba36e9189f6865effd2159fa35dfad5e5ea20c4d97966977d31f6dedb7af9f3f4bbf8998a2ad832de3ca94ef0e7aaa5daabfa953b030e98b0e93b860536c8c70fd93b2d65cb9b6e5603bd577e28c7f872eb1fdf18ddefb0fe991b2dd9795e40bf548bbf4ec6be99e19e96161ae4df8195e984f3b72cccc086b613d34b3226c86adf032bc0aed7337e16d68f44b786fae0773b545ee8726fdf0297c0e5fc24e68d20e8d7e09cdec08cdec08cdec088d7e098d7e09cd0c09cd0c098f65768566968466968467f8343325f2f1bc2ff723336ba2c05c46e74446e744460e4549308ad2a81bd97abefc42265386574a6dc38bb19e13a461ca1419dd15f5457f064bd155d4597fa8fd77ffbdeb8f40fe078bf6575df22b7f0097fb4d490f79617bebbb510f3c4a5f6adf7e7cd3f7bf1a3be5f8e39fd1757fa48d921d76ff767ae477f6de5ffdac610d416455ec6228120f6a4403730f32221afa76dda1509961d7246c4bdc44a3288fc6d1249a46b3681e991e89cc288956d13a2afc4eb4893e2333832253a3c8f44a548bea51236a46ade832323a2532694466d447b7d15d646650f410b523db63e7e6f3c9f0737017991e8d3af61eeedb7f9b1915991915bd476d37433ee4d3ce98684f668ad359360f33732233d3a2c3e8283a8e4ea253532fab03ef4b7eca5759bed523cd925c371c4ca3b3e83cf6632f0e82c28be2303a8ea33836e98ee32498c7c6df8abb81e890aaae0bfdaafdbf5e5cfbb1f1b94f5706892d5de39ee885dfa7cb4fd797ed459cc5bdb86fca672cd078e83762bb4ba7093db8b0fd6cbecfdd772ba343cc1808276e969872c463f4fb777a64bb9e23b1cbb69653c6c85f1f9fdbfe28ef65f8cfea9157c80cfb196ce58dde6feec8a2d7d2bfabb8674671b0095bb1b1fb63233b6363efc77373997bb19931b1d1f0b1d1f471116fe24ff37921f22c36e9c46ee698cf9ae8023baaed088f8c3e71b3c4c8b2b86e3e5fe43ba7233ea03b0cc70dcc0c7c67d93dc719637f6f4740cb702e7575656eb77f6e2f7f67ffe25e6446577c692e53ced8b4536c665b7cdb16bd62afa31df9fdefe891529bbbcf698929a37f27dbbf4b9fbec6d894f54e2ea74b76d7aa76d7ab5e7f925e6de7df657d52f647fe2e7db2eb1f7ed523ffa40ed9ca50d109e7f17dfce017b19103b1d119f1139ebb31f2c78c56b73fcaca302bd3f6cdfd67fcfecafcdbb476dcf18ee3d7f82d7e8f3fe2bd783f3e880f633362e2e3f8c4ea97f834fef0baf1997f629e3f4ffcc4f35749e0744b3b31332689e40a5a32e2a3a7244e9292ee30233f31d64cd28585e59bef5f4497b819f581d9716ad8e89c24333ae8499e4d7a493f1924c3c4ca4f2b23696fffce1fd9b58fcd8c48f23848c6c9246c25d36416cc93b95f24a67ec912a3b12d723ebef8c3edbf2b9b1bceff58fa17c67790f59f3be7f7358c0fd4713e611b72fa77b1a50fd809f6593b3b6cbb188995185f2a29bc45b289df92cfe422290c9b5197548dff68fcabc4cd2cf12792fa2ff54849af99df583b847e2af7eafdf5f1f9ffb33fa232d5c890c4c8e0c4c882a4158c12c8416b532797edafeb0d8861254696fa47613d319cd8d1736b678af934bd9118cb29b13d62d24e8c4c49ec2ce3da85e5e7e425e924af817dde584d8919ddf6ff8919e9c9de5627b811de9519c04fce06ea0bab2bdc73fba27b924c2c33ea94e440625dc9617264edeee4785be76fe3f1657f64477e3abbddd6d7d42336333c3915bda87e0af5d31fb5cb7f96bf4dc3b6fd19fac0d43335fa35e51eae3f2aa3e95742c7d919929a72a7462aa54622a5463ea7499aa656f20ccdbfe9abedda13df95b5561a43e5d859f527bfffb33a64d73ffc1ad7fa2ece5cf9328fff48eceac7b9f94536fa45da4bfbe9201d867974928e924e9aa7e37412ac8caf318adbde209da6337f1cdfbb98c8951fa7f374911ab999ae8c9c794ed7c9495aa41b634135d3cff4c24be2abb49256fd4e5a4beb69236dc6af693f5ce9da77c7c5cb6c9438f6ee5263a3a597f12cbd4aafd39bf43635dfa7f7f0ba3f4a3ae2cbec303a82b3e4743b2becf7cec27a828e319f96d387b49d3e7a51928b6c8cec0efafa4f657943f5c8fa9bf6bf36f74facae35695066deb876e47356ee769c9efa5d7fec7ecf7d6be7d1287d4a9fd397b4939c4747e96bfa16e5a61f56e9bbff893c7fb65ee16258a64f4d5ba546daa4fbde223df0eae9a1b7f2ced3a3f4383d496d9b9c491bdbd8606aaeae99815dc3ddc05b191ba1e31f3bbdf5d51fd9d52715897bfafbddb01b794137f687c9953f4f9ffc6137f9859efef7d7f1e2efc6ef377aa46cf7bde1bbf29e9ab25dc939cd58f80f73b0bdb5534d6b7553c87ac35d2353ba59b7d735b2b73b08465d2b5fcc68ec8eb6b2b26b6cfbee586493935155db1be63be393748ddceb1a9fa46b7c92ae9131dd6577e59edbcdbfb4aee264d789c8b8aef15dba465e7737a223e8777c99254f72515794f54af7b3e4a79851d23572be5b11d9ff4b3f8097ade377eb23bb6bbff40fcaedcc7581ddb6a77d5f96b52fdb7434ae64f5b8ed0373bf6b7edb35be983b07c3be2eade9741b320ed4f7a96dd3ed9a74bac66aed1a1ba07b25eb523602af31c363699feeb544cebb66b6778d1de0594967fbefaebdd5b3d55299cb3e11cb603f8d54eb3e881dd16d771fa39352993e76ca5cfb26dddd314a3dcf768edb5ff7856ffd9135e6625bd631e2dcad5548bcc9edec40cca9a2f128c6401a883388bde82279760fae6d517cef4683bfea3e759fbbb6553bdd57efc41b74dfa293ae1d6de3ee47f72df1bb7b626f77f74dba77f8cd81b90ecd7766e4778fe3b3ee49f7b47b963c45c7c12a9e76cf333ff3b220bdcac2709245599c257ec3d8b90ddff48edb6765cb7a02996dcbdc7231161b07696476b6165937cb24f21b3d88cea067be9d25e2776c67c856e7d83518f7db7bd149592feb67836ce8cea8883c6afc726dba525a9bd8c66e28ebb76b0e4eca5839eaafb0d7b8e12ec48cd41778f465cde91ab134f96cb8357049af80cfe785b3d8cb46599e56b3b1f5f3cc771da77b4dbf1a5decf6a6651397a6cdcbf88666541b1d60d73f3233ba33239db279b6c896887e7c9422e4e576329f99b1bcb2b58d966445b6c93eb38bac92991198d56c1f58cbcc5f6566cc640d632f98f1923583b9675764efe16bbca1ff96a6dfcc8ccc2efd2233333233ed9fdda0af1f55df75dc5eec57b70e5394da53c681f3afcc3df39d95182ece76adb1d427d74edbbd64653d529643e5f317afa57b8feded5a2fe354bbeb1be57808f58779c6d5ccc88fcc8cfecc8e2633eab276f09499df664fd0d6b6759ecd657bcce89cac93bd2603f3f996bdc7a6b533d30bd99ee880ccf45866466776981d65465665469e64a68732fbbb73b187bfd8abe57a94d67d7ba6777b9eac8b385df1b0f53bbee88ea7af7ac47af77634f44c597a612fea19f993f57b49ef3bffe25736309fdf3d5fc1fb6599d6fe2ad7bfac3197754f796f32ebcb34b0c7acd78dbabd4cf602f47af25cafdfdeeaa0335c94d3d0e3bd81e8f19ed1f93da3777a6684f5c6a5f6faf851e7daef7a66c4f7a6bd59cfe8fc9e91843d33b37aa68f7a6b8939f68ab09e9a51df3333b367f473cfe8e4f4103e18751ad78b6c392a320e740fdd0bcad8de8e4bb76ec431588e2d725da63cde311ee231ee97dbf5edcb7e2dccb7de40e48fd384b6542d27676c9ca9e164999d9f1f7ea357d539d930f2ad83348a2f766fd5fd2eebd564fda257ef357acd5eab67b473ef4a767af4ae7b37bddbde5defbef7d0b33b4b4ccbf51ebd453c882b3d333a7bcff16def257eeb75e249efd5c892ebde5bcfb47eefa3b7d7dbef1df44c6bf68e7ac7bd93de69efac77def7b3671ba3ef5bcfb30af9f1a8b6b52d67a31f98729b1e493fc2513f8cda6ea7c9b5917daf5bffe38b2e29f57a3f4a622b1bed6a623fee27fdb4dfed67e1c8cae37e0feb0ef4397e661f97d74776fd9536e467a5a40faeb1cfb8069dcd337856de5d8713e955e8f526f63534b9d66d65b25da337f5eef7077d33c2fb2323b3ed9af7c69f3b7f67cfc95fd746fd3cadf4c7feaa3fe94ffb6616f5cdc8f6ae4d3b2dfacbfe2a98f7d7a237dd4aeb81c40177a31c655dd237f2babf81d5f5299f56baf43f6535d7b67ddfcc06ab93fa668cf4cdace99bf1d2af9b7218dd62758af57bec67dfd4b3dfea67d98b29df65ffaa7fddbfe9dff6effaf7d151d6747be41a3646978cfc8ed531f1f3ce9eb93db173421701c0de8e6b9c43b47ba0df5c3b6ccf0d192ee911dab727327ffb0fb8da223fdcfac4b4342f2193dcdea469e9f74d99d31a87c1f37d3377fb66c4db1eb271ffc0e88cbebd5e24d6e4ec58e3a3f48d8cee9b91da37b2b26f5bd8b44edfe88fbe1d9176bf9549af7f287aa47fd43fee9b72f44fd1b267e219f6cf07fec0cc9041792da6acfb6adb38c920345734880789f9b4bdfdbcf54fb4d7777c94e04ed659ba9783eec0c8e3be9931835ed4fd72f6e177bae43b7fe43b5f8ecfc29f7292eb4cdac1b6b14ab2a31d7959b2b9a3c136ad415ffcb9c140facdbb6d7fb1fd07a67f0646470c72f135acef30180f2603f3ec6026f27f309791ed2cabce763d4975c8ce6cb1cfd978a08b099674b59d29b61d6dbfb9bd0fc626182ce0e799e70666d60c6c7e66560ecc4c1bd8b298993530f51ed8ba983e1fd4c40f1a98913f30bf1bd83630690f5a251d53dedb56d64b65bb89fe48a9fd9dce3ec47e2db776696dd5f4c32f069783abc1f5e06670ebaf06a607fa937032b81f3c64cfe9f5a0ed1d0f1e074f7d33576d29ac5d6af7c95a39357836cf9b12d9f5816c6aee9bd61bbc7a496c46dde04d2ca4c17bd6e9be8793e062f031580ff606fb83838119f103d3c3836319a5bd23f3db7ba32b52230f8cac1c9c04f3c8f6aaadf9d9e07ce81b7bf469e80d03bf188632ab6c8f0da3616c771f0e13d159c374d81d66c3deb0df3d8ddde8f53bc381e892e1d06fb8fdbfa6d587a361debf1b8e87268fe1d4c8bee71ddd51eef1a7e0ceaea7d81e1ece86f3e162b81cae329bcf7a5804723eb1565aa3fe598ca5ec8fecae236d7d94865848a6bcb69c9fd1d1f062686cf9617558cbb2613d9c78a7de62d8b07d66f71e436fca6f3bd8cb447f7145ff6cd8343afa63d88afb26bdcb7466d7a8ba07b6ff6cbf99ba5c89c4195a6b7433bcb1ed3ebc1dde0def65440f1f86ede1a3e804bbbee45652cf77db6aeb8fb0ed5c5cb0f4bdfd4d706574b8c967f824fe9df30bb1de64a3294353a6e18bfcdbce8aa1e9ebe1abe870f7fc9e3c1b98993e34636cf83efc181a5dd1bb0fdefa2bd36efb224d860732b6ed65748cacd318bf7b68a56d43ee9b761cbab3f5b592ce39f41b3bfe8829cdf04876fad91884b5d3ed7ea4e1b170af2e7b696d69ec5c76a5323264685bd1c882a1a9f5c8b4a2675a6f64e4f8c8fc766446f12832572cf26094c83af928953db9a3ae4406ede7c8b4e2c8d8c7a3bef8155c2b1819993732f26d6466dfc8c8b7d15874dc68329a8e66a3f9c8c89e915d6bb7cf19b9335a4b7ab6dca362b419f6c3ba4dc7e98e725ca814fbeabd8e3623c4aa18cffa4e26bafbbee82e2b6b6d7b8c4c5b8c767db63f1293dff55f76e38ad00f23336247e6bb9169ff5143765adad8d1a829bab55f17d9396ab5b77b8d21235d9de9ef5445f7f01a999935ba1a6dac1f30b4699bdf8d4c3f5bc96875c3c88cbc91f9f7c8cc8ed183c878ab03466decc079927d6edffa21a54bd79c76fc14ee7be3a74bf343dad7e992fdd2beb96399096e5f1dd6abd84fce320e64f6d87eb156e0c8f4c3c8dc1bd9991f8b056fd766ac5d3432e37c64ed95898c2b7b6f647e1bbfc2662aad6975dd1c71b11023ff466fc3d6c8f6b86dfd3dd18a2a1f5eb0f3023bfa46a54f37b20fccdcbd1c1d8e6c8f1ecb9c77dad88e64dbdaa7b29f76647a7774de1b8e9e8379eee75e6e74411ee65118e5719ee4e9609c77f32cefe57d6f959cfbab7c900ea3ab7c387830cf8df2dca6958ff3493e0d27b9d161f95c6654be103d68f79ce6cbec395fc97aba6dbd7c9d17b91905f18b5ff4447e77faa645f34fa75bdc1ed4fc222df24a5e7591e0779165db19b28d6d59fbdb3e637da9dcb4605ef71b79236fda588b3beb58c3fea16a49377cb75eb4eb8f509fd4109b32be9e975b9fca1be466e4e7976295bad1749ac4b63cb92d8319d5f98d8d88983a4d928b78667444eacb7b4e5af96d37f657d696b7fb15864646e677d1517e9f3f74d7f15b7a93bd644f793bb7918b439158f963fe943fe72f79473cedf4d6f4d36bfe96bbba4b8ccaad15591f22dac6f8649c7cf5dbbeec4d285bada54fb79fc1e49f9776feb87d713656d6d9d1e99a8ee91fbb729cc867b90c6eb6bcc8f74e3fd95913cb18756b336696e57bf97e7e2063d4fa55b9a97b6ec66d7e9ccf4783e8e8cb79a0bd2feb23d72287f313d8e5af28356a9397a3a23b570e7bd2ce61ce65b797f60c330d9ad1ed36ef8a5d9b9bb4c7fed81b9bd13ab6bac6c8f971243ecad8d46a9cc8bc1f9bb2d81a0d17928fdb4962eee5fb2203aca535ee8a1c55dd603ec71974a1d167e39ec4bdc67d919fba5716f67a7e3b1e8c87e3d138472ba3bedc9162659a2dbfad979de53d5b56a3cbc613898d7d91dde5787cb5f4fdaffc91b27d5cd2e9e369bcb13bf86d3dacdd3f9e89ac1dcfc56fb2ed6b63855697f54c2f8f6dccc8f4c778d956bfd2ee574bcce7d88ceec0e88ab19199e342f61cd874c71b91c1e34fc860d3dee30bb49bf9ed187edeb826e3a2bc5feda73360f7fa6175f6ebe5f4c7eef3dfc51477d6adf45efbebf7e33a74cf09a4f9a1440e9c0ef2f179b0d54de38648beb11d37769792b9c697f4a99d1eb16bc1c7c62635a98dafc6d7e39b30b6769eec6d2dd9955f6a58fafe4166829b05d7b42bf1bdb1dfb95b707c9bc7e3224dc6a657c766fe8e1f249661479d3d11356e8f1f6d34d1dac256ffd8796fe7b9b598c6b6e6cf18c176b4d8f4ece76b5e1ddbdf4eddb98b8eff61e4e5c0d8999bb43286b7e89eb523676fbc3f3e181f8e8f82f9d8ee14e17edbd6f8647c3a3e1bdb673fa55e3a43ce45f3dbb32256bf4efc8937b17e903d1d7cefd6c20b5ddf30ad6ced5c3b6bac7f3009fd55b2fcc9f98eb23fd246eca92d7b63fd4a30ef9b5eebdd4e221bef91f59ba86d2d9d492c52683c175d674757de99249374d29d642863cf5a1493bef515f355af3919e44fe32bb13cec3a85b5446c3ab61d27c3c9c8f517fad1adf9d8f21f06977938d89be4a343d71f1e2cbcfd926edd9d21dfe9909f7d3e61cf3574c464fc8be7bfe4f1f5775f74bdf97e32810d60eedbfecb758f369e7fd8de57fd732ad7f86132b5d6b3f5bf26b3f071328f8e260bf5474ccf4ecc68cd8c3c9f187933312d39294a73f41732e08b9dfed1fe71addab680193d93cfc9c5c4e6539dd4267599e3d65a703626ce6d4c1ab043fdd2dc3f43cf99cf8919411333c727978885999e9b9834268c55d833ed66c64ccc28b0114a966762f29898993931336ef2108cf4bc3ad61fa27cd2eed911f3d8fe21a6e564911d794f62abdb9892d3453bebce13338327d61a32bab8d7125bd77a84dfae7decfa23dcc3cab508db4bb63caf6d8d01d9a8c6e4cd8e7a911cbaf7f84474c0c4b6f387ac37f57d597718ec61cdfb1db123e8442743f785277bdb76d2fbf67b737f7280f58f7db4cb838cb8727fff6a4ce8f58c586059e697f636a86efa6e9cd9b63ffcfe7bdee3de6b8da361557372d4d6b89a1b0747dfe826db6e76ec99769c9c8a9f6dfdd9891d6fe677a377f7ae56dfef4cbd69303533646a2c99a991315363cd4c53a4465fe414adf4bed511ce5e7cdf99d3bb357d109d31ed4eb3683ded656df1d2b315f63d754446aa6c413af969d47672e045f64345cf62878726bfa037ed4f07dee774181d4d47c1dc9e699fe6e61a1b9e0c5be955300fb013c2eaa1e9d46f4c67c3d674ee776cfcc61ff16c8aefde8fe285d3c57419dc59399b64c8d794636a46e4743d2da6e6997e6ef7ddfa6e5fae7ba760056b45cde9e7f4625a999a5139adc91ea5a99102d346ba9c364be7477ee68f5cfb1db78f016bbcc3cf7c386dd97247ede9655b6247a6d7a7575123b575b91e35eda89f9a724cedec37b3717a37bd8f6e8cdf76ddbbebbf4e1fac8fc23394d1de56d7dbe82bfb523ea7a5fdccd28ff61939cb69f27fa45d602d18ec8d2efb077f4467bcc3aff826d6c534a64f18edfe8ff7b73364e7f71867eea4c3e9f679ab3f5c9460c7af9c1c71dc96c699cdfb59c6d7f465da99bec66fd3b7c1d9d47eff31dd9b6ed2027a04711ecfa43c352d3435f263caf8c1c376aebbb9fab295294e363cff4686d83db2b1ac1859bb797a84124fe49ec6c3fdb6da93b655a6c75b1fc8f90376449c88976acf91db75d8a9add919d67e2193edbaf1d4f6fe93f83d3393eecce89b5910d6273ccbd0dcea107796cf9461164e7b337b96b08328a52fb265168bde98e18c9aee61e685b5e9280f4633538659576279339346daf983fe082fbc8365d64384f344dad77ecefab2463033759f0da57c6c5feba7cc6ccccfea1a339367795bf70ed8116ffd17ee5956d90a9d61a3ae724a602beb13f81d2eff0efafbb9247f9fb63ae00fe9919ff8b1e5516efb7c3696cfefd6eabff821fcbebd538e529a3a6bec787d954f893e976297e6f733330e67c63fcd53ec3fbb9335fcbe797666df49f022eb23c1dcc8b162665a72b6982d474170385b41239f5306e10c1e668df3376cab3dff5e86b8d960e7aa8d5216b3b5fddec5441e3012f6709d62ae97f4508efdb6f6deacb0dab0f7305cd998b7bf1abdf9c3feaa3feecec2d16c9375669f7ec3c670ecfeaed985bfca3e6695998d9af666b5dec5e07e564fd799db371bcc67b69506d005764da365be6bce5a36fee156baacaeb2d1eebdf4313987cee1790a9ecf6ffbb23fd75ed69a5c78c17433bb1c9c798bd915f6122d4b670c7fe68fdc886eb265ef2f8c061cceaec70fdc851fb5ad3799af6637b3dbd9dde8507ca3e07c766f634fd65ab5bacffa0c363a3b7b907fd39f747b92cfd15f7654f8c19d9b254fd415939193d3c62610a9b56d7ff73b9c207067354b52affcdcaffbff2733636706508ffc546794fd90a7d2f7bb7e09d3a66f75007f8efef5f95642b8fba762b9ceda76b5c11f3adfbc62df8fe3d652acbf097f84e7fcac2d3b333a65f62473afbc6f89ba64774df5a7fb744a25b73ac2ca325b2aab0b6c69ad7d3c3072636666dacce43deb94ece1f36d4da9b3acbf327b95f799fc70de9b7124bcdbc4c6c4dc1e2f93dfec4de23c767d99e7aa7f5807c73e9f99f9cdec43f2b3f190d9de6cdfed2f58949ee31edcf2faec6be91ecae1cab59bd72fd647ac1eec87a26bdddb244e4477da585eb496b58cd981b0b37eee6687b9a9e7ec4874c6ec78b4999d88df36434cc7ed12c18850195cf6037cf4c747c926f8101daea3ed05ed6f75d9d93723fcaf5ed023badeb1bbc7e1573aa9a4d3766788f581edeae3ec5c2242737feed9757db7de728ed8d6838cf7818d0f5a3b81fbb55ecb673c759dfd462c977920a74ee761dbc50068eb59af6d901a7533c3cec43bd101aa070eca312d5c28f93c46e9edccf89c4c6d8c649e6445af314fe7dd7916199b7adec37cf7b7739c7e8ff50fec77f3fef4cded566c39d9ecf62ff57bee2c5ae1bfca9af4e0117132bbc6f3ee453d2313b24b2ba3bba7767d55cf2b4f455e58fd29a3dfefcc077e311fce47d68fb196e63c9f8f23b7e30fe7b1edefaeb67b4983a9d3017226aeb4dfcdea88f9c4c5d91aba67b5bce65ed9f147cc6f527f3e9dcfe6732b9dac0f61dbd5591fa62e79c3946be1af86175e61e380b66dec3ad17c395fcdd7f3626e46c3fc737e31afccab56ffcc6ba23be675aea770b41b9d7eb4d501f2b68b69fb4b9f7deccaf3ed2cb3ebea368af2a3eed819c13f7cfeda5fb5d268326e8bae7a6eff38e277d21b718dfde3eb38d3f7e1d815e16534cf0fbaad79c36fcc9bbde6bc35bfb433c6452faaa23be657f96a7e3dbfb1fb8fed2ec9f9ad1fcfef5c9fc978c27ebbd2fa886d75fb4bdbca762e7b628f3bbbd7ae619a916cdf3735b77b75cdc899cfe49cf5fc49f6cd58cfd8c640ecefe6cfd064c7d2132e467d20f1f7f98ba437efc8de9fe98becb7b1eb1ebaae7252d229bec8469bbf3b63585ec7663c8bfb3d4f249ee5f6efd85a5b3b74d2d6bdca2a1b1ebfc6b5beece5b1ab9c83782fb3657cfb853ff1ef5c4c03ef88b4e5b0d7fcbdadfbd9e61f7256d2ad539c49d4c4c6fc9c0cdc43ffec4b64d2bef325ec87f5b969abb99dcd66e4cf4ddbcc4f4aedc775809db56ceed6b47d62dbdbeec3d5b5ec93ef9fffb7beffc9735627da7eb775b29fa1bf8da169bf63f4ff90ce213cf363c43a312e2d5ba960ef5b8b746ec797952a75ecd732ff9e9fcb5e8485dd4563f4eac28ccf45207b00adae777b13d0f7a661bfe93ff737cf22df5bc48b647c1c9fa5cbfe7291e673bb00b7c8f2380f8777a19911a629fbf1647ce8d58d933df482eed962b4c887fdc57831091f2783d151d8b76b10612fcf17d3ac981c8461f438991a07671eb426d3a035bccbc3ac08a3c562b1342ed22ab85cacb362fcb4b0ebec7178bfd82c3e179b301ade4d4fa6d6951a3957cafcdefc7b3a7f595c04d5eea91f2c2ab3869f2daa8ba41ff8f1a2e67717f5c45f34fc9ed10dc345737ebd6865c5e27271b5b0b5be59dccede7c2f3ef72f1677899f98e7ba9191dfd12259dcdb7a1b1b34f13df35bcf7cc67e6ad2ac9aef1fccd0795c3c2597e63bf3bd79eecf7f06fe6d5237ff7e5ebc2c3aa6ecafe6df6fe67a5f7c24f545129f9b7a8d177b0b334216d9e2607118dd2dae17478be3ac085a8b22baec0f1627be973e79c9629285836e783d3b5c9c2ece06e3fef9e27ce92fbdec7e512c0353ef6369efc5ccb4ef8c9fb61d83cb65b8e5e9937dcef6c732faf1f9bff773fa346df7a692ff647f7867f3b5ef41b3e5306364b434e362190fefecfde9097f67fb1fe99876983e4d4683c3697b99ccd661649e4f4d7dbb66865f0607cbcce8d9ebd960b6b7ec1953bc1f1f2c07c9c9e2697cec45f1ebe42a3e35be696f395c8e867dafbdccf3e672bc9cc4f7fe831f2fa78bc4f6bfe91fd3ffe313d3573a0edca7b9a047da5bf966e7ce7226bec9c2ccc1e55cd615acafbfc4bb97dc5e5ff830f65ada9540231317669e2e57d82181f5e0d1fe560658bbd9dabf5cefe09ecfe57a592c3722d3969f78fe4c3e9d0e32d7f2c25cb66c90ffee4c1ded7d9c5b737b90c2b6eef7b1bb2996b5b033b3ebcb368dba9c0fd773118c2fedfa09e5fda07f5587301686f7c24c3f652dcadde3be64d32e0b53a6a5f5e9ccb56c623dc393b3318b91d4d1be5f725a601f5a5764a75dffb03a98eb18aeedcedb5fd695d89edcfbc0371e595e865fdbfb9ff8a4ce608c943606cbc7f53167fd95bee773cb96fc6e79293ac4ead28ce7208dcd927c8ace585e0523bb57245dc9194bbbd76269d2581a1d66638edcbf4e7f56639495527f7cab4710a759b9f32078efd2b0216ff7b42b56de59d65d1a0dd94dfced3bf35edd730dbb47ca1bfb8da5dd1f3c4b8bfedde06a1289d7e96261a75b7bd4d5d82bd9bfafb2e7b3070decae9bf63672076fdfc6badddaf04c76cbd87304f6ddbc7ab6ac16ccdd7b3ceefc6264f7397590beb1bb6dec67791f35968697a635968fcba791f16796cfcee694f7bf6fdf27dcc03ed9c29d25dcb833f11d5d47ffb357db97f70adade7af1926567f96adf0b63f2f0dc1eaf7b777eb2331e2f5f97f60dac67cb77279d6c9cab63ca6afdb85e30f7726fb1dc1f27cb03b1c8ec0cb23e1ecf71587fc1ed5279d8c622759fd9e9d7cbd9efd7b2b6bc7bef9fb86c19ecfa8addefa55104f43323398c33fd701d6037a5ddf36ba473af9dc56e1ce4a66d8c95b5b4abae2f720e24be30fd65f7661c64ddde265fd975a2e5f1f26479eaaf701e7385f39bfc1b02d24775e75b7aa5f7057c779efda3bd3ddf762db6fff24cbc603b07ddde95f2bed4d299697db71fce372ccfc54e2cefcdd418d82362253ca7f1b0f5d0ac5dc958cc17cfad2d2dd8bd59f97607caca937dbf2a03dee40a9c11077bf541e498f37e63d8af764dbadb7d747bbb8ee4375fce3e972ffa38dfddfb77ae4aa99ca6ad56466eaf2279d789f547d447aa8aae5ec5b2877a9588ae18f36d412772767f95a23daeb03b1df6b89d2d5ff62c97d63bd4f33efb9117b39fc48ffee68b33c5bda969c7b3576f9bfbb6be598b9fd7646f85dd3fb6eab6bfbe0f8c3e26fc6aab435699c400edba9cf59bf55c3fe3a0b415cafe6679ff9c5ed8f72b73aa22670b8d4cbe3576dad370d43db57b8fe2e770e4f6415a79e57a14ef1eb1f3f245ce27381df4e8ce4337ecfc5ef5567dbb276b5edbc62a9cccb89a8c54b7b855a9ed3972591bfd3e4ee25ad64687cd4858d9d3417babe1788a73662d1b430ae656060c2e8337ebb9329e6e5b7d35dab28d68aff2d5d8ee4674e7dbdfbe795779c59eeb737127fb1ec9bfe77db24647d9bd5ce9663559deaca62bab13dbbee7cacd5350ebb65bf99ccda2a3d57cd25f2d56cbf9e36a65f732dbb321f68480b562ed6871eb45ce5a95bd073666e5eaf7107dddcff4f0e3bebaf2a8b5eb23ba77e2fd1ffa7c91f2d112dcddefe5d6b8b9c3fd071d289fb6ced6c24c6f930b6f62fae4c897773dd660ff3c3a9deff674db3dcf2bbb13c993347b8746077767896de7a4865824dfb552515d62d3f2be7bc717f4c8754987bcae0a1b275e6ddadbb8cf71fbebbed4f219876bd141ee3c34623856ef0c1e569fab8b922e799788a2935b5ca17ad9eea329bffbf0073df28e5d14a7b0bbb18fa86766e1aa22efc0b5f9aeacfcc0085ad5657f17d3ed47c8d76af56ee84ef3ba3abc96e4fd6e1caaf9cdbd3f19d7b2b670909b72d9f298b65d35e59d62e5772d5a89349ac8c9b5fe427c3c2b33ed2e98d160d5b2fbc6ec3b469cc582758cf27ad20fe7f079710de1e12bbbd179f20feb9027e46b75a4a9ef4a67c9b68fe93ffd4a07d933aaab6b9c6367ffd4da5fde87a2b149c4feac54b57b2decb990d54dfbebfe8aefde359cb6bfb105709ebdc1f55ecf3732d4beb74fdedd27fe4705fb519b784f0663fc559fef8eed94cecf35ecbed5c4dc5b19ff62654feb9c96de25723599aa2cd15520deffeabf3042b9badf6a61b787ec436425cf72ac1ef26152f18b553beb8eec68f1a3b65d9b5f3dae9e448789aeb272977b95c6e1aab27a1e1fb97a528f94ff766dbbf4fddff04ef260393e58d9f3eed9aab37a9d4e57f694dabd17b9fce55d2dee9d20ab77a3bb5ac3faf0349cac3e96efe673b4f2567babfdd54170ccf527539f52fb717789db69f1cbf5891ff73b85fb76bfd63fa843ec2c3f0cee6c5fad8e56c733ec3891dd2fdbb57ab73ef25ed21d5fd231f535f6c3bcba3a599d7aab95dd55daee9eaecef1b708f8774b5acea628ecb99b35def3bff6fccef4d43b72ef9face26fc2ac314eb7efb497bf6375e3fec65af1133df22b19f8dd7b06cbb676f9bd45e5eb45cea2db13508c83db91ce5d073fdb95409de1e48791716b2337d621e2ea3bfb765cfc7ccf7ae26d17d758476d7de73b9f2bef76e33b3c86d375bc36d6dbda9ef01db575bf9abe0b70f74cfa5fbc6c2ccbae3bd9bf8fb236f2706d46f3ba676422d768ae65af5c62da6add97b5e1a9912e8b965818367665576ddd3beacba3ffbbb5687c9f60ad9e7b6275bf5d593effa7fc11eb3fd97707d8ba0fd03fa5f5f16057b7ec5cd6afb2d19bf5d05c23899daef36fc622c6a3f589ed2ab2dda7b71e97c6e977e3b96c1b95f7cf699afa5e14bec384b1229ead586bdce7abddfe5dfc06efeee3fbc7e327bfb19ecc47eba9d4d0eeee0efdf5eceb5aebcefe1b6ad653d129c1d57abe5e64954477aa71ef265aef4ad6a5d7c6b35dafc2d17a2d79592bc48d127fbbb7d8ae3e592fd7cae2856d651b45ad1b59be11dd27ebe8edc5173952fe7b7e7ff6d3f86b9e19216ba3f3d626fff5859cfb9b75b3deba9275d28f60beaeae6b569ad835605b1fbb93c24519ec0aeec356a7feb8ef69a7fdd84ed81deedeb4906ddb7577368507b27fee9fd325b20a3048d7f57543fe8252e8f6917ddd933b7d6aff5ce7b1af717a3c6e66857d0bfac4ee86cd313e9bbefc1d4a77fed39ebc36eddc5cf4d72d7eb7f37e94f2beb9edfe875fbd37befceec5f299b8eaee9cfac9557e3738edf9b6c8e5f5254e4dd93d40a675d6bb67ce4ab246f77de19c82931d26adf5cd8e5ff1c4198359627588ddd1725192511fa2d519e3b2e9db91e7fc9fa1d8a96b236ff2bbf6d73592f64fe4d35fb8522feadaf7c2d873e9eb7bc9d7e69f9e88bf61cff8bbbf8be26d756e794dfc877dafa5ef5cec6ae75c9eeae1b27f421f7067264df64bdffd039f36fff5c3babd7e94f8627eb6ed0fc6366d1ffeeafc885e0fb2c7796deab97ec6787bfd46475ccb7b78ac3fe7d6c276f7e77dd74ff6fbeffec6f0f67dbf3fd30be573d9dc67b4867cc5fcd4b3bf120b92b505fbfc87df59bfac3bebd7f5dbfa1d27801fd61fdbbd9a3fd121e7d21a7cbbcc285befadb10796e717f8b73f68b5857e1edb78967db70acf0dac0f204fed4cc30e36fb66212bc3e7d7e1647d349dad8fa3a3c4daaf27a57750eeeaccbffaee7c93763e307ab56d63fad1d1f4757dda1f87a3a8919df6fdde9d3d412be7692279bf17ac511be7d35341eff6344112bbbdb93a024bb141b6236357d8e75696c9e5b50abe85c1eed7fadb7729ee5c6ee592fb6e6dfecf3887cef347653df24d5974ffd84b70b7b6d2f0bcd728fc609e3ac9fc839e70ef2788edbb80cd9871ef862bbfff7857e794fffec8f2b77f7fa4baf3f99d5ff2b3fb5c2b29bd6784ffb67f03a4b0ab5d46c61701f448fb272d5a6e219e5b3123bc3069d8d9411d63cf22ba1de367a5a8b12feb097a26cdfa22fbb2d66ecf5b1411dec93894f559bb37c0fed585d5aebedc5d13f93b7c92135c6d792f7b11cbf99785edf1f5f6bd5eceee2ef94f5fecf69fe9de87afeda97e072d52eca5559d827387dcfbf08ffb231f523f1b81b7f9db98dcee99c41fa238edafbf9fe02c93fdbdddbf56d81380a1585be5b527ed43c6afaeb12f63d7efd8d51ffcfcb93fb2fb1ea8257cfff2f7d59dabf9e5f9ed1af5f6ddb5f29e40630f16693829ba8bb3c29d5c2a7a7ae670c76efd628fbe94ec6b9ea5e0fabb7d2bd1a8e8dbb314fdaaf82dd6e6b6766f8473cb3c87626749312886c5689e8e7c6f51189d61f7061463efaeb032392ea6bd97c5937feee3ef33aafef8d1fffab39f128bef488bdb732d5e50cc96effdf5bc657bdcc5d9e618cd9de8cb79fa7e54d211e591573e476175ee39628290d5c93e58d7494ae7f53012650d7b32fafa4e93bfdf1f717b256cffbdd8185712ef9eff70e78618ebfa690c0ef5347d5fcc83f9f8322dfaefc5a29b489b96fa49faed3a98f7faf6fda1edc5b76740b7efd4dff671f9efc1fca8477e36bf7855bfb9be7b8edff19db3909fd6e68e27abcfc2c8ee62d5feb2b6fe831dbb73b175dd0e6aab7103796792db0360d22a8c1c2e70f67e803dacc546648e5d632d3e8b8bf1ad3de1da767fa9c1b59ab90a53cec2d4a330e59efeec7dbb7fa71e698b4c8b0645dd9e99b67b538b86c8723b1b66d0893c7bc9730ee57d4e3ff826ef5f6386fa9eaa9b9d75a6f7ad0ed9dd37f59f5a67b752cc5ebbef7274e5b82af9a13b6bec22f1a0535f25565598f155b4b6edbadb4fba3faed296d5d9dff9d4eceb74876baa476a5fe6d28fefaaddd521bbbaa42c73656e16f6fc967946f63a195db23cf31b53e327b8774f2cb0ff665777bc977400d78c3f648dbdb8945dd1c555713dbe995f67cf9e7bf7888d83db952917f37910bde17ac3edf18ada83c3f587953d767d7a9da595f8c597f7ef5d7a83ec7af696568b9be2b6b82b8c27adefe9dd95257f7d8d5dce1a9a116adfd9523c743fec0ecbf4dcc870affd250ea556d67efbcbd90f3d53f325962511e1a22d116267853c6645017fad2ccbdd1b9d2af36892664518b4d59a0dffbff6feaba975a6690385cff7cff87cae2287da474eb2c12c4004033e9373c63955edfffecd35dd2d8dc632782d8c59ef7aeea2a684654b1a4de8dc579fa8cf27e27fb2f3412a9bb1707ee7c85824c8bf0f2aec59947128f37d1fd30fc977014e8ee2f7e30662f61295c513e7e8986b1532cd92e59902afc5a9a187989898d17a91ee167ce4335af8510c6c1ccd357e8f38aac53369d49aab8abcfc1b7448f39037d200174a37598017bcf6960b756ea1467071e045722485b6ea95a068f4e290f25e16475eb46e4a9afc171bfd3cbb6812fb8556223ad7be250b34fa1b6097b13f07b61b5d67eb35e4b9813e51220a000c29e45d003f0b188b8b63c2235c481ebb7814d92f84d8ed851aff05f8938c25f0017cf23b74388337d083f8fb052c27c3c5c5e272e92c13c4d7b7ce63ffacc94ee12c3dd19bfa6c5de8b1cd0d9fc11bb52df090e66de92fcbbf53fbf7d3b6a91eccdeeab337477307e8669d93d19cf808db64b6a1518f5e94c69e93269e58f5ef97956575a9f8ccb23e6b2f1b1c497f497e10587ae14f81cd68d95cb6de6bd5c2b23daa2d14bd98209251c70f3096bc67d4aad8fdfbd351f54363ef979c62e23d315b76140d7708070ab8b7da1a5125bd6ad95df6967dfaacf5068769ec2b4965c02c435cf0f21df8ef4e77a9c66339acbc2f4794a3283a9ad6ce6f96e379be9b47ccd760bad49899824db09cce52c0c7edea982a8e4e31a24a97b3515147ae3bb63eb343bd45cdef72ce91ef97225d553ce4516a4c173def4a2648719538259754fa8df258d7aff7266bfaf19f1c6dfc65e3fb3dd5d53d23bc278cf47211b53d6d6d7934e457ecaea5da01d343f25d036d1bf6a9b1da19cb154b2997cc4380b7d5210c62d439590a3696992762d3935dbf7f9a79c905f154f88181bbb14c31ed649eb14cd37b21a374a9fab7645e11f010c648111ffad2a5b1c5fbf4789c13eab7cb1cf38a22496dc04a411f205122bf46d36cec9e33c26a7e2f1bfa80a1f3e0b9c8dd08f485831df2106b6e75ae6121aaaf80ca013d095455e7aa1e7b81beb1440c02e7deec648e4c7d649d8f7c270fc1d1234ba7ceaa74285e8b109545defd84d698181c684ffe2d667e79354800cb6a79ddb900aaf1b2d0a9751acb9be52f8eb057cf5bde2eef902dd61f9507d349bda8b115b34eb13ce7ba1305434e95bae5bb7e7fc4626512fefbb073bdbc6fddf66eea374b0ffac164ac33559f5b33ec8ce5c3f271895da07dc4eaf368f93ceb3a3354b4d1e8e48c638b6be0efe91d4ddf9645f8a38065ac66f392b058eacbcec5f285f53158314e66a7cb57fdbec9e51bc54d97d987ff5e6c679725cedb61fc32338e4eb00c44178afaea77c34b96a05c1213ac737f28be4e57d3cb912ef9de18df00715dcfd7d4197731df47b5e4f2b83c88c52ffb135ebf7d3dc4ef68698a9f815d627962c46b3d867ac6474ddbd38d5d82cf4b255b2fcfc87685bc3d60d4c3ba0c9abc64da8bb8a7ce0bd1ef20af50f20c4c3bfa77f00eb3a915bcbce0fea4280f025968c80104dac5529d5f395c4b04f9fdeabd5609ca1d0122c1caa75805e820e227420635f24cf06e01d63937c4c6aeca8ccf7b4ef8043206c0b2ed30ee098ed89de803ee8b710d10dc04a3e4c0f0fd5f7ab1715f3be123871c8123b6ad22f18ec198ea290798caf06d9d53cdb2c685b7bbfaec3fab8f649cc5aad24f2302a47c3e196357686d2ce21dfb441f1169ab441207fc09ab2afcd3156f555bd5578dce01b0a5a07b089efd0a28701d67ac6d6ca81b78c678178aa656951c1fd40b2c04b904dfa38f00e3319758e8b85d96e99b73e849fd2a6aa5b41f1c5763b69ce95ccf05ea406277ac5a4e717abe6a43425c75bc008b173c45e754e21dbbcbe74aa1d9981e7613ef437fdc551463d553ad3fcdc1d6a5fd4c6ad7adde576dbc6fe2bd9e6c56bca00640e7543df28068f76a60485b8fe4d30f72012f19a76bc73c44e675350ceb8ae8f97ea5a84e50166da73ae0f951e3d9bc5c8d9a17f03381a2a879fdbfaf8fb07fa5dc261feb6a6c44177ce443dea08fe8e32bfb012ed80fc2b8c0d062250f1a3c66257e5889eb113fbaf4ebc40bea7105b4e43b6c5b881fba32e4fa22c50abc97016ac1cf2dd16f578c1fb6526335032598132fd43c48f185d582ea05a296e44ad1dd15764592f432e0e7c3b3ba4a91ed0f7c4747afa89db5e218e3a17ad62a435a3f227de01f814d0b3c44f252223e988390b60791423be421180fd4245e2122e7d40b700e747d15f4f995c7c6f3024cb595cb3c7797fcff67f5911745bf141d874fbcf232d458ba2461d9f15a9fe8236f952836a068e625b291ad72b4fa707e8c4caf31e705487e0cfaf2ea90ce5177c87e6ed6fe306d50bb7cff0cdebf3cd031afbcc27484feafa50b1ea173da291f72b1523b67754578f489413db5423dc066f50e1e536042b56bab6be82cd581e3f64f156daff378700428fc2d628732636bf1bb95e223e545b9b7ba616fabb68e0f757ea01e4fe8230635828f5f7203bfd3170fc48afa2dea62a20688dab58a2aac7e398b9ef6fe490d4b6fa2733fd26a8c6e413d1c8d03b053dbe3cfe9232cf72f5ec94ebfba33f88191a3f861f32c3e1213d723b69ff7e7d5fdf2da5baf5bbea9ed08fbe4c3f7874ee1197e07b512560f5c433865e073e4289e2bd0934033d5f880f7c1ea091cb3f63bb005564fab67aad514c465199896413c94c4f71e537ea6e00dac8a5e50836a22988cb6446b8fbf35de5f694229305fa889857168962a8d9e9ab715f34c5493d53c5efc4aa24f9e13cfac5d1abc6517f3f4b3fa08f2889504d1bd812fd8bfd29afa1acafd16726b44ea121e13ad65e41756afabb7c42471c31889052b579d730d2755c6c8d8854de4b363c959546bf5c6b84d7e0ed890743df76ae7b18b7ac573d44d7774adc27ac999d52069951295d541a2b33a74ba9573e004a8f7bb5e1dad8e9b6dd4f15b9dac4ea758dd8ee030abf100ef28fab73348b28390e76a1de864d0688e094364a5f4b3f2015dd75e4cc66b3ef6dff27f6c3b7feb47eab7d283cecb3d5f499035e4fecc1227ab0baa2ab8c22eb87538f6cf9b24755d17ff155562e715eddb5aec4c7ffc79ff08fbb351776a5a67b99769df6f638fcbce92cf06fd83269f4c948b0db52b93c87b169cc5b8380013a3f1bbf9488972eea12321de2c59c68a57c70ad1f6a4a25f0df57d7f48fc7606daaa5649b266f43f4d3913d55b3a57cf53cda5c931e7e778acf5428ae5bc8cc06608cc6275af649d9e9384dd8af50c78ef62c7f99338ba2f37e649d085928a472694c4976cd17b26db54636bc6b10f62b74b760863b1c9586a71b15a5f9aa79fd347ce880e366f56ed6417b6f85a9530d195bc1b892bfae4c833a76b15bd195a3fc7b66aba8891ec35ca24c3aa4658bc6b31bc08400ef8c837bfbf46273a70dc641f96d6f9db2a937c4f2a4d3a396c7b8b57a7981c55d3dd036736ee038316d246b301fb542f5ff59b3784673c85fdedae511e6a0fa83f56fca6981cb7a7c9c9f2daaff8478de270f85e4e4e7525bc02f9e47b8c92f19e55e37c4975ff9233d49e657f8bd633cc7cf6981db16b9fba79e4ba32b07726e7cdf7245005a7cea2d64f2e93eafd93c9baae9f8ef880ce93b348aa159b04a56df7ddee1161d770bcd6ff757d24cd7b3e47347338e2bcf24b2fb0956c4d7b36f091aaa03f9f5175cd0886a39d9f6ee64a9a9fbf918f24990fa01eb0f616de914f074873c8fc820d071e565d4f12f43e4b988c669d45adb31878c1824f0fad1f7e02f09f2478b2e345b0f6033d459d4fe6a8495d113d070f31e31bc7bbbfa9e95dcc7100627bac7609b312b63d8de17c403a0be2a5e11d85bfc48ceddd49fb597da44098ebc052ac979279d4e61bd66c4be216b4c78a7995cfa4dbf8b788e15a1cf7f3fd5bf23d3b73c69db4e54e9b8f7c872dcb3cbed0739257ce0c7891a8d6895a6189d7c110fa8348435211c06f3b45d4c0d5381f197f5c5e906daee1328e5446e34b516c755ee353fe9a2ae92a790d6b6e74bc0413b37cae9ef362f8b21fc5f7311f7dcc33ecb66b9e823e8cfaa8680a0cff6441bfe3b8dea927910557adb75e6be3c46cfada4d246f92bf2a57e56eb5a3784d86b17abc1dcdd3cfeb239253fc4a769b59977cbf5ae2facc5662d332b171f175413cf019c5bd6a7a74e685787ca5284f8bd4bbdd873ec2ef8f98db1ec75b95196fcacf7b816d4f7cd9c95bb25c6b4cb314f7ff998e5a6a135fc1b317e6e0e588a7203a3e620394f112de227aca8077a3993f62da0a9fc2f1dd877e92bca33833bc8f7e479639c04f92f78b4943ad9d86e820cf216f951a62bbe2f73fa88f3cb33ea038662bedfc028e54d2a3e8ef966ff1880db486242c432f613c5fec101d497dc43b64091a83d154cf7be6e78b8c69b49deb2331726c7054b431f930be4185212de1307e607be15f493d10a92e878c567cdfbdf167c3f3fabcd6776609d5e01ba80f928f4920402b9a8b9abd1ae7f610df118e63f2d9a22c26cf7d032a1ffb4b9e041b13b6b079697d9c0dcc925889eb776d5bf6f7eb54b0fb40f5265be9a01e8c1ab7fa6406fe591ad592451d7fe06abb24f827a4f485e6a5bbb14dfeb83e12c9cda8d3671dc50d146ca9d964626398f9d86fb40b922f5e185587ef5fbca01a19ae4bbe7a512cd7cff2f277d5ec5c4da16f465c31f2301bbfd8e6f4e80558eab134fc5e902e285f2239241e51bf21bf00ea6724d56f3b39c23c06a22b7854e28978aa543ba54cdd90475165662f92b7833c95ca43f85cc17c8cf857e27887e52f096c93717e9452f87d80e152328e6f145f37169c33c15be498de72ff9bd7672a9ca71fd447d2c65e05f6c403f0e65bafc992a211c5f7026c3158e9c98330bb26a8b7c83b04f416769ae421d964e697e4634870551b1f35c995bcae694bcaa8659b661bba997b9633fc23bb78bf57c60094f7541a37d7d573b5def04c56ef8a6065f10ad69824360f7d249b9460c2248f66ed41a9dc4b1e0ffafe39dd03e3957c4e9e244ffb8f0de4663a8e8b5c1344e6086a50404d044fd9f1b8dab441e3f5b9d15cae099017c45668c63698fd7b8bfb2cef56f136d65a7e0cfd36da3669dc77f100cb83e2b767141301ab8b3f699c4f406da6dfbc3eff0e7dc4a4dd4ddab3902d81833e2c1818f3a5b04268a42e3c327cce8916ebaac06d5878d996734e1ea7ee8917e6697c17cfd8f63d25ef9065e8f98c6c571144eab3183e62d166c4a1758b8882279f3a2a616b5be009c5c40209097e11d8b3e04f08fc4e252fa2b7e9dd8638b66668d3125d2e796949556f5ebcff294e4f8ce1156bfa6529e65efc596751bd918fa4794eb6aa24c7170432c12e6d579fc9033fa78f44f386b15717a81fd229d64f666aa6fb1215fd2678bf5eb4e202bc4ce5fa6d62d57ceee79d623d9f725209a577f494ac3e2044b7943fbea9698e19e42f7fd8af401fd9c5fb092693f025fdd91f63d43b4fce6c3e6b15dee1a97be69ab6fc9ec0488ccdc7901ac60e614beadc0ecd83484f10cc626db342e4e27daaac63c17c8af1b525198c654af19ee67836d7190ad821cf749fd17baada3f17dba0ec10b6b5993cc5ec9fadc56fd322fa66b84345b71ca8d599aa19750881cba3debb76ba23ffc7dfad8f98f415da34f057b95689c628545248aace91df975e68cf971d7240b517bbc75ee82f60dfb3b6915f504edffbd48be71bdf95a31ef78e668e0aeb28a8f38b3fedd736e2d3b0ca0543df5e5192f3a7a51fbe4eefaa63635ccec3959e6a2c2e524d8edf7ab276c913f95d509765a6f8cc50d1ee548baf3fa0bcd088de21f15e81c7d6e225256ff32eb1be0b788b956d6d361d818fac00a9b322f56fa47671e91be62aaefdac3e920bf6a6abf988d21f46aa3937f5362c7a58ddcb29cbcce7511c58b4543b314b753cc2ad3f74dcd9a5b67f503c96e72caa4f959314761a72300a8a7e4f1d3396773d3674d7fac8d4d04570843ee251dc958ed69b7a84fb751f62ef6a9d43e923211f09696c8df58620e3f829f4920a7ea3605196594749f5fb69e03dc247a457de09dfef897dee77dd9b146a9838957c6a40b919a921e212fc2becc45a43e2bb2a9e19ff16d8b81e6378c8267f4a64f754d6f00822bc6450ab2282bf7e5e3fa99734be599122e0039d7277b1bd7fb73e62d62e697a614df333aab70e6c8ff28317d49a8a70639f703f02fa2c58c2432fd03d528a1ea7c66c3f8fab3d95f2d663b67665578fe3976c93e978c443748d261383916d4db17ca464f09267e221c038c6ce81e4a56ba73f7a119b95c6cecfd18eac303290fe9de807f7d40fe434a2ce3baaf8614cfb6aac53132fac712be36ff272e103a67e68f779139f8991ac8218b25278dfe16d6aaa6b8b717ecfa8e685d859af7be2233fab8f888c2efa08fecf3a8b4a87b0e5db6ff562f7b872023aa871612d5ffaf47e5e699c3a33aeb73573729c874e7bbf086c8cde4ba2d3293ab3c0af6ec668c5f4a73cdfa13e227428cc45d1b50f51ef1e5a75ff9a6c3da0ed417c1a249a82e823eb34582a18e96cac01e90b7d41a853b49d2420cebf68e878ea4a6a564fbd5f53bc167608f40ceccec109e917a9796a915a92d4da2ba456a964e26c591d4e7b2bb21136aefce3d61557713071ae1eadfe99e71f0d5ef3813f44766c903764dc171ed53976c81d8f9dce0c6019c0fb067c81bf531f3163fcdfd6693c7802ea64cf1256fc9647752b74ed43e12322f35f78a17e82bc88acc51f5eaccf19ebf85d3c44def79c6a12a752965f40e8e77d0c46a24d83e3f26b0c1e625ed77e22fd2e95269e20985de03d03ceba828518f919ad2ed59b45de7be28ab0f353cc63e66a1e126f948515f157193c0ea880d8a5ba021ff33a7db4fbea197d36721951b94df2f231bf293577cd4b6f3dae6e5fbaa4ccd9cfeb23c44b9a4e2642eb67e34ecd5926fbbf526ac45239b6d73c8672f120a1eb2ec25e855a8d849b7b81ba8b1ee18203170412499bea14b55b1c0f0a9e73eb8478c4b9108f38e023bb9467a5a955d81ca6f2a92bac04aea5c5fe8640d208f4910df2fc47fe88185b135674fbdd292e2f12f37695fd20ea77ef6e883f0ffb58eaba750f5f12fc4ba942e52471fe7eace3e928be0df6c659e2bc59d1281007d68e957e615e04fbfd852ccb8873d07a4d33be7fc88fd73ad5395da36b9029c93875537e482a99e2bd8d8ad1467dc2f91e78c7dfa58f98f4a0697dce103fa8bf11ed7d5fb08471c23852afcc33525e807368c61237949490faa5665d7d9f2c72ccafe5e78ee567dfc54b32d4b785c3166d436a34f160027d24d64aba81bf6cb02b699b9792661acf941f823c12cdbb9ee8bcd8c0407dda9c2f0ecc7d581312522f596a624247b9a53c1f6d53cc5acf171ec67160c0e44fdd91ff475ba96ddec73638ade71c501e3f3218fa88439e908ca0ebe40a768de90fd9271ff9797d24e3881fa11ad89a0487556b6744eb13057f9cbaa719951a4e88c3d276b003a631409e035a99d265525eeaa176552fa61e139d55dee9f693e50163de2f347dc4a8df18b827361fd9350f21dc587704fb5542560bd1d27087304ed691ad8f7c9c3723ff23de20a869c5e720bd8037203265c63c20f554ab06188fcf610cb0e46d68cf6c29f55c7d207ba11e9f5767068caed602f926a962eac57c16f3887bea7f4aeda8d45ba7d93caf9f75e64eb171ed31ae89a19f887e75483111a91222e197add4417980aae6ad073d3f337fda38af6a0b8c3f8ee803732366e2dfd6474c39b3eeadf311c9272b501c52f9358c9cd7d5a6abf4bdce2df4087faac7f7e976bc20ff1bf96a5db542526a46827adc39eb59dfc54b4c1f10aab95d87345e6c422269691bd711c7fdda3ce3a3c6f789d513ee498f48a9fba68e69d7d4180955c765dd132d1f9cb275f9887f7fe2456d81291ac71eea144b751d8b8f006d15d2584add0bc870e003a809d2612cce40ffe27ee3b929cc19acd4e7e4a7d115d964ee24deedc48bea8f19631ebfbbfd34be56a07b301f89e66db057b0da87be91a8a52ea41e15afa8ba3f6e6b3c13f5bb2c67691d53a68d8e132d710daa3367562da62edb0fc97cdaa9f4aab78df374826ba9160cfd63d7fa8859eb8bce2d066345ab356268c55b93e72577e36030d4df7fc443626c4411694ce2aa9efd5be8246958ca1dc71d8c189bff9178089e07dc43f1d5e3ffee73ba9cae242ace9cb16332acc321c3ebdd59805a4177d1fcc7789ef6f1ab96ae564ef46f864e11b5c0d2358ecebff7a2befa279c4f3cadd42e49a6d2f5fa23fbd3319f88cf52d74cd28849f0265cc7395c2f6983fffffbfa88f00ec9f130692ff6f00bd333752edd20da03bb098e405383dc5a874f84e3b3505f35a0419e17d45f94baaab0d9a49b54174feb28dfe10fb17988bceb05c55811b2911746d698f2bcbf051fd932e2437855bf48fa08de7f7a67acee472fc0d417fd007a4953f5a17ae985f52c3146252fc8cb48b7587fb17819763fb023b54f43f418758f749b7cfa66ccb6b6ad614e3b1cff3cf002ff7992d745200b3c7bd1f562d7baf9ee35fa73fa88d005a2b909ad2f987e697058e80b0f4a16559cbd964a77577ebf8a382d689fa087abace3b69dd9bc3d705cec984e2add43fd11e786b11605af575b86d5b9fb64bea1deb0fde8cfd2fdca99fe9dc89db63e62d62f8c9353b7d547425bcc62557116e8bb44aa07bc80fd09c44708eff7539fb57d3ea861252b5e7ce16a25be1356632fef8f5ba26db38d0978591a6bf91745914ed5ca1eff727e4d4fd86e9866db9fc7b56aef9c597a605686667f869aa3f410baa347b506091b6c36bd2584229d2bff64f41f1ecea4bad7c899f5d26a3e808d5562dd12e3fbe22cd2132751ed266e03bf888ceb2e6d8f7fbf3e22ffc7ed55db270e8c73252da4a7145f54e61cbb3647f2c186b2945cbc82417f0ad173dae67e66d1235b3f31e995f9bbdfa55f663dbe53a04dafd76c8ad06227f4b307da7c1c9ff80c7fcce035da2f7243f4fdbd49bc2ab8fe91f4044d75801cb120be9b9e6da6d7d0abc6cc8350d141f75bddab31f2a2b93a1c5305de8ddfa7e7ebfa481abcdcc4e735e75cdd37bd54f3fb66ad955de29e7cd67e5e1f31f76a6e7daf1ab23c8e1afbb676e98fdfa735bf754248d21aade092626287d7cbe777c5476a0b67361a63c65827a17b1731e3880b0eb01873461fd4736a59431f09ebb22e029e60f6eb335e22d7482cc183534cafc8feafe3aa6c1ec0f92195d2308a87cfbfa3efe8983cb0f5918f790d284843edcee9eda00dc4d3ca0bf398fb5a1591f5a8b43aae371bf5a61e2fe08e28de6df1443d4e7afcdcc1335974a56a27f84f0fba0470c104673fa5b15b8ac00f4857d46a4fa65390fa827eb1b499567c0a71d04e1803c13a90fa2ed37e4c67cb039d9fffc2f734e6eb7f441f91ff63f76acc9e16f9946356d38a46a6735c8f43ed9a96a255e93c69f011de60e81d01968879df38da6fe72efe290fe17705fdedb0ef23883af7425a2e345fd7f432f985f81dd89614e8335bdabdb092313eb0310d946ed0bbe0e73d132f4e5f514c17f4151def86f71e7ff05ed031c43e77463b10b15e7a5e245f90710a344f820e03a4d4297b169d9097226619a814c1b5a6dc80eb9404d8bcb2d6cc77ea90716bf4e7fd23b2576d395f68356328d2aaa59827e46a8f045fb0b77c84dd0631abc8f0d508ca3a5b95ed311ef3204fe935ea1e65f8e44b4e202f9bbc2ad047a4a6b7cd137ec796928edc47f5bb72561d92669bbef5421b8fe4e8dd73fe083049ccfaea461e39f2da41bf71fcd47f22d7956815d72f17edc5ab3faeff22c92a7d47f158a39bfe207d4fb9efce893f460e8feaf3630caf9fe9f85bf0e249b9071ba3aee7f248be975943d3faa2e29733e730a8e1a27d50b04d35ddde0d50f6a8de8c17581550050395bf2336c034cdf7ead11f6bac46c5bb462bae0d83f9bcf99ff28fc8ff9bf411fbb3994fc858533adfa4a3661d362cb522d20f6a54cbf49d796d402353065ea31daf25b8281217b449eedd96a798f779a65a5288ba087884914fa1d145c12b1e0cfe61c46069f9fd51b26bb7e0212646cc3df9d061f71b5e1325692bcd7bfa8b69b89983835d90fdf8bd10c7a591390e884705310fc29f390e5b68bef6ad287e907e22ec1bc16186e505f92dc1f5c6b8c1ee987eae34d24a42832ea7e78f6380f7c64bfe767d44fcee54175e8f0ac77c2a5aa27d2039c51b8018ad565a1395237f0d8b7d356b3dd53a18f5bc13faed5ff8f39953d4715b05b6d384f5e3173a7f646ef4c36c66fdee6d6898fc2ec7bc042bebd2af94ef0d9b9365bbd2188ac867bf37f2330c5b15be4fbfa45fdf9fb6c0a9628c18b9bfaea800d49dc47b21fd9658f43ace225d7216e301c563693eebe97a5e88bbee46f006e8bdc5b6a5f135617d004f9b239bed6e35734e823973b56f25c57825391aeb9ae2e5a87132698f5ad32453844bca241e61a7aed56756d46f099e5573d207f5515abd7b4d6a54ee5bc6f93bf591381aee7d702fb659a186d3f894ea7547eceacc77342d83b473ec85b67fd173e4735c3fcdbefca95ec2b1ac5a6bb77cec92d787cf917c76c3d398e67ae4a63cbfa905750c4d0dfe95f48fde096143a64f897ea7b976a2b64389bc5f8d197f23d60dba55fa9cee87bc791d2797611c2c5327111f17d70841dd4550b3f69c7810785b5a741973bc247ff3848e13b7d12ab3cd6da7f859dbacd1bf571f31f5019c175fabc77e0fa91fe209eea2da1d6aa57593e94b20ecf460edbc637a96d3b59a52fde9f826592a77c6a3cac9eab29644959bee11be231fb2839c45a9c73e3572e06d5eb22dfe96f0c6291d1b6a770e3b821f16f2108dfec6982083638ed7b27608647fa977b5753c97d8ccdee87af0928c9349a0eae8fcb4e7f43ae501aaa6a58f190739e390fe567012d6fccca86201f35cf59b767f76803c98ca61c6ef1eeb772d46e623c7c7943eaff953bb54eeb513f0fa564e52d7a41765cacbe74cc5e0cdf360ec16f0b367aace385373dc4c9d7deb9eb33d2fffdfd0473eb283dbf9841ec9bd19a59f649a4cdb385e0b3a0baa84c2af92511ae658d1ae4c5bad1aac2497f054025a267a8a6db38fe30d9fbd9ff93b8e17c87404cd22d45e45a2425e47df8ee5b57c1e412ee227fa48246f5cce3f91b6debda7382aacf2b4e4fc9bfa59ed93b14f139e3d2a77eaba2e675ed456283cf9951beb1035b11582dfab39cf74393e4be404d137e477eabe19999b7ddab3a4fdedfac8e6df87b486ce1f38240b6394e74e31d3af9f64de9b8dccc0716b3789ce3cd54d0045e21db6a37a669819553c8da8833a4f09d2f0e799722f51d73274d179e51aed39877089bd20aeecf7311cd35ac7d1fc0cd24242f5e91dd1200ee755948c3c731d0b3b2f691c31ec9e52c5d3194b8f849dd25fcb2bf9e068c6e4ca0ee3d862608f61a70c67feedfcd21fd765fc44075c293e227a9aad8709af3f2bf79a4a8f582432e30c24a09431173927cccfc9b00e9975168389d3cd4c499f68ba9debcc6c389ade06f5c41688a7d0fc8c9ebba8018fec36d1c9a8f14b562a27ce25f5afbc70d6f483ff417dc4a4d59b6c4ca60f5be8cf03db3fd2437f04d48043b22ca2163b383b625d6117923c6d39f6149fe92819b99ef242599ae3bd6269cbefc4099bfe9602d3d053d258237a4589e3a71eb89fe721ed5fc321f90c0f39c647227c085127fa399c47329578683b7eee335f36749b37aa675b35e7d4f62b19f7c92cbc805f577dba87d631f01bd15b3ce3a87ed751fc3ea3f86ef517cfadccf13ef8c8dfad8fcc2d1b939ccf18df9bfe07f1ef66c886d43d5acd32ab4c1208caa8d35e663f36ea7e138d36564d81337c4efd714dada60c66536b8db86779d06a1b7c2467b48fdecbf405934eb2108c46c44d6532e42b89e46d14287f043e045d59075afaa5ed27d9929798fa4809b9e3747ef41e4635229a1d988e3a362b6df091a991cf638ebfd818339abfbab51efc1ed397641258ee819e48d7dc05b1b9aea356b8a3de197a08e2b2152f255fcb1dce6b9f0a70e167b31bf2bf346af089284dbdeab8ab2ba7db01f548ad668b7bba3f6aadec55c6f97bf511931699d7d87926568c4fd00ae43b862e92567467207507cf3897f132dc2592b3870a074d608df4092f57cbca71b5da7fc73f228d311a2163a37af238676051de4bdd46b53bb39060d4b373148fa6f1b31c838f6cc3430c5d26c0c57a0c71abe47d61290f72fd8cb1cdb8dee77c44de0fba5dceb8470c0fd131d6a7a423ea6a6d175ea8f331bfd0fce4997e03dc67b947a543715bd34114f7662fedefd64722b6728b87449bd85066da26a5ed5f780b4763fa81de7572dd945e6dac21131695c44711edd5e86f57540324931f2486a3cc1562bf60f3ca5c6bbf40d4b6b52d8f0cfb4ffe9807c26c498fcabd4c81aa8422661971021deccce3cccde2b596ec22c2c66975118da8eb146e63cbb231474a95001f992cccb5aa8e8279216c9486b37c6ce7b8664926c22b9bc11ca4acf7119c5d3aaf734ca617a3d7f62bf349cf09f33b52ac23e6fbbf2031a1ee14906633bfa66fd507cd4b161a778cf43e5d37b8bbca5c81a22d8789ce3b706fd4f7d5fbc46dbaa87847be3cf027ce4ce36cfda78f98b468132fb1e99c60c29af766bb3c72a4a59a3256499c7fc1bf26ab2c22fc809b8bd599b9f5a275dc4ddeb0edfb99581e19a28b520b16ba4046491c997bc22906b664a2c1fc0bf5bd5ec80f312f6ce717319b44e0a35a28aed331bac25f3c923e6b6cfbb3fb5bbdfb60aee433e79883b66bfa6ed46834e37fc11fea40007f217d2fa39e9d61db95e62fa2c360ee5019f48eb0f0338f466de19431b7df8d3f60bfe7dfab8fd8727f141f58ec3026bf014d2bf23584d7f8007f87a2d59541bf2c1e35f161dfafcbefc3c7102914d6595458c3caad65029f7c54575a7f8f28cf9b1a3a13be3b203f4ea54374103e99d4c8592415bf025658d785ac5e9feb77d1b8244ed19ff79cfae9f20e39e49a0f3e0b36ccc7bc44dbca4ad821ea7d9f08a581f0ac88b7f419eb4bd763c906745f8f63a2ef24ac9882a88d4b6c55922b7212f04bc2e7273d92e2743daa115251ef58ed38eee8977f9451cf6fbd388b96e87cea37a88f9bec977b4039d291fae0313ef7cd633fcba1c1c3e2622136afafffabfa88499feac6e76d7303b6f19d7894bfb06c84f536827a8b563d0c9d69540869b5ae137e46f43ec09c159da210d30fc9db8b7b874dbccfe499122f253c959f01f91cfc0c3c4eef608ee10aea81b03e63f391f76c98ff1fe8288267f516f2aa35ba8ce7d67e73ec6dbe6adbb4d43d331c2f9c415ea4637d7fc1185e45aa8b997931c604dfdb3e2b390a66a37cbf8bb5638f45d5ba4e5f1bf091ef6fe24baff251e2a7dcafde3b79c6fbfeae73bdca8a2d87f329ae65e584f2bba0514b9e869ceb1ef8a0f7820fe2b21f1a3e04a2a5af8caf32774cbfcde7fdb76956d8aa5aaf129ff28d532ccf6a495d01416a95d878bb7136ad7b8a5bc335a8be4d98c29ceb584705674597616fba31e21984dfcd99af7fa559b1d38b7b6791812ef29629650e38730a3a89ea43e6703643761c223a813c01fcafcc91fa4ef1d9aaa64ac46bba6ea31cd80749f7046ec12c83c822c2bc91e71703de77e0cc3876c235fbb375bbe1f988aecf9fe023ad6fba37e8d709e34939a14d47ea0c9a476d793d655a8d95f64231ada8671bd8b6848e0876b9498f0a46fb42bf47ae75ee9430826129969a52c20b237e9ef3101b45e77500d78a637303448963b20e683de4cce8b74557279ff1916d9b41f7c1b7106bac7dfb40b7635e832a759953aa26a479a3e2252344df4ca8de6106bef673fafdc2e655199a071dc79d339e578ae9435cbffe643e74db0b1ff1784fdee8f6a8f7ea4d4083bfca475c455f5c6073f4f3acf132fe94f010bb61874ccbe4770f2a3aa8d597b9e877bbc78a9ec12af9c0f4a810e97fc83714cd4a384ee86bfe3d7a35d375ae6e942e206381fb43abbf7c9fa112b3ee27c76c69c9f03a7c27b3e19cbad5693641b439ebf3b5a80e77972d23beaaaa768df64ddcf0bbc4cdc757e778ce6343f75a3487fe385b517c62de9d25105139251f4b2f4116048dd9029b9bdadd6db55bb2d5ea45b656f5ebaf3507fe96cc63b69e6d50ec173e5793ea9867bd3307bd0736302543f8fe98f9fb4ce305df713f3c5e5be15afbb8d9f321f37c13f09104efa16f3c6a3d04f25eff1beeafeedb50ab63029c11c5b197736ad0cc91eb373ce3e3234959d372b6996df1f903da31ab5ab6bd442df0ece8708cd588d8a631e757005b12f4b6c5ef015c41dff8fc87fdce76f83eea39d92ed51c1e6327abd5b5ba23dc14f41b4769780734bc278e59b5f2b26a4cb3eff42e389f1d507d3060f22b461419ffc9d36ee7233be4fbf87494f365f40d590ce78d87049ea5c6b876961d57a03bddd198f7cbc8ec45a465a59e9d8c0eb353bf27f3999d118fcb222602c8a7e0856a8cb20b3a6a3c1735fed965f4b9724cfcfa8df76885f3b1febde623b277beab613f42ae3cd0f4a6b5f6dd57efafeedd386a4fe7392fa8590bdb8e641ce9ca0685308e56fbb42b74d4e70fe8fc027478d5d5a8058d97f614354f90afa26df4738dd315d2fc03876d5706adda762c6c3e72cbf91a4afeaecd076d68b9bd838a17f04287a42f34bc93f0c7808fa855363c244c32d067d069d88c6a97ea9e8842a4da8cb68e143f1f7f3abf26ed453ba39887fa05d0b713b344d59995678e9b594ddfc63e6560c15734bd4f775ba99ad3cad486d9547990159bd214f988b00a4f53f0ed77949e9228f8b3eacba00ddc7b60e234a0c7488ea9c9a3e378c747fdcff071ca983d37d1ebf6a88f484b7cc33dd3c4b12131bd5b5823c87b086c5825d657586f11bd44e4ff6c86f412e47da046baae197e4ebef8005fc5d683b6b59bd832728169afa927a863b344fe1ae821bdc3757d4a620544af42ae5f4fd151d4451c5ed17559c4af15d9e760dd7fadbfbb9c0fb9f719e924f3348de7fbaddf9b3cd079f097e63de104675dc24deba871c82a0a97cd877e92d90dfd3e0b4bf239fd6eaeee9f55bb3e5ba0d88820f6ecabfdb6e7635d1fb1633d777dcc39a1dffa86eb8f48ada9cc0eee3f0726971afd16cbb9412cac17d40d0ca20639666bc0689e22ef8b1f426afa968fb2373ef48382e3766fa66f29b56b925746ce89d93eebdfba5d7fa17df16247b933304096149d018b6dd86fa3b6d49b17c47dc1af032b716b5af1da88a057bc278b28c6fbb9932868ecfc22db868afa7992e761cfc797c7df7837fd0eec2b7a9ebe205e387b0b7f7b2297e8eb671713a7ad45b3e257d456d091a8b5c93495bdcbdea7b3555fe918646f4b65bdec43d65b5df9e3446eda6f1c977bc30cc527d49085966ba616afcea2bb74c88735b5fa239fb7991fdbae958abecf5f10afb50b3aa0560850a8d77cd3864d2812737bc15186669c93156bab7750896c33f8434df40097f04ffb6ce7c1c4c51c3c137e15a446c91ff1a56a0efb7960e105cfccaa3e77eaa1cd4b7f5fa49cff203e2a673ddbe67dbbb26bd963c2f82bd927c288c16e101ea36b58aad55e61de9c3ef67b1d45e12666cc9c110f5c57bac9ac4cf8c4908c75c508252da7cd3951bfeffffae2bc54adcfa17fe4fb7decaeb12fab5bf94c7fe7587016994a3701ec0f2d6d4450dbe2f1a8869263ce79173a3750bee798db408f392404e8e4a473dd0cfdfb519cdfcffa19177bb6213e087825bd27b6e40a968ae11fd128d76a970caad9e72c70ac9ea88f3a36ed1eb5db8125a331afc82e17ff7cc1a209fd237f3afe769c178d8df623a11fc06f863daba6decb1f42aff374ad138d79a2aead749d5fb5b3ca59efda71abc002c66e2ae89c46f2bbdf386ef665d5eedcf9e3c615538357a222d9d7c4bc3657e78ffabf9cbbcac9242eee6c1bdfbb391fd638fd10deef269af6a72d47ba837f69f8a44d1e1113af151b0f1587afcb988ac0bdcdbe71cea3195fb66d3c575c33630ef83df07f0b5a7b8f56bfcebcb26a0d4b6e481658bacfb49b468cd535bba23cf2c0a790def06ce9db36f923bfcb47ccbc12d5dedbd983ac5af9038e4f90da31121f57e994b38db2818702be20710e8269af7e9f547df51bc6783864bfab0ffd5ef6484967c75e887793f2b69b1b737eec1810ddf612af65f3119bb67ef5fe9ece512f22b6b67760ee10c9cd5bafeba7d1df6cccf652fc758810d4d5c91c4270e3fa26eb3992dbf39078ba253c57bdcffb9553ecbef8b7e4338ff64feab6674f54638b83aeb98bcf4a7a999f4cdf10371591b5ed67c7cdc7578f26cd36e3a015cf182b9d2baba858f622e1573b895b8de7bf7474ed43c54716ce3df33dc159cbb16fe48175a897f24023e2ad329de66dc583de098ad885c7f2b93eaa4d8055a0780fe29ad77057b69a9fbf898fd4bdddf211894bbd209bc71a8a82c439597c24825b65238a5ab5a7a4d62c625413b6df769bd8d44d7cc4967fe57f648279d178b2080f618b7015769e4bc67ce4fc45ec1ec4adadc5226f1af3bab79b39f8e83c6220e0af425f6b8499827cc600070d630a3b15e703e918613366ee21ac09807869fc41b2ce94282eac8ddc98672b67f17778c9bfaf8f300d731d37d13db556ff5b68b332e579f091489e86cd438c7ae454edb9e2a1f6794f6288f0cc03a6777fa68fcc2274cba4f779c7ad4d81956ff2bab07fe02ddacfa36b0aba3e7426b74c3b04b9fb6ea5dcd37cc47336c5ccaef3915df290100b20c033436e885b7566d57bf094fa22f3bc6abb3a07d1adbb8dc6b9db745b6edbedd47a4e7199ccd6870e61b7e878e194c619283a2fd0d5eaa9d1aff14d323db81da931e9e4d57dba9c452c3cc7e623dbce4f8a6dae3fc747e4ffd8d8caafdd5bd318ac945e983b1244309af5c6df8c78ad0b2326f8d1c0a9f2a2bf973c14c43fa1ee6f8001b20bdabb2127d3edabf64e96dd35bd49f01c5f48fac37bc096e50ebcc0ff335c1afd3363cfe278499c6d6d577cc4fc5e748b02e58b061829aa7feeb0d2d0f85a29f2eb747b5e88b1c2b6b9c0d793a2ead9ee283cb754e3e26a6474efcff411e963ac8d6f2ffe119b6ed936e8dc17ef8f1a7a9a7e287aa2ebf25a1821817f21c4561f9e19fe07337ffc9e7788601fbe51dd0e48369d5fb524b01fb56fd7c410fe5dff4846fa6dc9bf920bcf7ef7ee9be4531a7a9399ef8ea343f889b32b97aa7bde137aa93be57ccabc81976bf7973e57bf3cfe1927ea8f90fb890f2cc5f45d78d892f251ca0bce6f5f3a0b7748d85cddae3fabcd027c469d9782fac9f07fe975f3aa6d7545e752e927397dfd223dae2f56f944c59df16f72464b6fd97fb1f1997e3b3eff17f84776757fb5eaa72fc8800d7902a4a47e4cfe88f090585caa18fd05bf73e7de6e6b869bf9d3f63d1953a57d1e2339c6f87fc03bdc05bd07f2f7e18fa04aac5e7c3d4133ff6517fac8b673643ec71c4bd14984df18b88df556390b9cc9e9947fcb3cdc5d1af73563b04d5c813f9d8f753ef2fdfa48485b7e075f6bdba3a76965116fd47e4d7781dd889852ac1e77b5d93fb275de38f2334aad828edd7a60dff5b63613db7f1095df858fb8119ae7211fbc9b685d99b50837e7b343ba6c2cdd64d9e1dc11e005df301f79d67e88a2a2bd2d57af285d276411d8e4a6413ecff7cebb39df266dcfd0fb3a35d431738a15485959ae05537016f5c3e5e37cea14dfeb9dcbe1d8a7586bc53b600168649d993f34c633ce96b5adbefbf7e7b3ef8a2e2bdad9ef52541ffc22b1f9ec25c33f525a6fc1ef0dfd05f15b880fd2f9e9362dfcca98d8f6f874f82e33a020f9466ee186a6f5ab1b450dd264d3c2e7aef009f1419c517e466d62f45b9eb52bffc857c641f23d61db3aa1237cf4ed09e597a0924695e3b70403d3cda0a29d17ad1960fa84be321feb7c641f3cc4dcab9b68eb9f1e53864f56ad0e17f81a39f69dc7e5839b7c246697d83e7ad88f5c1718c3865c8d77996f89d911c7334d7d44f0ee83715112c6312152e8a8934f781d76fcfb7d73d19a7841c463fd387886eb622ca0d5e747358da39f336c3fd31dfa47b67dffa83e44e309abed9de3d6b0faaf563769d493bc74afdb45c2c007d2d272e4507ec899b368568124d8b91b25992786b6b428affa5d19e7e7f2d9f7a18ff0ffb097b805da2541ac6c4c3e7b8826647c6f1fd972dcfbc5b88ec2af4c5af5a734d8967f2dfed463bde9231e12485b979c15c0b997a941782ff03fe497b88a0e37c41e9733faff19deef77af0b7936d74549295dca55e3ed2a3ee2726d60bc17fe7718771eef94e638b08e6d63b4df655b9ef26feb231927e44b39a7582f396eab4015aae1d388f292187de4de3a9ab4fa9122e95df881cffcb1c6880af587108beb2bfac84a9fa77b6a4c4a2515f9443fd7305d628e5a1a7b619bd635495a33baff227598b972d58e1f43377ba89c683afc6ae83ff31df947b69dff4c4c7b55ad46b83689a1fbd87e025f9c3d0a4e9a605b767e75ae5df5ddbca1c6a64eb1d17dd8b2e6fc3eb66ded7778c9ff863e82e6b1cdfc8272d351a3bc6fd3625b1fc1b9a7f8b82e91f75b8c798e7b0798b542a3fe9406dbf2afc19b10cf54166c932df888f873504d0d357375de0be35ac1a73d3ca61a523a46c0c60fdb873eb229ef869bf8d0578efbdc7927ea00de01fd4a5799636ccb3eaac72a0914f9a2f8dcbc25c97a2dd6c1d6effe643ea27ce4ffba3e92e5fc01dc53e38b00270bd1d76e71d9617fc947fac8a31d5b1bdd51ddd3f640e3d6e6743eb5590f2bd42376a58f68daa7a422442a16ad78ad8d47c2d5d2117ed7fd47f7057a92e2790f949584e847f0191d6b9675421d809e97f8b6f9b6f50f9b8fc8fb02b7d17766ee6b37051c159db5c05553096793e647c761ab559c4eb96fba0a1e223fcfd2e5d68313ea87612d99a8adf03f7d24ae71ae9a5bfa5c1f89d45167db166647cbf76ab6122b6fbd46c92ef511532ec77d9f2997705bcc78f41748df8b33aaefa57dd8afc48f705e6bf64d2f5a7b446c5b4f5f7887afac05f169708d46a0c9428faa705d7bbb663de2d1b47e891de487d82ffe01c7a7e5ac67fc2e2ff9b7f511933e1d18fc448d4ef362d92a9f7ca48f6cb069315615ceb907e55e50274b9e65dae03fe389bfeb1f51f4b0fdeabfea4a719b70b5acfa23a0a98da253740f518f50cdec0beeafa413c63df67ff959f7886bd51a7dd6388ddfad8fd8fe9014e7449e39b3660eb8ff6a77e45b05f718b995a4176287e85df2e8df9a989315a9d51b447656bca5d213db41053fc39f4fe3bc88ccd5ffb63e62c7cea25d9056b7b57f84b5747d7c269a063ce096600d4afda63ff5e5dafdb5f347e47ecf843e8ae8ef4f717fb9efef4a4e0f560a631a8236030b11abaa65faa2f7ad8fd8efcd3924c8515fa25a7599f4284dcd9ebda00e7180812fd804e7eb3c063106a92b9219024c619387fc4e0ec9bfab8f08a6de2b1f8536237e4bc9a6dd974ff411d31fc21183b01521a210928aaba322f89e1ed3a53963a5d8b6943fd14732d6ef804938571aac2ff5143fe625c86f41de8cae52f04cef9ff451933173d5e3ace471ce1f374e0dff8ec8ddf33dea2399e0fddce989e3baa76e71ac28106ab94f8e29eb18e31ee4849648c2ea1b7e2c1d775032e6eb8d28d952ddd33d631f5954dfdaaebefbbfaf8fc4c5b3b25c9f2a7cae8f04fc43eaa31f52be34ea082ee03f105fae8909181707f53bcd967f4dfdc6a3d8d8f7c616fa086335f62f39bf0ff7e0dcbd296bb6a34bc67689ab1bb24fff88cc0ff0fd536473838517fa45e7c49817838f5095552fc06f0e6221e433f052506de9867cf36b6be03f7d2467b4687cb1d64760050536f9a7f15a467d7444762076b655e8dfb7d4b58ce7a171d1959c1fcab9730363fe2bfa88e92316591abad408b9889fd71f1129e41d517fcf0ec51d3c386ed72d0ffc1cf9113a3a2a9df511799ec9d7bf7bdee5bdf859ee7962914cb3ff0abe0f919e1c89c11649cbbfa55d52abea9d125007fa9df60ddd9394863a98a3b1c1477e27aeeedfd747e26805e8c205d1aa4ffd236f5e18430b6b2fec2c52afd7ac8928b8bfa69f7a57fe1193ce624523e7714b7d04ef83b8a6a07e0ae7f0019f1d3c7188efccfc49539fda873e62f178d8a1908b831d52ab729c00ef927625baf38379c2ce79e27ca0378ac513bf092cdbb8befdee45716bfed3476c7997e28fe8dc0be528241805c8d64702dc78eb3cbc52493573ae46a4d1f4b8a835e01b43960f7de2a1cffa2bfa88c41be5023ea8e3c01aa7992bf803627987f1193b64e1ad8eda23e613afea5a17f7ada792a0af47f586ae494fb53dc2da9339633ef631ff86ad69de280f3a29aa0a81958ff9181cdb39978c85263ce691b06a82df3d528c81447d425e40d5711d4b20e3fe3bbef67f5b1f3179099e05ba9923f954631e5a762b9d3f724047b1bbe33bf8e4878a36e9b8a038fa13476f7719af65de4bad8624accf82b3f5e405182d1541b6f06887b817949bb7c6ef142faa2dd95f62c41447fab1affc11f31d117ff518f284a0b6704cfc9cde45bc73345a600c768dde290e61567666d6b37e878fd8328e9619fe097d242a5f8718b0cfce625c37d0e6c4a77e4fe8d2fafc93926b79c435d646a9f91cf8d4cd5cb5aff6ef33f9375a339d72f72ecabdfe15ef88a7505f82dfa67c49ef31440dc5b7d5d1424b7f1a6b8478e9ab3fd6fa538af2c0b90f8b4037907eed025febb36348cbc5a6e6d64ba97c73caabdbc01788f0f6c770bef44e30eac5c4c5726397745f17b544819ff5ea8476ad4db1c7618e66888b62d92aff117d248e97a4c896d3b63d854ca3ccfa23e32ac9c5dd21d5fff892dfe377c6a46ef4dbe6231ef96546092f5adfdda8cd8b2a37e07d885cd1bcc2acbbf5ea45eba4d8788de67cec2b5e4b9e8de8ff25c591e9fc97ebf01820249dd16713057c936f48ff9eadf53ddf7896f9eccfe6e2dfd647e4dea6dcabe5eecee5ace605bee8d0f354f1c4ae85363f22090c79e1ee65e544c9ee517bfe2edefb237dc4a46538deb0fd2c4d96035df3a96e68ae1ca38c1d32eb79939cd3bead971cf25f670d5b5b4adf2bc4f80d63a3d7e7e3bbe79d9ecbbc52adbc3baa182a3e73c1cd948a75828ea473f44dcc1ab1411abb446a276bf9e0dc59d40f780ca61b7888bdfe8487cb7c98fd9e3b8b7f501f91868ace6a16de575ed46f6b5a4c2f429a8511465476e0538fa3b9bb6ca63e62d359f9fe9978046c36366e98ae3baffa9fbae738e185b7ce2b74748617e67ca7bca8dd47e6631ffa8869db82dded9c6d8ecf848f1f8973f0580a3b33ea429afcc30bf5333b9eab6adb1b7f175f6b4d2ffca7f4919c611757e706e5fe7d2b6bd42d37685180af75ef05d8f2bdc5f8265130f2da4c1de13bf591d0176cd44ed7582fb3e989e213098e123f8cee12e8537ebdf7043f0ae5b27814a725b570a96e6e584737c5bc66dffa4894e733afa4f805d4a3d73cfe5d7881d20f5fbca04e4cf745bc8a060e9ae82166acf6a37f0bed7ed6e925344f7d0d702add98715fef5734ee21e4bb773fc247be531f319fa3e847b2cef5482c395673f233d6d26f49cacaf9ee73aeecadc7f77e178db5f511fb99ac17c1df9eab90fe14d871cea9ffb92ac529e95a1d292f8a8f6bf22bb9b7f9bf391ffbf28f98ff3f938fc4f49deb0a431764cbd398fd77142fa7d15acf42bdccae0520d837d85543aea7f847f3578be9efbfa18f84be54c32ee44d9aeef2b16bacac00978ae55f1dfba3f8484e8d4caedecbe41a0ee532d834fdab3c6f1b7d24d4a75ca92dab3fabfecc1ba31bf8fd358d7d23c90499b9fd9b6675a9add4e039de2488e9255f3ad1c267a3b6498a6397f7ad8f649ce83890bd6dd67ae839dd9a17d6393ea29880de7dc5eb1ff9e3f7e2e0763eed0fa639ff28c77a99d4b08c48676cfdc5795d01c3ce97b779c8a6f9583a89006bd8e025ff983e62d160f8a93b134bd67da3ea36429b746dd7ae1af52b2fea53ff4e1e22f4bdeaadc710dbcfe5cc5d8901061236fe06238e4fb2f946ccf59fcec7bee37e313f67403822dc01cd23de28f61775787b8c2fa6e3e49e292726d7422e65b6895d02fb5580c3cc1218e2bd1609e2bb1b799834d3ce277371c635860b9ec583fe297d44e83ee590b8ab9ee3fa81cddda8057540d535736d8a5c443460aee3b8e585c6748ae61fc4c4ef7c833eb24e73c3fcc4595bc9d653b59a4073735d3f9b7e7366bdeef42d072caa0cd795cd84bf0f9e638fb34d43f7a58fc8fb0bbf7c205e594b273a03c79bacd42e1f9cd7cf5b8aff0309dc45e5bdc700ab51eb6bcde1aa9df995ebe7de590fbb09299fced57c01d57016c92b7ec69d919b6abf7f8a632772cea22675be701ef529cfd6b16efe417d24c3f9d18afee406965fe12dc4fb5da088d890ec20c3b2119bb50f1e22cfb0f3d9e3fe4f11fe6ded063b99f40fb420c6d7eeeb36fddeb73e22cde269b911d571472d4b603106f10d76cc849aafb4a26a5db54372639692bdd006066d7de13396a3e0fddab93246d3eb43edaa1ce344a301735ed7503eb17fff8fe92342ff35b608326cfd0bd3274bda3ab8726e0a8d30371b76298aa30a9ca613aa8711a1c5bbeadf67fa88795e9e2f7c21a5e99dae6fa577067040607b2b10b67af0dbe907cf33e5f19fd447f0fc2ccf91a2d958d5f0f466150faf69d43ccd3f8a814e059900317359f5ee4ff5457bb83aeafe2209193112e29747fd329dc5807191dc1e53b688be3fe2f0502f3299a3dfbbba7664ba7a077b5ba49ee2bfa78f1874b5c5f13b9a137ba1dc0a4e8d6c1e2db92c58a63fa1a6e98b1dcff45d3ef74df9ec71b4ef818f268d145c5cef8331dfc41ff6ad8fd8be8a9217c404e85d7f66bc5b4c5e3ae605fe1ffc76a6f8480e3efa8710a312b114b995757d5cec82b4173afac3c47dfd857518257754efe2e6fb9fd047e47e62db56f427d15fb573498e6b327cb33aef1b517e8a76e5d408642eb5fc099a463ee91b431edd959cfe793e7b48efe6fc7f385eb320b72ec77ef46b67a6eb35a53486fac2e01d8233b508c62263f5e327f411b30f78fe0bf311ec8a39e98039c2472972bfc9fec6b92eed16d52f211d862a5a03a1afcf3829e315b2192ad7ad14df57c623942b22362d8d48eb117e7df5b93ecd659c62eda6f5aa74986aa40e16cfdb3fa28fa4d79f05ac586dd3923a828f64e91da8e7232a7baef847aac7f4ccf4437b1beefb1d6362e3fd7ec4031eaccf422f4f365cb72d1ff96e7dc4ec47cc3cc97b04d86585e8f9604e72e1717ac178c86a4cdad02bb21cafa63e277defe3bc918cf11c60402a6a39468d328cc393d54fddf77f421f11fa2434589d4b0cfa83729d6d5986e5b7a334c3f7b7f203b4bf453fa8ed4af43927ba8c4187b6c961fbaa3e62f29118fbbcbe3e1b609ad0779e81f115de5778d13a1ff9597dc4cc2f9f39e203ba09f8c522877c97824375800b016e3c5d23c71ce33a2b9e8f7a243d64528fca0354481da1424f100fe684b10ba6adcf9c07fcf64e3d57edb877c4c30d9d59d775ba465e4dc087fe217dc47a564b4954a850dc3f0f7dea65458772c01a872f5664e07dfa06ccf651fd914de73e3a1ff7dddfa68f989ffff499a28f315e41fd80751abb4ea5c9471e8ce7caefb84e7cb54cf57e35a67e22aedfff843e62d34e4563d323ff7501db4789f1a7a0d55d39ee60dcb8a8979cc5a4ca7159991df7e34ff4915df3d48ffaf153fac84747d5ca73f6876ce2c1260f446d441cef9cae3baa8f12d3c9236abfb3cee2aefdfe81f349b35e80ac048c824ebbdece5dafda9d337f5cbd57bfbbd5f3b1165bf18fe923429f148dce15c20a378809d5987e152f94553fb09fefa5d9fe917d3fdb9c8f9f1a832f34e81435a53f34d4dcb6525e68ebb3df53f48f07b28da1417799abb590030af76db816b47f646d2cfe097d241aafe522f6d59ffae34a92f3a1b90e49a294fbd5d33bc499e56e8d9a7bfb78ef4d3c7553fcd0f78d7ffc7cfc140fe163c04736f16033275474b14367b1b8f326cd42eeae8add21ba5c78bd81b7e68f1db6a575d4ceea29ca99bbaf8e3a4567d1043ef454eb3f4dad27e1fa69f8dc7f441f11de207ce4816a76b72fc2ac9db6fadd08f4c4f6a3fe0dfac8bedb4fc66beda219b50f1bb04d9e1975776dbd44d64421f4b134d47a484f152f01e6d8b3715dec7cfc13fa888da1f4ea2c205fa6ea946105df7af250697737ce42db3f941ea2f5911b87f8c83ede7b134ffd4f1f89f2918f787024de8a63ac4e1de8118a0750be8d3fa4638467aa63a54b7e91eeb259ccc172f35099e51e956c01ec8202f39a17e7d1096d83c1f3ff317d841be845b247b1b2e021d821c3438eed35f3f1ecbeedb3fda78ffc597fa5f1fc21ce2a32a7361f91f35cab17b98fb907b21c4bad48e135895f71cffa27f4918c139557e74e32f7d4b9ae5f867986c977606639ae3f6479151c9a7098fed3477e9287f0f1537d24daff20c6c01fb28d8b7eafe3b002bf888cabae214c3ba476e6cf66955ad2d799cd0ec52be4187bac60f0d469f8dc7f401f89c997489cf4968b4418a785789e865993dca043ffe9233f3806fb784fd3c78f3570e105751523fef8b8f9f897fc23141f3a15ffacd24366e9a4e03322a36afcd8eb346a4c2fd435938a41b7f6f1de9b78ea7ffa48948f7cc4836d3d23ee7cf4fb68ac0263346bccca2856251d250fd1cc47cafd13fa884d2bd284279be6a86920cba03e928eed34ede73fcd47fed347f6f39e968cb1969f62feb61c374eff843ef2ca7c84730650c7a93f55bbe48122a7c7adee0cd56a225853d0474c3ffb77bff7269efa9f3e12e523dbf2e06ddf338a8d12d6434ec7fcfe96f9483a7addbfa98fe85ce9996a8a77248a542f49cb9f8ca71eb17ffca78ffcdfe623196f7d0d7cb446ecd86333fef8df8ed74a87adbc70dcc6d1f83507741a441d289ed275f1c69cb7b75274a417f847f6f3de9b78ea7ffa48948f6ce209f67a89d33be2de378c050fe3b0e439d3e03bfa0c7d24b5fe9c7f401f316983d085176f929d7b93e6ab3769e57b4bf8dcd7f2d20adee7f4e7bbc7e43f7de4cffbfd3bbffbe8b3996f538b39f76fe823c29784a6bceae32251cd15732fd3d79cfa9cea391a1b70a35d6bdfb473dffac8265a3cfd0d7d64d338c5db9462797c6c9b1bf31167a3dad696b5e977c21b24363cc4f334df6b1def97afdf131f31f7a68d05b24b1a26f7132c8d7eee2d575a9647ea9999f9e830a8c361d6a1dad7bbdb72f3c6f8a03df4c33cf727fac8363a80d9d29fb4b87512778f5daf45f37f733e22efb7177d84ec0982bf5a8dd0a45dd170eb5e95aef6a92f9c436fb2b8f7c783e9f4a576ee4da627d4974935a02fdf1faf15f7ae391e8b9b6f7eaecd4332d67ccc793e3e93ff3f6ae94faecb399ff111b79675a44e58886b66df3fee39dbb68fd7e7fa7c18ed07f848c23ab72b3e62ee7dd8ae047391f349847f44b04ff0ddeb8e9eff27b4775ffac8261a5cf0d66d399fd1dd8fee6f1fbf3a3e9fdd3f0e2739ae6ddb071b5f20aa8f7c6713ba40b42161d0ce306f7b17cf90fb119ec6c2996247705e34e151cd025ae5732ef5ae9ebf5dff84362d1cc2fe48e87eeee3f9664bb15c4e7439b1c535ae930bc6c9b53e7f7eadd895e0c33a303e1b3c23f18be72615fbaced9eb1f9f8f9dc6434ae6342c76ad0b9c056b6473e2234bd669cfb2e3e62da25848720be53fcecc23b3ec2a7da65db44d7f6a58fc4f90784cfc6e98776cbc5b46de9b6f06af3fb57eb9cdcd3fbe4de329771facc2ef84822e65ec4473eb211ece29873423e329dd4024c41913977f11c537e159ca502d3cbb937d1f8afb06b31fd1ab9ba0f6e70ed77beff7aff088f65ea3c46e283be729c7ff27d38ce8b00434cb798f9b05bc87336dbe0ccdfcaefa7ceba7fc2e6216c5fd2f391fa603ee2d689f8cb53cefa18c7f57fd311bf09e76311b94f68d7aa334dfba6a38ecbc767c543b21d3a7ef7f3c66ffc19b4019127496f32c93236782d7780dfe9fce5c4f7bfbf7d1cb9f45c3d16fb787e2d7ad4cf97cfc8c52b73b37ee70cb995ad368cbfefda519eff44c7dca1f159dd6752e5cfe5d1a1be6f8fc7e3b3fbd6a2f7ddf8dc9dcc47c047beb3493dd71b4d337ee9bd3a75ecfa4a7fdad6ef930dce1166df52c779528dc4953aa23ec915d32d9386eeb369baa569f82ec661113b0ed2a64633e7e380e763a5c76511cc8b34397fcb2dee73f41a798ed9171d67abeb6931edc7ff89778d4d4271daf8fd95be1fd58eb1fbf13b2d1573fd67e317f0119e0f6b3dec511f9156dbf3f34406377118cdfab33fd9be4b1f11d95d3ec3ce2735dbf199f16ea1134c32c6351fe914e66f1eaccf252fd42f1e8c67caf566bd0f23177dad0e88cc8f3caf64dc4b9add17f319f67bffee1cc7cec75ef411910989c654bf4d1f91fbadd9c63dc2f04b132fc9a837af293ed238c20830c6ec3ef49175fa5edd993e62ea09e633d4e796faae76caf9dec0474f219b591db102b34e2b66ccc42624f741ec82db701db1c949bd5ed2f93cc64fd4bf57cfb171267306e662ced04b3cc12c718a895f6cd3421e21304c80095cd2f7c5ef8bfadc837e0737d2cf8cbe6611fc6fea34264fd86e7d561d5b2fdb1f1f31f7fb77d1ce8f9a4779cfbaf6ecb3e2f2854a6388aacd477f406b763926dfc5534dbf109f13ecf5488c81c7f361fe3e8e87487b357e2778569ef13b7e4e10cb20cfc26f042b1ebce0c50bf99ac9df6c9e224d303553deba5dcd7c5fab2fbb990fcd47be9b86466d1ee4cb34cfefeafe9b1ae53ecf5c20d31d7b9376d39ba4ef1d1788d8b913835e7ef7fbafdb7faa3b7b8e69634a05e7d9b6571e807fd450c1065538dfe9e800d5756ac41edb4deef76abc8760ecdf514e9fbebfde09541fa5a69ed938f526f512ea510287c699e54e9d59e59c7503d4b03ad07e2b578dbdb62d02b364f2c67d422b305fba56d7afd05ff5ff9d33ab3eaa6bcff89969ddbfa2e6451e788c8ee9e6cf06afd9767e36f191fdf947cc7dfd9df15a9b1ad7df1bbef496fd43aabbd7291a74edbb9fbf694cbe93a70aad9723ea442187e69c723257334fd3786dd3d914476563b7e33ec027bba07ba09e16723e751cdc05e1ceb4d52a5f287e93529f9b556a99153fff84efa1be6b1c7a411e8fc6eb4d7bd13c73ce3dc7fd076d45cdb836a27e96fc26e5ade3fd7fa4577d3417f67c04d7ee297fc4dcd7df1fafb54eb315ed5bcd50d76adc2244a1dcb9b6abcc02f9f67bdf3fae8571a6a92fdedfbe5ee20c966a8697541f0ab862ee69bd302bad8e926ffe78f15a3f71af501b2a51019d0606b234e796ae635a4df7d2fa1c300ea72fd54ee524f1d09bf51c7f3c2865ae528a2f2d2f3ad7ed66eea28dca487d6f922cf7d3be925c062fa8ff8b4a16ed66baa2aecf75ae474da73877da83fa75ee32a9eedd56fc67be6a36862ffe6c39ca5ce53afeec7da8cecd12d7d3c3cea59bf5c733c597f24ef57579df4dccd5ee9caa3e76516de94ae94935d5c7bce653517dc4aebff2f1fc84f361cdd51ef988eccbaaf1ffaef8c86736995ceea0adf491b6da2503458fbaf7444ff5f7a51d3cff77fb27ed9be2b5829834b467aac5b268d07b57d5731b8a6e27d4f9016ab068fdccd3345bd713b469b9e814fc1bf08e7c82eba6abfb75d4774bb51b3b2375ee95723fbbeabbd63b654a0367f9fd9e6a8a2dd54e4d28a92aa3fa9044ec1cf0aeb26a17299ee62bea95f7e9fbd6b56aea5cb94535ab50d955675eabf19aaabe0f81483a57f7549f07d78cb175eaadd79fdf767dd9f31199a7adf247c4bfba0b9aba8bfc914d74d98c199d925d5ed345c5fddfdbe01ffe6d7346d5def2657fd65d8acd24e67d455e35db2e789adc1f72ef92e3833e9297c5576de659cb3bce49c6877e01f91fefaa7d11f83c2cf7564e6252bb290fc66ac5fa07b4a2a58e208e7a45ab7bcf9d7e37a9f483b9e3bfce1dc76dcf6ac979da7151d7a3bb22bd42eb18cdf14d4fe90eef73e2c5bab6cb4b58331d3866bd0342fdd3750a0fa4a67178ae7c48b899a8af2e0d5593f215c2d49cab1d5551bca8a2ee39e8d2fd9a33d5df17f4bde26994f30455aaeea27a2a106b07b3d9cc4dccdab7f5c568599fe7abce0ce3c17acc624d5fcb396b3a4720e384e783f5c47c242efec53cc67d6fda2d64cf6dcaed33aed3bed6b8fb9af625d35e21f7f7bce8feb63f9bf691025502eda132a81ac9e1886850e5996676a4662c5f633bcf677d8e1b179b1f70ac518039cb36a0866bdd9beb6640feae2b1a39e11a1891e79a74fbcca0e7f85f72f1a51fa0e9eabd7ab754d7a9c7efdd519420df209a8c9a5d159f28435063f88d57af3adf2fabff517de2803e830780e6af147d7f573b093b2cdf54b43f4fbc02558ef47d9ed4fbded278e233ee27f7b78f664d6354bab08fe553e37afb7ef77cbd755eefb8537a2ff0aee12df1b486da612d5826d4580d212b9c5bebe9848f2f3c9e9e319ea28fc4f3915c402f176bb4739d9eba6cf3261f6681fdbc520f358cbd25db834993898f446331e999e135b2d7f52a7150636ac6b6787daf6a9f6df399a0feea4cff4f75cadd4caa72517eec5ce6d52a6c4e2b5e6b4e68a6ef638c3461c8f7665cc735cc5958ab9bb7b14569901be903f555eaf2119f52ef50eb693a3f6bab9db380c4703e9be5dbf94ef7bcdc7d7faf2fe66a6652a3cac9cae9e67be9faa2f3d09eceaae5c1fbb473d97cac9cf4c00be6f50534dd66c11f27c7ab76beed8f51b939afe86dbe47727f67b19c244f99221c50fd47da15525b385a63b87c34e8e1a8cf3f1a752351031d55d592cb650f3b51e918c363ba26a82ff91877dfdf3dd22e19bc1bf5c6fee03ea87ba9778d43bb1c481f8d5faadfefb383a6e2afd05d6a73e82fcc5fa06fa5746d7b93b75783dcc4104bc5e42326efb0f7529c0c67c66aa60c3a9ae1a3d8416c9adbdc702ff3c8f7d4368c336ea75e886772e685f69a94d10ffefc3e181dced5b37a6a16cbaf542514dc5eea790fd40aca5e311db16352ed7e65ac71896b621b337dc469ea3f6c3da0f1dd1b929ffb905ace8926bf9788d6a3c6ef44d1695f7db7043ed81dd1764813a0916dc5474625da052d753fac5afce1bd502318f23ef42cff9c7e8755a2df7360ae3aab79448b27237b758634ba794bf7c373c063b0434c5ea4af2b7df08c6d5ac9b86fc9baff96d7077d609ea36b961d53e571e84dbd5f34d618f756827977c15b5bcb938ab50f343fd77cc48e595a97f36db92d3c9fd27e56b69307f770f99cab6b9e9bf13ca5c9732487e0d571993785f56caf81efed8ff383c4ace3555f1bb97a01752260cbc8a895ee1e414e56fce4499d3b51d73d33bfb9a3d61cd54f06155a79ed34c9b77a87bcf9b7b51a8d647ee868fb4fd267ffb0f9bea12dcefde0fdc3ffb38ed4c470a5566c52ad64c8f3ab97f14d7e44abbefb4cab0d2bba7c8236e8a17f22ab3756520942d14648858ffeadac72fc062bc9ffc5ed9ade07bb9ef8a392e52f58967748121a0c6ad528ad8fd268fddca3c130e00dc24b9e154dbe0c6932faaaeff9c2ab50ee07fa7fbc035ea2ee337c64a9ebfccfaea75d22bc508dcb13c6407dd67da6f7812e8335911f67aef29384ef98f92924232422f202d779dfd2ae15679391f3c24fcc7d29745ee46a693837dcf00c432e6c29da9e6f931f630a4e3fed389922d9617a5da2cb3e6650ad8aae7afb461dab51ad16c5a312eabb8a4bb616d062ade5496d5d8ce833d974741fc1435e36bcdf261bd9a6ef3cae6da1fa38573c61a5e8ae7b473619d4636c4127b8a095a76d3d6a65778ea95fa8d98886ff753df937e6797ccccfe83aacc8619d6c46f939d1dcc14928b7bf8f425a2ad7f7cfc3dd61d368f42b8e8f681e7349fdd5dab868e86fc65176c857f9084b7d5fe2494655589115deb3a1be84392f4b5dcc73c65bb3f560531f8934f68face786a11d382606d1faf7a297202f43f18c1adb929a6a266a8abec22692af2626f5e3ca49f3b17eb2784d74eac7f5557e41951ed1dc73aa0101fb7d17b6fc1459223b1763b7a3becf2fc98601cb1f68311a248eda5b3fed1f38453feb67a16ff4b2f955efd871df1bf80eb85af383acda551dd040754c1e54bc60b5a8d5d6873f173cf0c0d03f4c39d46c531e0be133af4e14cf29ad7dc0b3761fb5c3d3dd91479a32e87df93ca4e19a462a391eab9acee5937ae59f100dd4c712fd7e70429fdb15ff96760ff51f3b032b33dc5554ef51ff7f4ff7c7fbd60ee9fcf034ca3b36eb23e1efaa59be97b92b1e896789beb22e69fdac3e621e032a23fdbea777d576bc553e35ba72dce60dfb7c0a2cdfcc9da89fddb071321ff98c86dae7cc3df84cbed099a2754b456f6655427d833e3050ab66f440bd835cdb9c926c08991a0d16495fcdc88c790378809b255b0af800e4c9f113bd2d6880b6b7b32d0335aa348d2e91f531387fce92cc19af4aa1a93ca3b036ae44d711fe67dbac3ee3a5396b1c8026a1ee0b1fbe7efe79947605f4edd15805f08aa5bd807780c6d70ee3e571b1e500bb18bf89ac268bfe6ae94c2417e703da6cea2371df3f7a6bfd2e9fc7dfe74b7ce4abfa88f4d51c0b93c7b10497b9e82df319d645326c737cb5e6f62d6e1f047e76d3266cfa09c42e6f606ec3f60c3b817b5e4f65faf542db4bccf36a65e7ddf762ab4b741e9638c8ded51cf550ece7e5c3c1102b19964669d048f17bd8667a6a97b46bfe512691cfe595c402db4ce549c9d5d8292c2743bed4e70fc8deae3ff3f7d0d6f477daca4b3424a081588dd07093fe71e7a6fababca01aed8901d93a8c1c87a8be61dada44767da66b14bf5c2c5ebb37d0c4810989f79c1db33cfcccb3f448bbbcd60c79048eb5c6682e2b582ad2c5d2e647ae33ffcc7a8a4133710deea7774f839ff564c8e936cd363e933e32f46c5a2cfd0b6d57f67de47b1ed79fd647827e84bb431a3e634d8c0bed615e51e54c8af3541eb44dcb357886bb2906c4f28f98f6f9e7b041c6467c4e0236168ff844fe9a6d2c25a69d6f7c3c229a8ed522766c99797cc668986f10d8c79907689b8c69cf37e9af671cef43da13274f4766d7b3eea3ee9f47dddd36d99adc2bf21f07ef1ce727326a82cb780c5fc85ea5dffbc0b2f39736f42d46c2b0edfe7147d34f10797fa1a3f2ac4796c34d199d9fb9511f89e9dbdae7b8f7b179e31fb62feb2396ff25721f354ec90449f55a07b5f55f23966062c6fd06f38f3d02db3d68e2a04c713dd527c7d5b130b9ca49329bb9eadd341bed666fba9ce46f206bf72e487ad2924f82f6e9fc8269f93dd3bc0db607ff9a69a749e3c426c13270b0ab3ea255b65cbc89d6c97dc546f448b60e78ceb42f173e5e25fd3516e96ee2b23f404c11ec67da8e3ea0463e6cf239b79c7a2a39aebeb612cd2a78e6f48e76b3f082d8d564cf3cbf63f97c4836fdf3e8f591e39b415befd78f7ec1a0f5a66d4776e19a6d6b5d1fd96e3cedf7326c485fe12116b5f8701e3f9adfe0685c2ffa93d3afb6eeba09e8baa95ef5ae71515f941fabafab4262965773ed2a89b4a63405a5a3741b4712ab10d42961bb563343b6a1740b9535158d54aba7a7686d2e4976fcde3dd999612f07cdd4d6d433da1d364d5ba3a146837c0c3e62fa6423ed31a409b1b4ec23fa65cbe506af0af412ee9f5ed53ef7234316e25197fc1379b5ea1b4aca6b252966b5b5245e01bb9a12962633f85d94fed07ba0880c6d5b3af6d67786c9f32c5e213c1634fcb7e56ffbbdbde8fb06beeb33de09b71bee63ea23969eb471a76fe2275f695fd547ccf567f058fddecc5331bfbd278a1b802f1e5139d08ff3f7142fd65414b3aac621c536afbc4747c42c38e7d8230da5455495bee1677bc7a91c623669b5688d986de3819c8ff6423e4d6d773ef7368fa0b93b5827f1af873ae646df4ff4085bae3469da8734ec031b8bf17bfddc42785eaf0cd87b947c3f3f227f84f63ab1b68f11852e857a8af0e2e958e13a35f16fe07ef30bff76766c3c3f8e863d867d90a3f00ebf309a073cc2fc7d1cadfd8006cb7bf50e3d6bdc797cd7c6f3637d2476bc3fdc413fac8fbc7996655a64071ecf22cd29641fc83db95a68eb42c37c4263984dfca37cc159f4677eb63f7366d574a33877441f014dd4deac63f2dbc2670b8f16ecedb0e36b1a78493615cda1cfd8ce7f465af087b4a6e405344bd3dcf7d08e2f7b7d4d76fe8c86f1c8c4ca9fe6bdc41e736ae93feca7c0f307bcca250a4ff348f60b68df7581c645dbca4ec3f78ee8099be8bdcdef2c7da2f2f0c1f55b501e737c3f1c0773bc8cfbafe923dbe879f6f73be0275fd54736c58999f162b26e4dff8e5c8f6a808843cb3f504cb4d846493fc61ea1f84dc86d6c5934f766408348eec48ec1eac0ce88ec8e8f6696ef45b69b418fbc52c65edf441b2c5a134bbb6cde12acd0284f32bd5de8c740bd67fe91fc0ada1ef4c636a37bbeef7dd8e49dc5eea4479bffafd56dfd28466f7ab48ec1f7f3927ec6672be323e967edf7162ffa607c491f11db5a8c7c1f370fa6dc6ff3ce3f3a7a5fd74762fb698cd53dcd6be037e1dfe9cf6c33a43886c1d0bf086524997fe2239af3f35ed6fca2492d79109d01b1e347f48688c6f8f14ce339c255833d1ec31b02fde129469e8eb36d99e7ed26b4dc7886c423e9880d5b5a8a93cd0daa1119e992419b6c3dea33ba68af8c8f7e6bdedf6ef6f98ffa6f5d1789d72a19f78b7b9ecd033f9aebdf69a51dc66b6dfafe39bcbf50765306d05e53752eff443243f47acd470cfa44fe5bf2f16235c867cd5f1ea3b451dbd137d99ce2e4eb12e9239b24a735f972d37db6a695cc430686ed855790d647021abee93e3caa4dbe5e6c381be4fb753dc1babf79d4ef1e43c3b7399ae3f2e4ad8fcb9a8d2afe3e14c3c4f31177ff381afdd9bcfcc97117fa88fdfe46bf484e083f4bd44f649dbd212661346f2fac3559123eb2339af0c97ec7de5d8d7ff3ba1dd8dfe36c60b13ee33d363c7f75e77d4c03bfb989bfea27c741e623b26a7f683e8696bc414df311fddf1769c14747e639e0a8b5fa7cf4edcffbf0482dffccff7fc283beeb081e5dbe9c97b45eb6c7f70e69ad7fab75aa839f9e0f3ae69f7ff0f9180fac878321c57158dfef918f987b754fcfdbd8fe44eedd71131afe23fdb8ff6f3eb69e0f2fe423dfd938ceaa14fa47227e95bd8d4425f48f8c423fc5be6723c8edbe1ccdc96fb38716d1fd581f3967ff489cad6c1b4bc2aec60373f0b0613ef6b43e3896b0277e2cf33cf1916de285be720c7a7116fa96bff3799f1dc9eac97e929fea87436361c6b5edeba8fd0585bf673e341244e1e7e7637816ce87f0b6b2f6b393ff5bfce0bb3f0a7dd0b91255ff0ade19f1717ee77337f607b9da79de25e7fb7fbef8fd25067aefef2ff37144f311998b1f9a0fcdd77f7a3e12341fbdc3e858b07f447cc7df75647f0476c732c5a3f19dcffbec28f15a092fcc0ddcf3f3311e188bfe0f3c5f68b6c6c19afce03cc8f184e7e3d08bc632ec713e300ff962cc7c9c628f0c0e47f3c1e1d0fbae63e561349f8c06c3c969f7b635c9bf4ce6fed5773e6fd3b1fb88e360382d776ff3afcdc5e474345fccf6df8fc121de1fe331ade48b83e1f73f6fd0c3f3c27118f4866743a4b6e9f9d8fffb478f988f6995e683fa89feeeeff96a6df62633c5432ae17c4c46f2fd60f8fffbfffedfffe7ff0f035432c6</data>
689 </image>
690</images>
691<connections>
692 <connection>
693 <sender>frmMap</sender>
694 <signal>signalTz(const QString &amp;, const QString &amp;)</signal>
695 <receiver>CityTimeBase</receiver>
696 <slot>slotNewTz(const QString &amp;, const QString &amp;)</slot>
697 </connection>
698 <connection>
699 <sender>cmdCity1</sender>
700 <signal>toggled(bool)</signal>
701 <receiver>cmdCity2</receiver>
702 <slot>setDisabled(bool)</slot>
703 </connection>
704 <connection>
705 <sender>cmdCity1</sender>
706 <signal>toggled(bool)</signal>
707 <receiver>cmdCity3</receiver>
708 <slot>setDisabled(bool)</slot>
709 </connection>
710 <connection>
711 <sender>cmdCity1</sender>
712 <signal>toggled(bool)</signal>
713 <receiver>cmdCity4</receiver>
714 <slot>setDisabled(bool)</slot>
715 </connection>
716 <connection>
717 <sender>cmdCity1</sender>
718 <signal>toggled(bool)</signal>
719 <receiver>cmdCity7</receiver>
720 <slot>setDisabled(bool)</slot>
721 </connection>
722 <connection>
723 <sender>cmdCity1</sender>
724 <signal>toggled(bool)</signal>
725 <receiver>cmdCity8</receiver>
726 <slot>setDisabled(bool)</slot>
727 </connection>
728 <connection>
729 <sender>cmdCity2</sender>
730 <signal>toggled(bool)</signal>
731 <receiver>cmdCity1</receiver>
732 <slot>setDisabled(bool)</slot>
733 </connection>
734 <connection>
735 <sender>cmdCity2</sender>
736 <signal>toggled(bool)</signal>
737 <receiver>cmdCity3</receiver>
738 <slot>setDisabled(bool)</slot>
739 </connection>
740 <connection>
741 <sender>cmdCity2</sender>
742 <signal>toggled(bool)</signal>
743 <receiver>cmdCity4</receiver>
744 <slot>setDisabled(bool)</slot>
745 </connection>
746 <connection>
747 <sender>cmdCity4</sender>
748 <signal>toggled(bool)</signal>
749 <receiver>cmdCity7</receiver>
750 <slot>setDisabled(bool)</slot>
751 </connection>
752 <connection>
753 <sender>cmdCity2</sender>
754 <signal>toggled(bool)</signal>
755 <receiver>cmdCity8</receiver>
756 <slot>setDisabled(bool)</slot>
757 </connection>
758 <connection>
759 <sender>cmdCity2</sender>
760 <signal>toggled(bool)</signal>
761 <receiver>cmdCity7</receiver>
762 <slot>setDisabled(bool)</slot>
763 </connection>
764 <connection>
765 <sender>cmdCity3</sender>
766 <signal>toggled(bool)</signal>
767 <receiver>cmdCity1</receiver>
768 <slot>setDisabled(bool)</slot>
769 </connection>
770 <connection>
771 <sender>cmdCity3</sender>
772 <signal>toggled(bool)</signal>
773 <receiver>cmdCity2</receiver>
774 <slot>setDisabled(bool)</slot>
775 </connection>
776 <connection>
777 <sender>cmdCity3</sender>
778 <signal>toggled(bool)</signal>
779 <receiver>cmdCity4</receiver>
780 <slot>setDisabled(bool)</slot>
781 </connection>
782 <connection>
783 <sender>cmdCity3</sender>
784 <signal>toggled(bool)</signal>
785 <receiver>cmdCity7</receiver>
786 <slot>setDisabled(bool)</slot>
787 </connection>
788 <connection>
789 <sender>cmdCity3</sender>
790 <signal>toggled(bool)</signal>
791 <receiver>cmdCity8</receiver>
792 <slot>setDisabled(bool)</slot>
793 </connection>
794 <connection>
795 <sender>cmdCity4</sender>
796 <signal>toggled(bool)</signal>
797 <receiver>cmdCity1</receiver>
798 <slot>setDisabled(bool)</slot>
799 </connection>
800 <connection>
801 <sender>cmdCity4</sender>
802 <signal>toggled(bool)</signal>
803 <receiver>cmdCity2</receiver>
804 <slot>setDisabled(bool)</slot>
805 </connection>
806 <connection>
807 <sender>cmdCity4</sender>
808 <signal>toggled(bool)</signal>
809 <receiver>cmdCity3</receiver>
810 <slot>setDisabled(bool)</slot>
811 </connection>
812 <connection>
813 <sender>cmdCity4</sender>
814 <signal>toggled(bool)</signal>
815 <receiver>cmdCity8</receiver>
816 <slot>setDisabled(bool)</slot>
817 </connection>
818 <connection>
819 <sender>cmdCity7</sender>
820 <signal>toggled(bool)</signal>
821 <receiver>cmdCity1</receiver>
822 <slot>setDisabled(bool)</slot>
823 </connection>
824 <connection>
825 <sender>cmdCity7</sender>
826 <signal>toggled(bool)</signal>
827 <receiver>cmdCity2</receiver>
828 <slot>setDisabled(bool)</slot>
829 </connection>
830 <connection>
831 <sender>cmdCity7</sender>
832 <signal>toggled(bool)</signal>
833 <receiver>cmdCity3</receiver>
834 <slot>setDisabled(bool)</slot>
835 </connection>
836 <connection>
837 <sender>cmdCity7</sender>
838 <signal>toggled(bool)</signal>
839 <receiver>cmdCity4</receiver>
840 <slot>setDisabled(bool)</slot>
841 </connection>
842 <connection>
843 <sender>cmdCity7</sender>
844 <signal>toggled(bool)</signal>
845 <receiver>cmdCity8</receiver>
846 <slot>setDisabled(bool)</slot>
847 </connection>
848 <connection>
849 <sender>cmdCity8</sender>
850 <signal>toggled(bool)</signal>
851 <receiver>cmdCity1</receiver>
852 <slot>setDisabled(bool)</slot>
853 </connection>
854 <connection>
855 <sender>cmdCity8</sender>
856 <signal>toggled(bool)</signal>
857 <receiver>cmdCity2</receiver>
858 <slot>setDisabled(bool)</slot>
859 </connection>
860 <connection>
861 <sender>cmdCity8</sender>
862 <signal>toggled(bool)</signal>
863 <receiver>cmdCity3</receiver>
864 <slot>setDisabled(bool)</slot>
865 </connection>
866 <connection>
867 <sender>cmdCity8</sender>
868 <signal>toggled(bool)</signal>
869 <receiver>cmdCity4</receiver>
870 <slot>setDisabled(bool)</slot>
871 </connection>
872 <connection>
873 <sender>cmdCity8</sender>
874 <signal>toggled(bool)</signal>
875 <receiver>cmdCity7</receiver>
876 <slot>setDisabled(bool)</slot>
877 </connection>
878 <connection>
879 <sender>cmdCity1</sender>
880 <signal>toggled(bool)</signal>
881 <receiver>cmdCity5</receiver>
882 <slot>setDisabled(bool)</slot>
883 </connection>
884 <connection>
885 <sender>cmdCity2</sender>
886 <signal>toggled(bool)</signal>
887 <receiver>cmdCity5</receiver>
888 <slot>setDisabled(bool)</slot>
889 </connection>
890 <connection>
891 <sender>cmdCity3</sender>
892 <signal>toggled(bool)</signal>
893 <receiver>cmdCity5</receiver>
894 <slot>setDisabled(bool)</slot>
895 </connection>
896 <connection>
897 <sender>cmdCity4</sender>
898 <signal>toggled(bool)</signal>
899 <receiver>cmdCity5</receiver>
900 <slot>setDisabled(bool)</slot>
901 </connection>
902 <connection>
903 <sender>cmdCity7</sender>
904 <signal>toggled(bool)</signal>
905 <receiver>cmdCity5</receiver>
906 <slot>setDisabled(bool)</slot>
907 </connection>
908 <connection>
909 <sender>cmdCity8</sender>
910 <signal>toggled(bool)</signal>
911 <receiver>cmdCity5</receiver>
912 <slot>setDisabled(bool)</slot>
913 </connection>
914 <connection>
915 <sender>cmdCity5</sender>
916 <signal>toggled(bool)</signal>
917 <receiver>cmdCity1</receiver>
918 <slot>setDisabled(bool)</slot>
919 </connection>
920 <connection>
921 <sender>cmdCity5</sender>
922 <signal>toggled(bool)</signal>
923 <receiver>cmdCity2</receiver>
924 <slot>setDisabled(bool)</slot>
925 </connection>
926 <connection>
927 <sender>cmdCity5</sender>
928 <signal>toggled(bool)</signal>
929 <receiver>cmdCity3</receiver>
930 <slot>setDisabled(bool)</slot>
931 </connection>
932 <connection>
933 <sender>cmdCity5</sender>
934 <signal>toggled(bool)</signal>
935 <receiver>cmdCity4</receiver>
936 <slot>setDisabled(bool)</slot>
937 </connection>
938 <connection>
939 <sender>cmdCity5</sender>
940 <signal>toggled(bool)</signal>
941 <receiver>cmdCity7</receiver>
942 <slot>setDisabled(bool)</slot>
943 </connection>
944 <connection>
945 <sender>cmdCity5</sender>
946 <signal>toggled(bool)</signal>
947 <receiver>cmdCity8</receiver>
948 <slot>setDisabled(bool)</slot>
949 </connection>
950 <connection>
951 <sender>cmdCity1</sender>
952 <signal>toggled(bool)</signal>
953 <receiver>cmdCity6</receiver>
954 <slot>setDisabled(bool)</slot>
955 </connection>
956 <connection>
957 <sender>cmdCity2</sender>
958 <signal>toggled(bool)</signal>
959 <receiver>cmdCity6</receiver>
960 <slot>setDisabled(bool)</slot>
961 </connection>
962 <connection>
963 <sender>cmdCity3</sender>
964 <signal>toggled(bool)</signal>
965 <receiver>cmdCity6</receiver>
966 <slot>setDisabled(bool)</slot>
967 </connection>
968 <connection>
969 <sender>cmdCity4</sender>
970 <signal>toggled(bool)</signal>
971 <receiver>cmdCity6</receiver>
972 <slot>setDisabled(bool)</slot>
973 </connection>
974 <connection>
975 <sender>cmdCity5</sender>
976 <signal>toggled(bool)</signal>
977 <receiver>cmdCity6</receiver>
978 <slot>setDisabled(bool)</slot>
979 </connection>
980 <connection>
981 <sender>cmdCity6</sender>
982 <signal>toggled(bool)</signal>
983 <receiver>cmdCity1</receiver>
984 <slot>setDisabled(bool)</slot>
985 </connection>
986 <connection>
987 <sender>cmdCity6</sender>
988 <signal>toggled(bool)</signal>
989 <receiver>cmdCity2</receiver>
990 <slot>setDisabled(bool)</slot>
991 </connection>
992 <connection>
993 <sender>cmdCity6</sender>
994 <signal>toggled(bool)</signal>
995 <receiver>cmdCity3</receiver>
996 <slot>setDisabled(bool)</slot>
997 </connection>
998 <connection>
999 <sender>cmdCity6</sender>
1000 <signal>toggled(bool)</signal>
1001 <receiver>cmdCity4</receiver>
1002 <slot>setDisabled(bool)</slot>
1003 </connection>
1004 <connection>
1005 <sender>cmdCity6</sender>
1006 <signal>toggled(bool)</signal>
1007 <receiver>cmdCity5</receiver>
1008 <slot>setDisabled(bool)</slot>
1009 </connection>
1010 <connection>
1011 <sender>cmdCity6</sender>
1012 <signal>toggled(bool)</signal>
1013 <receiver>cmdCity7</receiver>
1014 <slot>setDisabled(bool)</slot>
1015 </connection>
1016 <connection>
1017 <sender>cmdCity6</sender>
1018 <signal>toggled(bool)</signal>
1019 <receiver>cmdCity8</receiver>
1020 <slot>setDisabled(bool)</slot>
1021 </connection>
1022 <connection>
1023 <sender>cmdCity6</sender>
1024 <signal>toggled(bool)</signal>
1025 <receiver>cmdCity9</receiver>
1026 <slot>setDisabled(bool)</slot>
1027 </connection>
1028 <connection>
1029 <sender>cmdCity7</sender>
1030 <signal>toggled(bool)</signal>
1031 <receiver>cmdCity6</receiver>
1032 <slot>setDisabled(bool)</slot>
1033 </connection>
1034 <connection>
1035 <sender>cmdCity8</sender>
1036 <signal>toggled(bool)</signal>
1037 <receiver>cmdCity6</receiver>
1038 <slot>setDisabled(bool)</slot>
1039 </connection>
1040 <connection>
1041 <sender>cmdCity9</sender>
1042 <signal>toggled(bool)</signal>
1043 <receiver>cmdCity1</receiver>
1044 <slot>setDisabled(bool)</slot>
1045 </connection>
1046 <connection>
1047 <sender>cmdCity9</sender>
1048 <signal>toggled(bool)</signal>
1049 <receiver>cmdCity3</receiver>
1050 <slot>setDisabled(bool)</slot>
1051 </connection>
1052 <connection>
1053 <sender>cmdCity9</sender>
1054 <signal>toggled(bool)</signal>
1055 <receiver>cmdCity4</receiver>
1056 <slot>setDisabled(bool)</slot>
1057 </connection>
1058 <connection>
1059 <sender>cmdCity9</sender>
1060 <signal>toggled(bool)</signal>
1061 <receiver>cmdCity5</receiver>
1062 <slot>setDisabled(bool)</slot>
1063 </connection>
1064 <connection>
1065 <sender>cmdCity9</sender>
1066 <signal>toggled(bool)</signal>
1067 <receiver>cmdCity6</receiver>
1068 <slot>setDisabled(bool)</slot>
1069 </connection>
1070 <connection>
1071 <sender>cmdCity9</sender>
1072 <signal>toggled(bool)</signal>
1073 <receiver>cmdCity7</receiver>
1074 <slot>setDisabled(bool)</slot>
1075 </connection>
1076 <connection>
1077 <sender>cmdCity9</sender>
1078 <signal>toggled(bool)</signal>
1079 <receiver>cmdCity8</receiver>
1080 <slot>setDisabled(bool)</slot>
1081 </connection>
1082 <connection>
1083 <sender>cmdCity1</sender>
1084 <signal>toggled(bool)</signal>
1085 <receiver>cmdCity9</receiver>
1086 <slot>setDisabled(bool)</slot>
1087 </connection>
1088 <connection>
1089 <sender>cmdCity2</sender>
1090 <signal>toggled(bool)</signal>
1091 <receiver>cmdCity9</receiver>
1092 <slot>setDisabled(bool)</slot>
1093 </connection>
1094 <connection>
1095 <sender>cmdCity3</sender>
1096 <signal>toggled(bool)</signal>
1097 <receiver>cmdCity9</receiver>
1098 <slot>setDisabled(bool)</slot>
1099 </connection>
1100 <connection>
1101 <sender>cmdCity4</sender>
1102 <signal>toggled(bool)</signal>
1103 <receiver>cmdCity9</receiver>
1104 <slot>setDisabled(bool)</slot>
1105 </connection>
1106 <connection>
1107 <sender>cmdCity5</sender>
1108 <signal>toggled(bool)</signal>
1109 <receiver>cmdCity9</receiver>
1110 <slot>setDisabled(bool)</slot>
1111 </connection>
1112 <connection>
1113 <sender>cmdCity7</sender>
1114 <signal>toggled(bool)</signal>
1115 <receiver>cmdCity9</receiver>
1116 <slot>setDisabled(bool)</slot>
1117 </connection>
1118 <connection>
1119 <sender>cmdCity8</sender>
1120 <signal>toggled(bool)</signal>
1121 <receiver>cmdCity9</receiver>
1122 <slot>setDisabled(bool)</slot>
1123 </connection>
1124 <connection>
1125 <sender>cmdCity9</sender>
1126 <signal>toggled(bool)</signal>
1127 <receiver>cmdCity2</receiver>
1128 <slot>setDisabled(bool)</slot>
1129 </connection>
1130 <connection>
1131 <sender>cmdCity1</sender>
1132 <signal>toggled(bool)</signal>
1133 <receiver>CityTimeBase</receiver>
1134 <slot>beginNewTz()</slot>
1135 </connection>
1136 <connection>
1137 <sender>cmdCity2</sender>
1138 <signal>toggled(bool)</signal>
1139 <receiver>CityTimeBase</receiver>
1140 <slot>beginNewTz()</slot>
1141 </connection>
1142 <connection>
1143 <sender>cmdCity7</sender>
1144 <signal>toggled(bool)</signal>
1145 <receiver>CityTimeBase</receiver>
1146 <slot>beginNewTz()</slot>
1147 </connection>
1148 <connection>
1149 <sender>cmdCity3</sender>
1150 <signal>toggled(bool)</signal>
1151 <receiver>CityTimeBase</receiver>
1152 <slot>beginNewTz()</slot>
1153 </connection>
1154 <connection>
1155 <sender>cmdCity4</sender>
1156 <signal>toggled(bool)</signal>
1157 <receiver>CityTimeBase</receiver>
1158 <slot>beginNewTz()</slot>
1159 </connection>
1160 <connection>
1161 <sender>cmdCity5</sender>
1162 <signal>toggled(bool)</signal>
1163 <receiver>CityTimeBase</receiver>
1164 <slot>beginNewTz()</slot>
1165 </connection>
1166 <connection>
1167 <sender>cmdCity6</sender>
1168 <signal>toggled(bool)</signal>
1169 <receiver>CityTimeBase</receiver>
1170 <slot>beginNewTz()</slot>
1171 </connection>
1172 <connection>
1173 <sender>cmdCity8</sender>
1174 <signal>toggled(bool)</signal>
1175 <receiver>CityTimeBase</receiver>
1176 <slot>beginNewTz()</slot>
1177 </connection>
1178 <connection>
1179 <sender>cmdCity9</sender>
1180 <signal>toggled(bool)</signal>
1181 <receiver>CityTimeBase</receiver>
1182 <slot>beginNewTz()</slot>
1183 </connection>
1184 <slot access="public">beginNewTz()</slot>
1185 <slot access="public">slotNewTz(const QString &amp;, const QString &amp;)</slot>
1186</connections>
1187<tabstops>
1188 <tabstop>cmdCity1</tabstop>
1189 <tabstop>cmdCity2</tabstop>
1190 <tabstop>cmdCity3</tabstop>
1191 <tabstop>cmdCity4</tabstop>
1192 <tabstop>cmdCity5</tabstop>
1193 <tabstop>cmdCity6</tabstop>
1194 <tabstop>cmdCity7</tabstop>
1195 <tabstop>cmdCity8</tabstop>
1196 <tabstop>cmdCity9</tabstop>
1197 <tabstop>frmMap</tabstop>
1198</tabstops>
1199</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 @@
1#!/usr/bin/perl
2
3# A Little utility to help tidy up messy zoneinfo directories.
4
5use File::Find;
6
7find sub {
8 if ( -f $_ ) {
9 my $a;
10 open T, $_;
11 read T, $a, 4;
12 if ( $a eq "TZif" ) {
13 my $d="$File::Find::dir/$_";
14 $d =~ s/^.\///;
15 $D{$d}=1;
16 }
17 close T;
18 }
19}, ".";
20
21open Z, "zone.tab" || die;
22
23while (<Z>) {
24 next if /^#/;
25 if ( ($cc, $north, $east, $z, $comment) =
26 $_ =~ /^(\S\S)\s+([+-]\d+)([+-]\d+)\s+(\S+)\s*(\S*)/ )
27 {
28 $Z{$z}=1;
29 }
30}
31
32for $d ( sort keys %D ) {
33 print "rm $d\n" if !$Z{$d};
34}
35
36for $z ( sort keys %Z ) {
37 print "zone $z, but no such file\n" if !$D{$z};
38}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "citytime.h"
22#include <qpe/qpeapplication.h>
23
24int main( int argc, char** argv )
25{
26 QPEApplication a( argc, argv );
27 CityTime main;
28 a.showMainWidget( &main );
29 return a.exec();
30}
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 @@
1Files: bin/citytime apps/Applications/citytime.desktop
2Priority: optional
3Section: qpe/applications
4Maintainer: Warwick Allison <warwick@trolltech.com>
5Architecture: arm
6Version: $QPE_VERSION-3
7Depends: qpe-base ($QPE_VERSION), timezones
8Description: Time-zone / world clock settings
9 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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include <qpoint.h>
22#include <qtimer.h>
23
24#include "stylusnormalizer.h"
25
26static const int FLUSHTIME = 100;
27
28_StylusEvent::_StylusEvent( const QPoint& newPt )
29 : _pt( newPt ),
30 _t( QTime::currentTime() )
31{
32}
33
34_StylusEvent::~_StylusEvent()
35{
36}
37
38StylusNormalizer::StylusNormalizer( QWidget *parent, const char* name )
39 : QWidget( parent, name ),
40 _next( 0 ),
41 bFirst( true )
42{
43 // initialize _ptList
44 int i;
45 for (i = 0; i < SAMPLES; i++ ) {
46 _ptList[i].setPoint( -1, -1 );
47 }
48 _tExpire = new QTimer( this );
49 QObject::connect( _tExpire, SIGNAL( timeout() ),
50 this, SLOT( slotAveragePoint() ) );
51}
52
53StylusNormalizer::~StylusNormalizer()
54{
55}
56
57void StylusNormalizer::addEvent( const QPoint& pt )
58{
59 _ptList[_next].setPoint( pt );
60 _ptList[_next++].setTime( QTime::currentTime() );
61 if ( _next >= SAMPLES ) {
62 _next = 0;
63 }
64 // make a single mouse click work
65 if ( bFirst ) {
66 slotAveragePoint();
67 bFirst = false;
68 }
69}
70
71void StylusNormalizer::slotAveragePoint( void )
72{
73 QPoint pt( 0, 0 );
74 QTime tCurr = QTime::currentTime();
75 int i,
76 size;
77 size = 0;
78 for ( i = 0; i < SAMPLES; i++ ) {
79 if ( ( (_ptList[i]).time().msecsTo( tCurr ) < FLUSHTIME ) &&
80 ( _ptList[i].point() != QPoint( -1, -1 ) ) ) {
81 pt += _ptList[i].point();
82 size++;
83 }
84 }
85 if ( size > 0 )
86 emit signalNewPoint( pt /= size );
87}
88
89void StylusNormalizer::start( void )
90{
91 _tExpire->start( FLUSHTIME );
92}
93
94void StylusNormalizer::stop( void )
95{
96 _tExpire->stop();
97 bFirst = true;
98} \ 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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#ifndef STYLUSNORMALIZER_H
22#define STYLUSNORMALIZER_H
23
24#include <qdatetime.h>
25#include <qwidget.h>
26
27class QTimer;
28
29class _StylusEvent
30{
31public:
32 _StylusEvent( const QPoint &pt = QPoint( 0, 0 ) );
33 ~_StylusEvent();
34 QPoint point( void ) const { return _pt; };
35 QTime time( void ) const { return _t; };
36 void setPoint( int x, int y) { _pt.setX( x ); _pt.setY( y ); };
37 void setPoint( const QPoint &newPt ) { _pt = newPt; };
38 void setTime( QTime newTime ) { _t = newTime; };
39
40private:
41 QPoint _pt;
42 QTime _t;
43};
44
45
46class StylusNormalizer : public QWidget
47{
48 Q_OBJECT
49public:
50 StylusNormalizer( QWidget *parent = 0, const char* name = 0 );
51 ~StylusNormalizer();
52 void start();
53 void stop();
54 void addEvent( const QPoint &pt ); // add a new point in
55
56signals:
57 void signalNewPoint( const QPoint &p );
58
59private slots:
60 void slotAveragePoint( void ); // return an averaged point
61
62private:
63 static const int SAMPLES = 10;
64 _StylusEvent _ptList[SAMPLES];
65 int _next;
66 QTimer *_tExpire;
67 bool bFirst; // the first item added in...
68};
69
70#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 @@
1/*
2 * Sun clock. X11 version by John Mackin.
3 *
4 * This program was derived from, and is still in part identical with, the
5 * Suntools Sun clock program whose author's comment appears immediately
6 * below. Please preserve both notices.
7 *
8 * The X11R3/4 version of this program was written by John Mackin, at the
9 * Basser Department of Computer Science, University of Sydney, Sydney,
10 * New South Wales, Australia; <john@cs.su.oz.AU>. This program, like
11 * the one it was derived from, is in the public domain: `Love is the
12 * law, love under will.'
13 */
14
15/*
16
17 Sun clock
18
19 Designed and implemented by John Walker in November of 1988.
20
21 Version for the Sun Workstation.
22
23 The algorithm used to calculate the position of the Sun is given in
24 Chapter 18 of:
25
26 "Astronomical Formulae for Calculators" by Jean Meeus, Third Edition,
27 Richmond: Willmann-Bell, 1985. This book can be obtained from:
28
29 Willmann-Bell
30 P.O. Box 35025
31 Richmond, VA 23235
32 USA
33 Phone: (804) 320-7016
34
35 This program was written by:
36
37 John Walker
38 Autodesk, Inc.
39 2320 Marinship Way
40 Sausalito, CA 94965
41 USA
42 Fax: (415) 389-9418
43 Voice: (415) 332-2344 Ext. 2829
44 Usenet: {sun,well,uunet}!acad!kelvin
45 or: kelvin@acad.uu.net
46
47 modified for interactive maps by
48
49 Stephen Martin
50 Fujitsu Systems Business of Canada
51 smartin@fujitsu.ca
52
53 This program is in the public domain: "Do what thou wilt shall be the
54 whole of the law". I'd appreciate receiving any bug fixes and/or
55 enhancements, which I'll incorporate in future versions of the
56 program. Please leave the original attribution information intactso
57 that credit and blame may be properly apportioned.
58
59 Revision history:
60
61 1.0 12/21/89 Initial version.
62 8/24/89 Finally got around to submitting.
63
64 1.1 8/31/94 Version with interactive map.
65 1.2 10/12/94 Fixes for HP and Solaris, new icon bitmap
66 1.3 11/01/94 Timezone now shown in icon
67 1.4 03/29/98 Fixed city drawing, added icon animation
68
69*/
70
71#include "sun.h"
72
73#include <qpe/qmath.h>
74
75/* PROJILLUM -- Project illuminated area on the map. */
76
77void
78projillum(wtab, xdots, ydots, dec)
79short *wtab;
80int xdots, ydots;
81double dec;
82{
83 int i, ftf = 1, ilon, ilat, lilon = 0, lilat = 0, xt;
84 double m, x, y, z, th, lon, lat, s, c;
85
86 /* Clear unoccupied cells in width table */
87
88 for (i = 0; i < ydots; i++)
89 wtab[i] = -1;
90
91 /* Build transformation for declination */
92
93 s = qSin(-dtr(dec));
94 c = qCos(-dtr(dec));
95
96 /* Increment over a semicircle of illumination */
97
98 for (th = -(PI / 2); th <= PI / 2 + 0.001;
99 th += PI / TERMINC) {
100
101 /* Transform the point through the declination rotation. */
102
103 x = -s * qSin(th);
104 y = qCos(th);
105 z = c * qSin(th);
106
107 /* Transform the resulting co-ordinate through the
108 map projection to obtain screen co-ordinates. */
109
110 lon = (y == 0 && x == 0) ? 0.0 : rtd(qATan2(y, x));
111 lat = rtd(qASin(z));
112
113 ilat = ydots - (lat + 90) * (ydots / 180.0);
114 ilon = lon * (xdots / 360.0);
115
116 if (ftf) {
117
118 /* First time. Just save start co-ordinate. */
119
120 lilon = ilon;
121 lilat = ilat;
122 ftf = 0;
123 } else {
124
125 /* Trace out the line and set the width table. */
126
127 if (lilat == ilat) {
128 wtab[(ydots - 1) - ilat] = ilon == 0 ? 1 : ilon;
129 } else {
130 m = ((double) (ilon - lilon)) / (ilat - lilat);
131 for (i = lilat; i != ilat; i += sgn(ilat - lilat)) {
132 xt = lilon + qFloor((m * (i - lilat)) + 0.5);
133 wtab[(ydots - 1) - i] = xt == 0 ? 1 : xt;
134 }
135 }
136 lilon = ilon;
137 lilat = ilat;
138 }
139 }
140
141 /* Now tweak the widths to generate full illumination for
142 the correct pole. */
143
144 if (dec < 0.0) {
145 ilat = ydots - 1;
146 lilat = -1;
147 } else {
148 ilat = 0;
149 lilat = 1;
150 }
151
152 for (i = ilat; i != ydots / 2; i += lilat) {
153 if (wtab[i] != -1) {
154 while (1) {
155 wtab[i] = xdots / 2;
156 if (i == ilat)
157 break;
158 i -= lilat;
159 }
160 break;
161 }
162 }
163}
164
165/*
166 * Sun clock - astronomical routines.
167 */
168
169/* JDATE -- Convert internal GMT date and time to Julian day
170 and fraction. */
171
172long
173jdate(t)
174struct tm *t;
175{
176 long c, m, y;
177
178 y = t->tm_year + 1900;
179 m = t->tm_mon + 1;
180 if (m > 2)
181 m = m - 3;
182 else {
183 m = m + 9;
184 y--;
185 }
186 c = y / 100L; /* Compute century */
187 y -= 100L * c;
188 return t->tm_mday + (c * 146097L) / 4 + (y * 1461L) / 4 +
189 (m * 153L + 2) / 5 + 1721119L;
190}
191
192 /* JTIME -- Convert internal GMT date andtime to astronomical
193 Julian time (i.e. Julian date plus day fraction,
194 expressed as a double).*/
195
196double
197jtime(t)
198struct tm *t;
199{
200 return (jdate(t) - 0.5) +
201 (((long) t->tm_sec) +
202 60L * (t->tm_min + 60L * t->tm_hour)) / 86400.0;
203}
204
205 /* KEPLER --Solve the equation of Kepler. */
206
207double
208kepler(m, ecc)
209double m, ecc;
210{
211 double e, delta;
212#define EPSILON 1E-6
213
214 e = m = dtr(m);
215 do {
216 delta = e - ecc * qSin(e) - m;
217 e -= delta / (1 - ecc * qCos(e));
218 } while (qFabs(delta) > EPSILON);
219 return e;
220}
221
222 /* SUNPOS -- Calculate position of the Sun.JD is the Julian date
223 of the instant for which the position is desired and
224 APPARENT should be nonzero if the apparent position
225 (corrected for nutation and aberration) is desired.
226 The Sun's co-ordinates are returned in RA and DEC,
227 both specified in degrees (divide RA by 15 to obtain
228 hours). The radius vector to the Sun in astronomical
229 units is returned in RV and the Sun's longitude (true
230 or apparent, as desired) is returned as degrees in
231 SLONG.*/
232
233
234void
235sunpos(jd, apparent, ra, dec, rv, slong)
236double jd;
237int apparent;
238double *ra, *dec, *rv, *slong;
239{
240 double t, t2, t3, l, m, e, ea, v, theta, omega,
241 eps;
242
243 /* Time, in Julian centuries of 36525 ephemeris days,
244 measured from the epoch 1900 January 0.5 ET. */
245
246 t = (jd - 2415020.0) / 36525.0;
247 t2 = t * t;
248 t3 = t2 * t;
249
250 /* Geometric mean longitude of the Sun, referred to the
251 mean equinox of the date. */
252
253 l = fixangle(279.69668 + 36000.76892 * t + 0.0003025 * t2);
254
255 /* Sun's mean anomaly. */
256
257 m = fixangle(358.47583 + 35999.04975*t - 0.000150*t2 - 0.0000033*t3);
258
259 /* Eccentricity of the Earth's orbit. */
260
261 e = 0.01675104 - 0.0000418 * t - 0.000000126 * t2;
262
263 /* Eccentric anomaly. */
264
265 ea = kepler(m, e);
266
267 /* True anomaly */
268
269 v = fixangle(2 * rtd(qATan(qSqrt((1 + e) / (1 - e)) * qTan(ea / 2))));
270
271 /* Sun's true longitude. */
272
273 theta = l + v - m;
274
275 /* Obliquity of the ecliptic. */
276
277 eps = 23.452294 - 0.0130125 * t - 0.00000164 * t2 + 0.000000503 * t3;
278
279 /* Corrections for Sun's apparent longitude, if desired. */
280
281 if (apparent) {
282 omega = fixangle(259.18 - 1934.142 * t);
283 theta = theta - 0.00569 - 0.00479 * qSin(dtr(omega));
284 eps += 0.00256 * qCos(dtr(omega));
285 }
286
287 /* Return Sun's longitude and radius vector */
288
289 *slong = theta;
290 *rv = (1.0000002 * (1 - e * e)) / (1 + e * qCos(dtr(v)));
291
292 /* Determine solar co-ordinates. */
293
294 *ra =
295 fixangle(rtd(qATan2(qCos(dtr(eps)) * qSin(dtr(theta)), qCos(dtr(theta)))));
296 *dec = rtd(qASin(sin(dtr(eps)) * qSin(dtr(theta))));
297}
298
299/* GMST -- Calculate Greenwich Mean Siderial Time for a given
300 instant expressed as a Julian date and fraction.*/
301
302double
303gmst(jd)
304double jd;
305{
306 double t, theta0;
307
308
309 /* Time, in Julian centuries of 36525 ephemeris days,
310 measured from the epoch 1900 January 0.5 ET. */
311
312 t = ((qFloor(jd + 0.5) - 0.5) - 2415020.0) / 36525.0;
313
314 theta0 = 6.6460656 + 2400.051262 * t + 0.00002581 * t * t;
315
316 t = (jd + 0.5) - (qFloor(jd + 0.5));
317
318 theta0 += (t * 24.0) * 1.002737908;
319
320 theta0 = (theta0 - 24.0 * (qFloor(theta0 / 24.0)));
321
322 return theta0;
323}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20/*
21 * Sun clock definitions.
22 */
23
24#include <stdio.h>
25#include <stdlib.h>
26#include <math.h>
27#include <time.h>
28
29#ifndef PI
30#define PI 3.14159265358979323846
31#endif
32
33#ifndef E
34#define E 2.7182818284590452354
35#endif
36
37 #define abs(x) ((x) < 0 ? (-(x)) : x) /* Absolute value */
38 #define sgn(x) (((x) < 0) ? -1 : ((x) > 0 ? 1 : 0)) /* Extract sign */
39 #define dtr(x) ((x) * (PI / 180.0)) /* Degree->Radian */
40 #define rtd(x) ((x) / (PI / 180.0)) /* Radian->Degree */
41 #define fixangle(a) ((a) - 360.0 * (qFloor((a) / 360.0))) /* Fix angle */
42
43 #define TERMINC 100 /* Circle segments for terminator */
44
45 #define PROJINT (60 * 10) /* Frequency of seasonal recalculation */
46
47
48#ifdef __cplusplus
49extern "C" {
50#endif
51double jtime(struct tm *t);
52double kepler(double m, double ecc);
53void sunpos(double jd, int apparent, double *ra, double *dec, double *rv, double *slong);
54void projillum(short *wtab, int xdots, int ydots, double dec);
55#ifdef __cplusplus
56};
57#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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "sun.h"
22#include "zonemap.h"
23
24#include <qpe/resource.h>
25#include <qpe/timestring.h>
26#include <qpe/qpeapplication.h>
27
28#include <qdatetime.h>
29#include <qfile.h>
30#include <qimage.h>
31#include <qlabel.h>
32#include <qlist.h>
33#include <qmessagebox.h>
34#include <qpixmap.h>
35#include <qpainter.h>
36#include <qregexp.h>
37#include <qtextstream.h>
38#include <qtimer.h>
39#include <qtoolbutton.h>
40
41#include <limits.h>
42
43// the map file...
44static const char strZONEINFO[] = "/usr/share/zoneinfo/zone.tab";
45static const char strMAP[] = "simple_grid_400";
46
47// the maximum distance we'll allow the pointer to be away from a city
48// and still show the city's time
49static const int iTHRESHOLD = 50000;
50
51// The label offset (how far away from pointer)
52static const int iLABELOFFSET = 8;
53
54// the size of the dot to draw, and where to start it
55static const int iCITYSIZE = 3;
56const int iCITYOFFSET = 2;
57
58// the darkening function
59static inline void darken( QImage *pImage, int start, int stop, int row );
60static void dayNight( QImage *pImage );
61
62ZoneField::ZoneField( const QString& strLine )
63{
64 // make a bunch of RegExp's to match the data from the line
65 QRegExp regCoord( "[-+][0-9]+" );// the latitude
66 QRegExp regCountry( "[A-Za-z]+/" ); // the country (not good enough)
67 QRegExp regCity( "[A-Za-z_-]*" ); // the city
68
69 int iStart,
70 iStop,
71 iLen,
72 tmp;
73 QString strTmp;
74 // we should be able to assume that the country code is always the first
75 // two chars, so just grap them and let it go...
76 strCountryCode = strLine.left( 2 );
77 iStart = regCoord.match( strLine, 0, &iLen );
78 if ( iStart >= 0 ) {
79 strTmp = strLine.mid( iStart, iLen );
80 tmp = strTmp.toInt();
81 // okay, there are two versions of the format, make a decision based on
82 // the size...
83 // Oh BTW, we are storing everything in seconds!
84 if ( iLen < 7 ) {
85 _y = tmp / 100;
86 _y *= 60;
87 _y += tmp % 100;
88 _y *= 60;
89 } else {
90 _y = tmp / 10000;
91 _y *= 60;
92 tmp %= 10000;
93 _y += tmp / 100;
94 _y *= 60;
95 tmp %= 100;
96 _y += tmp;
97 }
98 }
99 iStart = regCoord.match( strLine, iStart + iLen, &iLen );
100 if ( iStart >= 0 ) {
101 strTmp = strLine.mid( iStart, iLen );
102 tmp = strTmp.toInt();
103 if ( iLen < 8 ) {
104 _x = tmp / 100;
105 _x *= 60;
106 _x += tmp % 100;
107 _x *= 60;
108 } else {
109 _x = tmp / 10000;
110 _x *= 60;
111 tmp %= 10000;
112 _x += tmp / 100;
113 _x *= 60;
114 tmp %= 100;
115 _x += tmp;
116 }
117 }
118 iStart = regCountry.match( strLine, 0, &iLen );
119 // help with the shortcoming in 2.x regexp...
120 iStop = strLine.findRev( '/' );
121 if ( iStart >= 0 ) {
122 iLen = (iStop - iStart) + 1;
123 strCountry = strLine.mid( iStart, iLen );
124 }
125 // now match the city...
126 iStart = regCity.match( strLine, iStart + iLen, &iLen );
127 if ( iStart >= 0 ) {
128 strCity = strLine.mid( iStart, iLen );
129 }
130}
131
132void ZoneField::showStructure( void ) const
133{
134 qDebug( "Country: %s", strCountry.latin1() );
135 qDebug( "City: %s", strCity.latin1() );
136 qDebug( "x: %d", _x );
137 qDebug( "y: %d\n", _y );
138}
139
140ZoneMap::ZoneMap( QWidget *parent, const char* name )
141 : QScrollView( parent, name ),
142 pLast( 0 ),
143 pRepaint( 0 ),
144 ox( 0 ),
145 oy( 0 ),
146 drawableW( -1 ),
147 drawableH( -1 ),
148 bZoom( FALSE ),
149 bIllum( TRUE ),
150 cursor( 0 )
151{
152 viewport()->setFocusPolicy( StrongFocus );
153
154 // set mouse tracking so we can use the mouse move event
155 zones.setAutoDelete( true );
156 // get the map loaded
157 // just set the current image to point
158 pixCurr = new QPixmap();
159
160 QPixmap pixZoom = Resource::loadPixmap( "mag" );
161
162 cmdZoom = new QToolButton( this, "Zoom command" );
163 cmdZoom->setPixmap( pixZoom );
164 cmdZoom->setToggleButton( true );
165
166 cmdZoom->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)0,
167 (QSizePolicy::SizeType)0,
168 cmdZoom->sizePolicy().hasHeightForWidth() ) );
169 cmdZoom->setMaximumSize( cmdZoom->sizeHint() );
170 // probably don't need this, but just in case...
171 cmdZoom->move( width() - cmdZoom->width(), height() - cmdZoom->height() );
172
173
174 lblCity = new QLabel( tr( "CITY" ), this, "City Label" );
175 lblCity->setMinimumSize( lblCity->sizeHint() );
176 lblCity->setFrameStyle( QFrame::Plain | QFrame::Box );
177 lblCity->setBackgroundColor( yellow );
178 lblCity->hide();
179
180 // A timer to make sure the label gets hidden
181 tHide = new QTimer( this, "Label Timer" );
182 QObject::connect( tHide, SIGNAL( timeout() ),
183 lblCity, SLOT( hide() ) );
184 QObject::connect( tHide, SIGNAL( timeout() ),
185 this, SLOT( slotRedraw() ) );
186 QTimer *tUpdate = new QTimer( this, "Update Timer" );
187 QObject::connect( tUpdate, SIGNAL( timeout() ),
188 this, SLOT( slotUpdate() ) );
189 QObject::connect( qApp, SIGNAL( timeChanged() ),
190 this, SLOT( slotUpdate() ) );
191 QObject::connect( cmdZoom, SIGNAL( toggled( bool ) ),
192 this, SLOT( slotZoom( bool ) ) );
193 QObject::connect( &norm, SIGNAL( signalNewPoint( const QPoint& ) ),
194 this, SLOT( slotFindCity( const QPoint& ) ) );
195 QObject::connect( qApp, SIGNAL( clockChanged( bool ) ),
196 this, SLOT( changeClock( bool ) ) );
197 // update the sun's movement every 5 minutes
198 tUpdate->start( 5 * 60 * 1000 );
199 // May as well read in the timezone information too...
200 readZones();
201}
202
203ZoneMap::~ZoneMap()
204{
205}
206
207void ZoneMap::readZones( void )
208{
209 QFile fZone( strZONEINFO );
210 if ( !fZone.open( IO_ReadOnly ) ) {
211 QMessageBox::warning (this,
212 tr( "Unable to Find Timezone Info" ),
213 tr( "<p>Unable to find any timezone information in %1" )
214 .arg( strZONEINFO ));
215 exit(-1);
216 } else {
217 QTextStream tZone( &fZone );
218 while ( !tZone.atEnd() ) {
219 QString strLine = tZone.readLine();
220 // only pass on lines that aren't comments
221 if ( strLine[0] != '#' ) {
222 zones.append( new ZoneField( strLine ) );
223 }
224 }
225 fZone.close();
226 }
227}
228
229void ZoneMap::viewportMousePressEvent( QMouseEvent* event )
230{
231 // add the mouse event into the normalizer, and get the average,
232 // pass it along
233 slotRedraw();
234 norm.start();
235 norm.addEvent( event->pos() );
236}
237
238void ZoneMap::viewportMouseMoveEvent( QMouseEvent* event )
239{
240 norm.addEvent( event->pos() );
241}
242
243void ZoneMap::viewportMouseReleaseEvent( QMouseEvent* )
244{
245 // get the averaged points in case a timeout hasn't occurred,
246 // more for "mouse clicks"
247 norm.stop();
248 if ( pLast != NULL ) {
249 emit signalTz( pLast->country(), pLast->city() );
250 pLast = NULL;
251 }
252 tHide->start( 2000, true );
253}
254
255void ZoneMap::keyPressEvent( QKeyEvent *ke )
256{
257 switch ( ke->key() ) {
258 case Key_Left:
259 case Key_Right:
260 case Key_Up:
261 case Key_Down: {
262 tHide->stop();
263 if ( !cursor )
264 slotFindCity( QPoint( contentsWidth(), contentsHeight() ) / 2 );
265 ZoneField *city = findCityNear( cursor, ke->key() );
266 if ( city ) {
267 cursor = city;
268 int tmpx, tmpy;
269 zoneToWin( cursor->x(), cursor->y(), tmpx, tmpy );
270 ensureVisible( tmpx, tmpy );
271 showCity( cursor );
272 tHide->start( 3000, true );
273 }
274 }
275 break;
276
277 case Key_Space:
278 case Key_Enter:
279 case Key_Return:
280 if ( cursor ) {
281 emit signalTz( cursor->country(), cursor->city() );
282 tHide->start( 0, true );
283 }
284 break;
285 }
286}
287
288ZoneField *ZoneMap::findCityNear( ZoneField *city, int key )
289{
290 ZoneField *pZone;
291 ZoneField *pClosest = 0;
292 long ddist = LONG_MAX;
293
294 QListIterator<ZoneField> it( zones );
295 for (; it.current(); ++it) {
296 pZone = it.current();
297 long dx = (pZone->x() - city->x())/100;
298 long dy = (pZone->y() - city->y())/100;
299 switch ( key ) {
300 case Key_Right:
301 case Key_Left:
302 if ( key == Key_Left )
303 dx = -dx;
304 if ( dx > 0 ) {
305 long dist = QABS(dy)*4 + dx;
306 if ( dist < ddist ) {
307 ddist = dist;
308 pClosest = pZone;
309 }
310 }
311 break;
312 case Key_Down:
313 case Key_Up:
314 if ( key == Key_Down )
315 dy = -dy;
316 if ( dy > 0 ) {
317 long dist = QABS(dx)*4 + dy;
318 if ( dist < ddist ) {
319 ddist = dist;
320 pClosest = pZone;
321 }
322 }
323 break;
324 }
325 }
326
327 return pClosest;
328}
329
330void ZoneMap::slotFindCity( const QPoint &pos )
331{
332 lblCity->hide();
333 // given coordinates on the screen find the closest city and display the
334 // label close to it
335 int tmpx, tmpy, x, y;
336 long lDistance,
337 lClosest;
338 ZoneField *pZone,
339 *pClosest;
340
341 if ( tHide->isActive() ) {
342 tHide->stop();
343 }
344 viewportToContents(pos.x(), pos.y(), tmpx, tmpy);
345 winToZone( tmpx, tmpy, x, y );
346 // Find city alogorithim: start out at an (near) infinite distance away and
347 // then find the closest city, (similar to the Z-buffer technique, I guess)
348 // the only problem is that this is all done with doubles, but I don't know
349 // another way to do it at the moment. Another problem is a linked list is
350 // used obviously something indexed would help
351 QListIterator<ZoneField> it( zones );
352 pClosest = 0;
353 lClosest = LONG_MAX;
354 for (; it.current(); ++it) {
355 pZone = it.current();
356 // use the manhattenLength, a good enough of an appoximation here
357 lDistance = QABS( x - pZone->x() ) + QABS( y - pZone->y() );
358 // first to zero wins!
359 if ( lDistance < lClosest ) {
360 lClosest = lDistance;
361 pClosest = pZone;
362 }
363 }
364
365 // Okay, we found the closest city, but it might still be too far away.
366 if ( lClosest <= iTHRESHOLD ) {
367 showCity( pClosest );
368 cursor = pClosest;
369 }
370}
371
372void ZoneMap::showCity( ZoneField *city )
373{
374 pLast = city;
375 // we'll use city and country a couple of times, get them to save some
376 // time
377 QString strCity = pLast->city();
378 QString strCountry = pLast->country();
379 // Display the time at this location by setting the environment timezone
380 // getting the current time [there] and then swapping back the variable
381 // so no one notices...
382 QString strSave;
383 char *p = getenv( "TZ" );
384 if ( p ) {
385 strSave = p;
386 }
387 // set the timezone :)
388 setenv( "TZ", strCountry + strCity, true );
389 lblCity->setText( strCity.replace( QRegExp("_"), " ") + "\n" +
390 TimeString::shortTime( ampm ) );
391 lblCity->setMinimumSize( lblCity->sizeHint() );
392 // undue our damage...
393 unsetenv( "TZ" );
394 if ( p )
395 setenv( "TZ", strSave, true );
396 // Now decide where to move the label, x & y can be reused
397 int tmpx, tmpy, x, y;
398 zoneToWin( pLast->x(), pLast->y(), tmpx, tmpy );
399 contentsToViewport(tmpx, tmpy, x, y);
400 if ( lblCity->width() > drawableW - x ) {
401 // oops... try putting it on the right
402 x = x - lblCity->width() - iLABELOFFSET;
403 } else {
404 // the default...
405 x += iLABELOFFSET;
406 }
407 if ( lblCity->height() > drawableH - y ) {
408 // move it up...
409 y = y - lblCity->height() - iLABELOFFSET;
410 } else if ( y < 0 ) {
411 // the city is actually off the screen...
412 // this only happens on the a zoom when you are near the top,
413 // a quick workaround..
414 y = iLABELOFFSET;
415 } else {
416 // the default
417 y += iLABELOFFSET;
418 }
419
420 // draw in the city and the label
421 if ( pRepaint ) {
422 int repx,
423 repy;
424 zoneToWin( pRepaint->x(), pRepaint->y(), repx, repy );
425 updateContents( repx - iCITYOFFSET, repy - iCITYOFFSET,
426 iCITYSIZE, iCITYSIZE );
427 }
428 updateContents( tmpx - iCITYOFFSET, tmpy - iCITYOFFSET, iCITYSIZE,
429 iCITYSIZE );
430 pRepaint = pLast;
431
432 lblCity->move( x, y );
433 lblCity->show();
434}
435
436void ZoneMap::resizeEvent( QResizeEvent *e )
437{
438 // keep the zoom button down in the corner
439 QSize _size = e->size();
440 cmdZoom->move( _size.width() - cmdZoom->width(),
441 _size.height() - cmdZoom->height() );
442 if ( !bZoom ) {
443 drawableW = width() - 2 * frameWidth();
444 drawableH = height() - 2 * frameWidth();
445 makeMap( drawableW, drawableH );
446 resizeContents( drawableW, drawableH );
447 }
448}
449
450void ZoneMap::showZones( void ) const
451{
452 // go through the zones in the list and just display the values...
453 QListIterator<ZoneField> itZone( zones );
454 for ( itZone.toFirst(); itZone.current(); ++itZone ) {
455 ZoneField *pZone = itZone.current();
456 pZone->showStructure();
457 }
458}
459
460void ZoneMap::drawCities( QPainter *p )
461{
462 int x,
463 y,
464 j;
465 // draw in the cities
466 // for testing only as when you put it
467 // on the small screen it looks awful and not to mention useless
468 p->setPen( red );
469 QListIterator<ZoneField> itZone( zones );
470 for ( itZone.toFirst(), j = 0; itZone.current(); ++itZone, j++ ) {
471 ZoneField *pZone = itZone.current();
472 zoneToWin( pZone->x(), pZone->y(), x, y );
473 if ( x > wImg )
474 x = x - wImg;
475 p->drawRect( x - iCITYOFFSET, y - iCITYOFFSET, iCITYSIZE, iCITYSIZE);
476 }
477}
478
479static void dayNight(QImage *pImage)
480{
481 // create a mask the functions from sun.h
482 double dJulian,
483 dSunRad,
484 dSunDecl,
485 dSunRadius,
486 dSunLong;
487 int wImage = pImage->width(),
488 hImage = pImage->height(),
489 iStart,
490 iStop,
491 iMid,
492 relw,
493 i;
494 short wtab[ wImage ];
495 time_t tCurrent;
496 struct tm *pTm;
497
498 // get the position of the sun bassed on our current time...
499 tCurrent = time( NULL );
500 pTm = gmtime( &tCurrent );
501 dJulian = jtime( pTm );
502 sunpos( dJulian, 0, &dSunRad, &dSunDecl, &dSunRadius, &dSunLong );
503
504 // now get the projected illumination
505 projillum( wtab, wImage, hImage, dSunDecl );
506 relw = wImage - int( wImage * 0.0275 );
507
508 // draw the map, keeping in mind that we may go too far off the map...
509 iMid = ( relw * ( 24*60 - pTm->tm_hour * 60 - pTm->tm_min ) ) / ( 24*60 );
510
511 for ( i = 0; i < hImage; i++ ) {
512 if ( wtab[i] > 0 ) {
513 iStart = iMid - wtab[i];
514 iStop = iMid + wtab[i];
515 if ( iStart < 0 ) {
516 darken( pImage, iStop, wImage + iStart, i );
517 } else if ( iStop > wImage ) {
518 darken( pImage, iStop - wImage, iStart, i );
519 } else {
520 darken( pImage, 0, iStart, i );
521 darken( pImage, iStop, wImage, i );
522 }
523 } else {
524 darken( pImage, 0, wImage, i );
525 }
526 }
527}
528
529static inline void darken( QImage *pImage, int start, int stop, int row )
530{
531 int colors,
532 j;
533 uchar *p;
534
535 // assume that the image is similar to the one we have...
536 colors = pImage->numColors() / 2;
537
538 p = pImage->scanLine( row );
539 for ( j = start; j <= stop; j++ ) {
540 if ( p[j] < colors )
541 p[j] += colors;
542 }
543}
544
545void ZoneMap::makeMap( int w, int h )
546{
547 QImage imgOrig = Resource::loadImage( strMAP );
548 if ( imgOrig.isNull() ) {
549 QMessageBox::warning( this,
550 tr( "Couldn't Find Map" ),
551 tr( "<p>Couldn't load map: %1, exiting")
552 .arg( strMAP ) );
553 exit(-1);
554 }
555
556 // set up the color table for darkening...
557 imgOrig = imgOrig.convertDepth( 8 );
558 int numColors = imgOrig.numColors();
559 // double the colors
560 imgOrig.setNumColors( 2 * numColors );
561 // darken the new ones...
562 for ( int i = 0; i < numColors; i++ ) {
563 QRgb rgb = imgOrig.color( i );
564 imgOrig.setColor ( i + numColors, qRgb( 2 * qRed( rgb ) / 3,
565 2 * qGreen( rgb ) / 3, 2 * qBlue( rgb ) / 3 ) );
566 }
567
568 // else go one with making the map...
569 if ( bIllum ) {
570 // do a daylight mask
571 dayNight(&imgOrig);
572 }
573 // redo the width and height
574 wImg = w;
575 hImg = h;
576 ox = ( wImg / 2 ) - int( wImg * 0.0275 );
577 oy = hImg / 2;
578 pixCurr->convertFromImage( imgOrig.smoothScale(w, h),
579 QPixmap::ThresholdDither );
580}
581
582void ZoneMap::drawCity( QPainter *p, const ZoneField *pCity )
583{
584 int x,
585 y;
586
587 p->setPen( red );
588 zoneToWin( pCity->x(), pCity->y(), x, y );
589 p->drawRect( x - iCITYOFFSET, y - iCITYOFFSET, iCITYSIZE, iCITYSIZE );
590}
591
592void ZoneMap::drawContents( QPainter *p, int cx, int cy, int cw, int ch )
593{
594 // if there is a need to resize, then do it...
595 // get our drawable area
596 drawableW = width() - 2 * frameWidth();
597 drawableH = height() - 2 * frameWidth();
598
599 int pixmapW = pixCurr->width(),
600 pixmapH = pixCurr->height();
601 if ( !bZoom && ( ( pixmapW != drawableW ) ||
602 ( pixmapH != drawableH) ) ) {
603 makeMap( drawableW, drawableH );
604 }
605
606 // taken from the scrollview example...
607 int rowheight = pixCurr->height();
608 int toprow = cy / rowheight;
609 int bottomrow = ( cy + ch + rowheight - 1 ) / rowheight;
610 int colwidth = pixCurr->width();
611 int leftcol= cx / colwidth;
612 int rightcol= ( cx + cw + colwidth - 1 ) / colwidth;
613 for ( int r = toprow; r <= bottomrow; r++ ) {
614 int py = r * rowheight;
615 for ( int c = leftcol; c <= rightcol; c++ ) {
616 int px = c * colwidth;
617 p->drawPixmap( px, py, *pixCurr );
618 }
619 }
620
621 // Draw that city!
622 if ( pLast )
623 drawCity( p, pLast );
624}
625
626void ZoneMap::slotZoom( bool setZoom )
627{
628 bZoom = setZoom;
629 if ( bZoom ) {
630 makeMap( 2 * wImg , 2 * hImg );
631 resizeContents( wImg, hImg );
632 } else {
633 makeMap( drawableW, drawableH );
634 resizeContents( drawableW, drawableH );
635 }
636}
637
638void ZoneMap::slotIllum( bool setIllum )
639{
640 bIllum = !setIllum;
641 // make the map...
642 makeMap( pixCurr->width(), pixCurr->height() );
643 updateContents( 0, 0, wImg, hImg );
644}
645
646void ZoneMap::slotUpdate( void )
647{
648 // recalculate the light, most people will never see this,
649 // but it is good to be complete
650 makeMap ( pixCurr->width(), pixCurr->height() );
651 updateContents( contentsX(), contentsY(), drawableW, drawableH );
652}
653
654void ZoneMap::slotRedraw( void )
655{
656 // paint over that pesky city...
657 int x,
658 y;
659 if ( pRepaint ) {
660 pLast = 0;
661 zoneToWin(pRepaint->x(), pRepaint->y(), x, y);
662 updateContents( x - iCITYOFFSET, y - iCITYOFFSET, iCITYSIZE, iCITYSIZE);
663 pRepaint = 0;
664 }
665}
666
667void ZoneMap::changeClock( bool whichClock )
668{
669 ampm = whichClock;
670}
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 @@
1<!DOCTYPE CW><CW>
2<customwidgets>
3 <customwidget>
4 <class>ZoneMap</class>
5 <header location="local">zonemap.h</header>
6 <sizehint>
7 <width>200</width>
8 <height>200</height>
9 </sizehint>
10 <container>0</container>
11 <sizepolicy>
12 <hordata>1</hordata>
13 <verdata>1</verdata>
14 </sizepolicy>
15 <pixmap>
16 <data format="XPM.GZ" length="220836">789cc4bd59732acbb2adf97e7fc5b6936fc7cab87492d0433d8010926804089080b27ac88ebe134280b87fbe32638ce19a6beeb99add9d5a662ce6a7c88c708fc6c33d2232f9dffffdb761a7f5b7fffedfffebe3e01fe6e1dfc299bfffdb7f479febf5d7fff3fffedfffe77ffd57319bfd5b3ef9146e8ab77fcbffd7fff5bffe2b5efd2dfc9b974dfecb95525e44e2422ee5c9855ccc65533ebd8bf3b729875b7229ebd2a3a318d7cf3e8d5dfe5f6571dea5c7afe410f7af8bc6eefac9ad18f9357c31cacfdf890b906707ce65915fb83176f9f94731e4095a62c8f3f5252e3afdf7757291fa7d8a71bf7f12e3fe69c6d8c913293fd6cf639b4c7ddfa94f9ef2762e62dcdfa2fe7996ff1e93999fff2246f977ca8ff9d73be04216f537bf729cb40eda777c12177dd7fea1f8caf58fca1759fae87ab6e79331d26b1931dae3b224b3fd3eafc5b8fec8eb13fd5c7e777531d20f7b32f56d04c6eefa774f0c791e28bff47f8ac428ffebded85ddfbe88517fc505b8c0fef14efd0b6cef21f52d509e1af529b2fd9e8664b657be9272dadb6e02571f5532cb3b9fc5688f55518cfe57f900ab3f444b31eaf7ae29c6f5d32399fdd1ff2497907ff799ccf2a38e18e9770fc62effa78cf8caf58fa82dbe29a4bc2517285f6743667d753ec428ef93e517d47e9f625cdf1f8a91df23f52bb0fdb6bcbfc8f15a2f90d91ec7bab1cbefd5d99ba47766216fff815c447fbfb4c9ecafc1b318e9eb0199fdf5b417a3be465931eae775042eb03d8e1199fd79fb48a67efb3e99fa95a762e8b7db8a311e7b336357dedd0bb8c8fa3ffb648ea7cd5c8cfc8e2cbfc8fc87f7c6eefee731f88af662ccf2afae50bf634f8cf4418e7c8bf4b91b0f496f65fdeef364d6e7ec400ec1bb5bf1b5d32f5c830b6cdf55498cfa0eb262d46fdeae477d2c9be2926bef498e2cfbfc2a467ecd8bb1d3ffe5598cfade7e92695f170f62dc7ff4c490c7ff3276f21cb662c817eec9acff9aee677f6aec8cd1ff250fed41bd2c867ccd1e58e321781723bfcbabb1cb2f7b12633ce47c63679fe603b2fa6b20863eed2299f3fbfc057cc5f2f76fe42b8ce7f1907ccbfed42247485fa2fd6ef325b4d7eb52ec872e7f31f51d42bedb02e7abcbb318fd677c11431fbf452ea2fe665b31daa3d7155f3b1eb7c5a89fc998ccf17a1f89519fb58618f9573fc590d75f1abbfc1f4e62c8bb7e11df165d7ed287ed9fff12b37f493fd647e1d118e369042e72fcdec762dcffd03646ff7c27d3bf6bb4c4283f5714e3feac5dcff1bb13439f0af52fd29e6f2b62ce376763cc5f3d31fa6bffc518f3cf5a8cf2ee2c3fe87fdf21d37eeda53fc7d3b96aecd2fb3531f2ab2dc0eabfc7bc31fc939218f9ed8de91fde18bbfc3edfc8579cef5a62da8b1cf916e9eba518e9f7ec1fc9f8807da53cd7b7b0e74d967793a37d873dba2d91974e9f424ef351ee0e2c7b38fe22b3bdf22d31fafbfc22be75e36fb323b3fe274f628caffb1e59e373658cf1d414a33c7f61ecd2bf1ec5287fb314633cec299ffaebcbbd18e575dec5cccf23d3befb6731eba320863cab1732fbdf626fecda7f7d25a6fdd818bbfcfa1f62c8b31818bbf4e1b318f59fdd92d55f2f629457cd89515ed03486bd2a8b51de970f56ff3dec8c317e4a62e4df198b917f3f34c6789e8a39ffb1bca43fbbfbcbaf62e457dc88694f1662dcdf7e23df223dbb16a37e3e1fc811f27fa988391f37c490b799055fe738be57c6eefade0d99e3affa64ecd2eb7932e7a3cdd418f395f2e7f83c3e19bbfb47ecafd71c9fe399b1bbbf5e13e3fe11fbd74d0ee9a79e98f690fade50de25fa5f321f603c0c2fe2921b6fe793d8c77c31100791ab9f2999e3697c3476f767ba62f4c7cca331d2db62e437e1fd45cdaf6763d77e83b118e5f9cfc6c86f224679a33b63971e0562ccf7719dccf925c888517ef7c1d8a537d762d8ab7841e6f89decc4e86f8b9518f9554fc62e7d9b17439fe6bb18f2175ac64efed72b31ecd52514a37df60d32c7efaa20863ce70f31e4d9bd1a43de9298f659f2b3fd96185f361fe52fc6b0876b31c6636b650c7b722d46f95bb6b7c6f7c78d18f9750a62c853a1fec9fc85f58a8198f14f598cf20f4d63979f7f1053ffa5b14b2fb3fe641f4e2531e381ba31e2b7bd18e5bf9d8c919f2f663cb53576e9ef3931e429d8f590675704cbfebc1f8d5df9ef1331ca7fef1ba3bd59dfb24fb5b531fcc90731f22fb3bdae599f77436397df3dc7a3eccd7a21a6bdbf17633c3e4462f49f0ae54bec11e2c71b31eedf5d89517ed41523bfda1799fe7ef149ccf58dbc31e623d66f89f670332353df8cabcf624ef627d304cb5e3c8ec5811b5fc32199fe4bcb1343bfe1abb1bb7f742546fea3aa38bc725c3176e9f72a8ff6e1fc2986fe8b6731ed5bd118eb3d2d31ec43612b86fc930f31caafeb7ada87cd468cfed8ac18bbf4ee488cf2a3508cf21a0531ec6b9007cb1e043963f847cf629417978d31fe2331ed37e54fec03e6e32f31fd938cb1bbbf5210335e507eb4276fc6b09f31f595fda8768c5d7e4f9e18f9b5b3c6f02fba64da83cf8231c6f3b598f2b68c311f283fda83d39331fc61e6277b305b8b51defad618f3d94e8cf2f63d6397fe7625467945df18fad4c8b4cff3be98f167c918f1f1b598eb056d63a46fc5282f627b5f331e69f48c5d798d8a18e50d76c698af2c1de5ad2363ac8f497edaa7ea8d18f9dd53be1bd667361623fd301263becfefc4e82ff7d447f627ba1323bfe154ccf9a16f0cfff54b8cf19d3f8b31be6ab44f37f40feb0f62caa7f26e717dd113633c360332ed75f1d118fea5f4e3fcd6b812737e57fd44187ffb15b844fbfd702346fd36698f4ab4bf8f0531e793580c799f395e4b6cffe1814cffb6037bebcb3f5a6ec8f44f964731f25b3c8961ef6a2fe02bfa8b8b9698eb757563a7dfa426e6fac84c8cf6def68c5d7f187d91d9dfb77d63f43f4f8cf2efb3c6aebcbedd8ff2e67931cafbb4fc505e7b4d66ff6e9dc418af7e594cff2d678cf9f355ccfabf18bbf4fa500c79a662daaf73490c7d1f3bc6981f76628ceffed918f6682ca6fdcd19a3ff5b79d0dfbf13a33dc377b0ec59e7468cf28e6b6357de692b46799f763debdfae67bcc3fa90bd9b94c4286fd33346fb0ec528fffdda18feeebd18e53f7d89d19ef94f32edd97e2c4679ab9331e64bc9c3f9e7e1da18f347284679bb8db1d3efae4066fb859fc6eefefc8b98f7bf1bbbfb3f31bff8b297f1b3b1abafaf8398fee83763fe7c12a3bc6345cc78ef468cf243d687fcb946284679fba198eb612731f4eb7a62e47fe6f8be617cfdd21353fe6b31d7ff2231e47d91fcb497cf6f625cfffc29c6f54ddaa712ebeb6e45e6fcf034216b3e72ed7b95bfca46ce3f1b3f92af30ff4c3ec5180fab5bb2e297ba98f62663ecda6fd613737e991bbbf481e587f13f691bbbf25f2f62c69b2f62f8b7f72199e37d267dd87fee3d31caef67c52caf2c46fe830fb0c6737d2ea63f1c8b915faf600c7bd71523bfcb82ccf1bb50feec1ff74fc6b0af0731eab3f3cd287f2d66f9ef6294b710733c4f8bc6589fef8b693f32c62ebdf12a46f92bc9cbf63b7e193b797a3b31fd7fc9cbf60a57648effcac518e3b322a63f3e32c6fee4b318f21c0ec6aefc4a550cf9ea963fe4c9bf8961ff2e1bf00dedf9dda331da672ce6fa69d618fed3a718f294236327cff3448cfac90fc428ffb545a6fdd8dc88399fdf19c3ded7c590e775658c78632ae6fa54d718f1a49547ff91f5237fae5531c6fef78b18f2bcbd19633e6e8821cf8be507791eefc5ac9fa5b19327d713a37e3e9b64dab353518cf29f7d63d847c9c3fef261d7a3fc07f61ff9877151ccfaa47eb2879db5b1bbbefd24863c837731e43952bf12ebeb59e5d1dfafefc448af703cdd529ea1f34fae7cad5f16cac6ae3e4e186fbef63b1f037211e943d8b3c45f427f1aeec488e7c71531ec793e43a63f1d6fc48c9f4762d8f75cde18f6f54d8cf8fdb162ecd26b4d31e70f8c8fc4bf613c70670c79d762f4c76a568cfca65762e4b76a18c729cf7d32c747b32c467dd6d7c6580ff2c4b00f87a118f2bd3e1b637c7e89215f6360ecd2572331ea672ef9af503f8b83b14b7fb1f220ff94f529fb3b51791c1fd5400c793b4fc6586f517dd2debec6c64ebeeaad18f29f25cf2de4dbb2fd656fcf7b63579fd38b18f5592d1ba37f1ec5902f181a23fd2c867cedb1b1936f9f11a3fe16ecbfb2bf93be98f1455b0c796adfeccadbedc59067766decd2975762c8336b183b79165f62b4effb8d18e321df3376f2166a62d4e794fac97eafbac6384f9017a3be1f8bc6f0bf6fc5d0efc3eea77e6731fb6fce18fed38318fab50231f4c95afe90f7783176fa5ceec9b467ad500cf94fb118f25feac6f08f3ec4dcdf8c8ce1afa83cf6e77ad3d8a537d47eecaf5bbb9ff3b5da8ffedef3540c7d6a4b32e7878bca63ff8e9ac68857aa62c81b6c8c317fcfc45c5fb5eb59df9f62d477e5510c793fd93f35ff349ec5a8dfed9798f349410c799f6f8de1ff0762c8fb7e67ece4f9b0fb216f8efa6bfde36d2846799ff7c6f0bfea6294ffd533c67e41438cf21a2f64add75f89e9bfb48cd13fec7afa9b4d63cce7b4a725b6d733ede92ded418de3f196fa3429ef2de7dbb9f3afaff3852cc67324e67e593e47e67ed5b04fe6fc5bb936c67ac42bb8c8fc864d32e7df684fe67a75b56a0c7fae2fc6f54103acf5a071991c613e58eec08a2fee1fc5b03ff737c6aeffe70662f4ffea511cbbfcf20fe2c9b52b4fd7737eabf5c4a88fe9b5b14bbfbf13a3fc59d7d8951f4dc5283f776becd2979118f3f773ded8c937d88863275fa6638c742b1ff2df0764da8ffb9131fcc95731c6e36665ecf479cc89a1effcc9d8a5676a62e85bb5fca16f752886beed8131fc15b517fdad85c90b7ddf2c7fe8b3527bd2de743c31f45b3d1bbb742f2b867ee7576327ffb42a66bcd93746ff95fef4efbc0f63277fe524a6ff3213439fb7a618ed3565fd68be1e5dc45c6f2b88b9fe7934c6f9bba998fe83e5477d8b62e8eb5d1bc3ffda8ba16ffbddd8a57b563ef4dbc762b457ff534cfdd85e9a8fe32731e5df1a3bf9b6c6943f3276e987ba98f1f0c2d8c9773c8bb9defa620c7fe44d8cf6f237c64efe9631daaba8fae0785bdc1abbfe77c7fea0f97c951743df554f0c7d2f0d63a74fa8f6e0f87b2f19bbf4aeda93e3efd9ee87be33d5a7e6f7b531faaf950ffdcaa198facd8c5dfa4cf5cbf1f6207d38ff871f629eb72d18bbf4f9ab98ed7b3676faac3b62e8bbfd6697feaefae578dc59799c6fd43e1c7f0f8f62fa2fea8f1c6faf596397fe3e16a3fdb607b0fc85cb5c0cfd5a37c6380f711443bf46c318e7453fc4d0efe3d518f6a82b867eef5963a74f6e21467be6fa62e8f769d7737e90fc5adfb81863fd50d7d3ff58bd1a63bff045ccf3f8beb193b75516733fe69b5dfa5b550c7dc61b31c6d785fd53fe4aa323863c77256397fe2179395e1eed7ec6e7d762947fbc13a33fbc7c8a517ef662ecea6f7345667f0ed49e8ad7dac658ef903eeccf7ecfd895ff247dd87f2f0531db8ff2dc72fd7c743086ff7f25e6f996b331d6d32d9dfbd33563eccf64c4f4b7585fb73a5f3711f3fccede18e70b8b62e49fa3fdbde5fa79c513f37986b998ebf10b63f8a32a8fedfbccf6b9657d6f385e7dfa9bf74d63975e647f0af2e0bcf3a7affd02cf1fe4eb62b4ef06f2fa3a1ff6be10a33f0e46c6eefece5c8cf6293f91b9df38ee8bb91fb8045ff13c5a2f4fe67c7d0f797df98ff70531c6e77d8dccf965f22246baf765ecd2dfd662d8dfcc590cff2df32186bff3726b3c71f989393fdc17c55c7ff78de19f3d8b519f998531cecf2cc590d77f3086be5762c85bf58c9dbcf70331fdd19d31f4998ba18f7767ecf499bd91391f9c6ac638af771143bfcc9331f48bc4d4cf37867fa6fae57c31088ca15f570cfdee87c64efed5b598fa79c6d0cfe4837ebec90ffd0eb027b65fd6bd16a33f7a2531f48fdf8db19ee68ba17fab6decd2cf4731fdd3d818f14e530cfd5b9fc6a89f8d18fa2f4363c457961ff5bf3346bc712586fe01fbaffcbfd6d118e7117262faeb1563f8af7931fdf5a1319ef7b0eb511fc1ab31fc5be9cbf969723676fa7a563ec7e79531d26fc4a88fc9bdb1d3b75f15a33e9acfc6f037381ee40f7edd183bfda696cef3753963f817d28ffea0bf3676fa15240fc7fb7a2786bee599b1d3e7a8f6e4f85ecc8d5d7a57f5cbf9f0291043fee3d218fb731d31e4df378da1df8b18f247cfc64efeca560cf93f4263a4ab7f713c1f8fc658efec8ba1cf8767ecd2fd9518ed377b3446fb487f8ee715f591bf57a918c35fbd1243dfa7ac31d6e75ec5d0775b3476fa743fc4dc7fb5fb793e2410439fd5d8d8e9f33115d35fbf3776faecd87ef20f271b63cce77d31cfcf7e33d68f5a62ae9f8e8ce1efa83eb47e1a19bbf4e68b18fa772fc6b05f763ff47fde8bd19e6f0731f47ffb32c67a7153cc788cfd49fee649f547ff72a3fae3f88bdf8c115f4ec4d0c7df1a63bd6925863e8f9eb1d3677c27a63e2763977e772b46ff7d793476fabcaa7d381ebb0563d863da07f35f553f1c9fb1a543bfbb8bb1937fa3fec8f179ae18c39f55ffe1f8fcb2fce83fa97d383ef3ea2f1c6f35d68ffcd5cec9d8c9b7bc1143bef3c418e3e9494cfb5733c6f9db0f31e45b5b79a8cf915d8ffaacefc590ef8ef3abfcdffd42ccf3465d639c3f398a21eff3bd31e21fc9c3feff7230c679a48a18f595b5fb21efa3e4a37f1d5f89215f762a66bc5d35c67e82ca677feede18633ea57dbee57e6f2332c6fea9e461fcd3fa32463ca6fcd99f3a7d31e3db9d18fdfb8bf6d3677cf37225663c7a234679839931d6a375bdcff3596c4f3fe6fe09fdcf20cfe78356c6989fdec53cff4afd826bdc7f6c8a717f3143f6915ea07d0e59de4b4bccf354ae7fde140a3c6f1dafc18a27c64fc6f037b6e422c74b955cc2787a3883751ed1cf80e54f67b662aed7de1b3bffb1f946e678ed1e8d5dfebe27e67eb05d4f7ff8da18fefe49ccf82527a6ffdb37867ffb29867fe33d8821efee60ece49de4c15acfdcecc5a8af7d470c79b63531e41996c590a7d617331e7b3576f254c762c893b7fc204ffb83ccf968198821cf6c24467d457363c407d762c837793446fa8b18f5e54562c6074331e5b3fb21dfb04ed6788fc5b4975331c6e340f9717eda958c31df16c4e80fcb6fc6faa8cae7fc346f183b7d1ed43e9c9fc6563ef4cde5c45c2ff5c5689f8f8998faf5c85a9fff32c6faa8e467ff5e6d8ce11fa97ed9bf7b4363e823f9d8df3b3b63ac5fcfc4d027affa657fafd8f5907fdd1543fe39e5977f383b8ab91eb13176fa7c3d89793eae25e6fec2de18fb495931e47f3a18637ff924a6bf1b19c33ffa14439f4f9307fdb17511a33f76696fe4efc58fc6f0df953fe7b7695f0c7d1e0ac6183f4531d7a7afc41ccf763de48bdec99cef9e0ac6d8ef577d71be9b0cc5dc2f981863bdf54e4c7f6d61ece42babbd381e4e5fc6e83f963fe47d2919e3fc89e50ff91bba5ee7eb1ec47c1e73618cfd8e9198f1d2d118ebe5ea2fecffadb3b193afaff2b5deb833c6f904e9c3fe9d7d31c67e00eb53eb8db97b31f72ffa62c8bb7a1343dec7a1b14b1f5f8bd91f2c1df2be5bfe90b7f821e6fafd4accf5ed8918f53ba81bc3beb37ee5af2d6a62eee75b3ae41f7c89e9bf2c8d719ee9564cfbb936c6fa63560cf99fba62c87f67ccf5b29d31f42b88a1cf59f9b1bfc73d63f82b1d31cfbb4f8cd17f6231cfdf968db17f24fdb47ffb4c66ffdc287ff6cf8f6fc6790dbb9efeed8731ce178ec5c8ff692666fd70be97ff1766c55c6f7f34c6fc66ccf78b648c711ea32c863c5f9c6fb47efc5917c3bf8bee8d71bef241ccf39e7b63f8bb5b31cba7bfe6d33f0c5fc5c87fd43386ff6ad723ff5a854c7ff2fe5dccf74f7c1843be404c79289fd6c3bfc662dc5f8b8de15fefc4287f78678cf579b667e20fe3bcffad31e45b8af93c41608cf66988f93c23fb8bfce78bf263fdb4aac6b0dfecff01eba3bd11f33c6ac518f549f943ca538bc4283f5b15a3bd5e381f862cff79610cfdd9bef2efebf762e6ff6e8cf3a9b48f11ebbfb210b3fd56c6d8bfa07f1851de16fc9f40cf671e2e64ee2fcc72623e3f9a3776f622467b047a9e69d41463bc953b628cb7d950cc78b860ecf2fbba8839ff62fe09142f54f262fa53960e7977a8ef40e709ca1731f79b3d31cfd754c4f0979edec8b4bf5f0d31ca3f18339e2a1abbf4412ca63e2732edddf051ccf3634363777f3d2b46feaba918f22e3d63f857be18f3cda22386bfd46b8ba15f7541a6bdcc758db11e3013f3f9b01b31fb83e4a3bfbafc3476f2b4fb62f6976b63977eda8921df51f5c3786cd43176f2be515ef9a7872731fdb78198fd2b2fe6fa6b60ecca5f5dc4906f5e1073bdfc5dccf5d59d31d6cf7362c8b7bb27eb794a95cffe135e8b21efae25e6f31a7563f81f2b31e47fed1863fdf8538cfa0c6fc43c7f3d31c6f923e9cbf57edfca833ecf3532e7ebd3544c7f6f6e0c7ffa20a6ffd13676f2bf8562aeefbf19c31fb4fcb9be5830c6f987ad98e795d51ef45ff77b63277f4ef5c3fe5e3079d09f9aca9ffec2e224867e6f5d63ac2f8ec4d4cfd2795e58fd91f667d234c67a86ea8be3e1f52c663c7a30c679fdaa98e7e54ac64e9ff64c8cf67b817f1ce879829d31f73b1662e8170f8dd1bef762e8f7b932c6f3f33331edeb9731d68f6fc568bf879a31f4198b19af8e8c11cf9ec4d0275b3476fa76389eb5de59e889b91f1719e3f9b28c98fef2ad319eafec8b391f7d33eced9d98fbed8131e2938e98fa9a7cd0efa966ecf46be4c41c8f961ff43d5f91e94f8f545ff49f0b96cef3a85531cf23d9f5d06f751043bfdec018eda9fea0f5feb531da53fd81e36f581243bffeab18f27faa3ef4bc56cb18cfd77c8a795ebf680cfb3111733faa678c7840fd8fe3ef2536867d947e1c6f4f8f62c8fb7a30c6fac2458cf668523f9fef276a5e89b9df742366fc712de679b1ac31e20bcb8feb4347633c7fd015f3bcc7ded8c9dfea8bb9feee89a1cf82eda378e0f0628cfd154be7f9fb9231f683a40fc7c7a0608cfa0ec55c9f957e1c0f3dda6bc513355dcff8615331863c65319fa7bd18bbf2da6731e469f58c71fe99f3ade28f42648cf85ff2c58c1f1e8cb17f732be6f382cf623ebf583576e5bdb27cc52f8d1b31e38bbe31e2b72731df57f2688cfe5315335e7d37863ffa4156bcf0698cfe561723fffdab31e29f9698fbf3b4ef8a67ee1bc688873a62be8f6426c6fd7bda03c5371fe490fad5ee8df1bcdbbb98ef8bca19633f55d753bffbbd31e2a5a998cf9b4ec45c7f3266feac0fc54be76763777ff54acce7693f8db1df62d723bf06fd03c557e79698ed7130467d6fc49c8ff262eeb7b3be156fd53e8ca1ef59ccfae4f850fc1586c6e8bfae7e4b05bdef21f0c08a5f66af62cc47ad67639c8fbd256bfcbe8879bee2ced85d9f3f92399f94951fe78fe1580c7b34a819e37c7c48a67d7edb8a517e67224679870fb09d2f35c6f587d818fb1d2b31e46f54c590a77b25867ddf505fadff56e7629e4f6e89b9dfb51723ffb7ba31e2ab408cf25a3531e6c3b7bc31d6a7253ff74b961963172f2cd97ef2b7834f31df0ffb24e6f37d2531e47da919239eb574eefff8c638cf771043fe51d9d8a50feec58c7f4ec64e9f99da87f3ffbc6a8cf8c2ca837ef91b32e7fba331f4db14c43c8fa0fa627f99178db1fe5d1143bffec518e72f4662e8d7537b73be5f34c4907ffccd4efef2408cf67a0e8d9d3e5f6c7fad3f9f2662e853be32c6fac7548cf61b6e8c11ff95c5d07763f943df7a45ccfdf76b63ec6ff5c43c8f69e5419fd149cce77f3ac64e9f40f2d21fd8dd1943fe9c98effb8bc48c577bc6d81f2e8ab91f373286ff3513a37d0ab131d2f762b4d7e3c0d8e9f3d21733fe3e88a15f2cf9399e9aba9ee3691e1be3f993b618fa2d6bc6787e6f2ba6fddc1b63fd49edcff1f6fc688cf36a9f62e89b0b8cb1befe2586beaf3b638ca7b318fdf5f4608cf1d81443ff3ec797fce9eacc18cf47a93de84f6faf8d11afbe8b799ead668cfa507fd07a4fdb18e7fdd55e1c7f4f1fc68827d47f381e2fea2f1c8f17bb1ffa4d694fe57fc75531e6db75cd18cfb3f7c55c6f3919237e1a88a1ff62648cf67c10f379efb5b14b0f8f62e897ad1b3bfd1e8dd17e4dda0f9fef17f8ba15439faae4a5bffed236c67eb2f4e7f8dc9c8d713e6a28e6f922c9cbf1f9b61743beec9d98eb27d762c6a3eceff2d78307639c9f1b8be93ff78db1dfa1fc7dcee779639cf75c89f9fe09da2bf9eff5c018fea0e493ff9e37c6fa4543ccf79f548db17fd613f3f9ab2f633c1fcff947fefa7d5dcc78b5668c78a522467997a1b14b2f1cc5b4f71cfff2e7ab5b31cffb948d319f34c5283f9b35c6f87d17f37d6b6c1ff9f3e19398fb892f62be6f47e5b33eabaccf90fa9ee7c6789e6626e6f9b6b531dabb22c678a8b17f87d4ef60ccf5a8d818fb811331df8f427f28647f7bac8939bfd27f927f1ef68c71fee95dcce743a98ffceff642ccf7b7b9fd8a52a0f3451bdc1fc83f1e3c9275fe64648ce72d9ec57c1ff14a8cfa9864c95adf288a917f1018c3ffd6fdb49f6d95cff5bf9c31c66b07f565ebe1cb3b31d7bf6fc4f41f66c6785f8531fdc18631de173a27737e3f0cc4cc6f698cf52e4f8cfc56763ffc8dbad2391f6f32629e2fae89f9bee7b131fc8b4f31caeb34c5286f3c32867fa4f2395f5eec7aca5322b37dc62b31c66f363486bdb888198f497fb6e7d7560c790e960e795ea50fe7bfc6464c7ffa564c7fe6cbd8c9ebb3ffc89f6c8e8cd13e7d31ea2fca1863bd7d2e86bc77964e7fb22b86fcfb6f467d6fc53c8fb316733ddaf2633cf029863ee5b631eadf27eb7d026731f777242fe7b7c137231ecc89393eed7ee83ba988a16ffc618c78a82a86bef3b131c6474d8cf60a4c5ee8f7a0fa60ff8ed83fe46f6627c6983fca62be7fe44b4c7fe3c118f19cea9ffe656e6f8cf5f3500cf9dfe6c6388f782f86fcbd3b63c4a7d29fe3a37d10a3bd06d7c64ebf91cae378e9aabe395e96556327ff7625867e95a3319e7f91fe1c3fdb9cb193bfa7fae6782a4c8cb1ffb511733dd7e4e1f3114331fa676f6decd2d74d31f47db574e85b833f60ebbb8f5331f43d6cc4d0e7b41473fee81ac33fce8b39be26c62e7db71073ff676bece41d5e89a1cf283076e9679397ed773176fae458df7a9e31ae89e94fe78c111f8562ae47583adaf743e5697ec88aa9ffca18fdd5cae77ec2c218cfef34c5d03fdb30463cabfaa4bfda36f9a0fff84d0cfd1f383fcb3f1d3d89217f311673bda9688cf5abb298f6236b8cfd6d4fcce739d87ffc98bf679611733dfc51ccfdc6a398fb350d63945f11f3fc59688cfec6f2e5bf6e2e62fa8747639cff7f1573be6d88f9fe848918fa9d387ee48fb69ac6781f512046790f96cef30da118faf5b7c6aefc665eccf541da8f40fb03928fed776c8b39ff293fd66fdf17e3feb3ea87f5fdd531c6f3b14f62e4978bc4b4c7ec6f5aef6ecdc57c7f6b20e6f83889b95feb8b31fe5ee95fca3f3e3d8bf93c84f267fd0d9662e4f7bc11f379da1d99f5957d12b3fdbf8cf1bc9be465bc753f11b37d551eeb2bbc33c6fe16fb83fce726db27627fb8e37c1fb37e3a6e3cde16e52f2fe762eeef2fc5d0ef6cd743bfd62b59fe7153ccf5e7ac18f662f8cdf03f1a62aecf7a60f9bbbd8a98f1fa8cacf76d348d619fc662dcef378c315fe5c428af51236b3ff545ccf5ea9398e7b32764ce978d92319e57d98b215f253486bf321423ff75460c791e7c31ca7b88c15aaffc5a89b91e9215439ed1d018f67e2c863c9f7363f8934731d74b06c658ef33e6796a9307f24691b16b9f49474cfff864ecf439e97afa831f4363f43fddaff7d72e8d61cf7762fa83d287f351e55dcce7876f8c9d7cf1590cf9a29931d68f3fc9f4ffbeeac6587fbb16f3f99a92b14bdfa8bee80ff626c6882f9a62c8ffe219233d23e6f3d1763ffa7f640cfd661563ac37aafef4fc7bcb18cf47287fae371e8b62be5ff2de18f19cf4637fefbe1a23be7a11b33d1e8de1ff493f8efff597b19377ef8ba9cfb331e6eb8618fa6c3e8d713e8ef561e7779fc5d0a77830863e6b31f4799f1be3f9aaa198fed1d118f173530c7d77df8cf78184623e0fdc3276fa546231c77bd618f391c9cff74fcd8c9dbead2959cf47bc89b9df9635863f178919efbe1a23feb0fb21effbc818fef7bb98fb317363bcdf53fa69ffec9b9dbc15b6afd6232b3d31d71f5bc6381f22fde8ef6d3c6397be1e8bb99eff6a0c7f2827a67db5f2b9be2a7d7daeaf9e8d118fa8be7dc6cb260ff46d5afed0b7fb62ecf49d2a9dfe4db41543ffb6fa0bfd99f6a731f4bf88a16fe1430c7d3f06c64e9fb5e50f7ddfdf8c5dfad3b518fa764ac6d89f517f8ba1df52fac7d0afd33086fdee83b5de5a3988b9de3c33c6f3266531d7977762b46fff680c7f371073fdc3eee77ad242ccf8ecca18e99f62e87b588979fe93fd47fe70bf24867ca78298cf371e8cb11f581733dec81ba37f49de6bc85357f9d78c7fd91e818ff3808357319f8fea8a79de666b8cf8f646ccfda192b193afa1f2385efa6a2f8e97fabb31ce83d37e6abd395b33463cb214f3798d9118e58fde8d713e4af2d03fafb0bee47f3f648ce1af9ec5f4ef3d63bcbfea24e6fb66be19cfbf733cc83f6fbd1be3bcd0a398fb6d0d63c407763dca0fa99ffcf5a6e4657b14cec6580fa37d0819df148df97e9f9298bfc7447b2cfffc4bccfd85c1404cff9dfd39a23c0f185fa1fce543d918eb0f4f628cdf21ec4128ff39b317d33faa1823bd21a6ff60e9183fbd1e99f3c7ebad98fe7dcb18f94dc52c2f30c6fad6418cf2326b63d853ea277f3c3716a3bcc2dc18e53d88595ed518eba10532fd995d478cf11084629477f934c6fc7e14a3fce3abb1cb3ffb2846f979cb9fcfe3327ff9e38da2319eff9b88b95ed83346fcf221a67ff86c8c78aa20e6797d5f8cf2f76d63f84fca8ffef7e39598f6e2cdd895bf1c8a195f05c6787ee241ccf7994b3eb6ffd38bb1936f9317b3bf9d8cd1fe3b32fdeb93ea8ffef5e7cc18f567e990afbc30c6fb764662d6572c867cdebd31fa534e4cf9d6c64ebef53599fe74f54b4cff782be6798b37633cdf501533de8d8d31bf1fc4a8cfd1c018fbef0d31fb7bd118cf877b628eaf8231ceffb0bee52f57c662c667df8cf86621e6f3cf45638c9fb598f1c08331cebb95c5d0675a3746fcb213b33d4263b4475f4c7d4c3ee8d3d1f53a1ffb658cf5d02b31dfe73935c67a5e5b4cffea534c7ff26c0c7deec4d0e7c337c6f33d5d319fe79818bb743f12b37f1d8c9d3e47da57f9c72fba9efef13c23467b1446629e477e31c6fb8aaa62cafb600c79541ff47f5775638c57c947ffd7eb193b7937aa3ffa07e3a531fc13e943ffe0e1c518f62716d3df0d8c315e9ec4dccfce19e3fd458f62bebfe8c118f1a6fa6b0cfdba763df4dbcdc4d4cfe4837e31e593ff7bbc1643dfeabd98cf4f3f18637da321e6feec8bb193bf781643bffac118fe6557cce715d6c6881f4d3eee3f583adf376df9f17d1a2763d833da07ad0f3f491efa47e5b531cefb3d8ae99f558da1afa573ffd5f283bee73b31f4edd48da16f45ccfeda13f3fc5fc7d8c9df7d27d35f9b6e8d619f55dff49fab0363f4cf4f31cff7fbc6783f84da53e3ad610c7b118ab99ef62146fb4cd45fe80f9e6762c873dc18431eb50fc7cb73d718f3a1f4e7786959fe3cbfcbfce56f9727629457b7743effbf14f379afbdb1cbaf45fb2f7ffa5015f37d8a96cef7694cc53c0fbd22b37d7aafc6389ff324a6bdbb21b3be0a2731f72b32c68807d8bfe45f577762969715f3fd87ac2fad8f5796629e47a4bf27ffbb9d1323bd497b16317eda71bed5fa7ac1d58f5fb4f7ede48db11e1790393f7befc62ebd7f05d6fb681ecbc698df7d31d78beec89cbf86b762beefa0640cffe1468cfc875b63bc6ff3410c79f6cf64bdaf53f2d01fef47c6789f654bccf5f63199fe4ea56c8cf396ba9ffaafce609d87290cc57c7ea82ba63fbe3286bf7010d37f7817d37fb0eb595e9bacf3f65b31f7038ac638cf3b10d31fff3046792d31fdb3d018e93331e5d918633f4ae5ebf735243ffddbdec218f654f2b03d5eb2c628af2ea63cb131d2cb62caf365ece469a87cfab7f54f31eaebe9410cf9366b63973eb5fbe9ffdd19bbf21f553ff267ef8d11df4a1e8e97b79d31ce033c81ed7d230331e46d2cc5b06fedae31f6178e629e8fad1a43fe7b31e40dda623e6fa7ebe95f5ecec6382ff229e6f9f88231e2bbb118e51f1f8c117f5dc48cafe662beefbf668ce7338d694f3cb27e6fe856ccf7010d8c11df5f8b21cf3434c67aeb49ccf3e09131d68f1b62aea7aa3e144f7db393ef8ef651cf274e46629e2f53fb319e3a6d8cf1be949d98ed171ac37e4cc5f49f5e8c313fefc58c3f86c6b0b76a5fc5535963f84f64c54beb4731e47ddf8921dfe3a731ce279fc57cff71c618fef9bd98e3e3cd18e3f7454cf946c64ebe90edabf799ec6b62fe3e4a57ccf8efda18f19fca63ff6dc6c6b0877762ae0f748c715eb12de67a68d518f56bf9b3fe0363e8f72aa67e2563a75f41f5457fad2179e8afbdd78d319ea41ffdb5d69331e2d9b998f6aa6d8cf9d3ae67bc5433467a53ccfede31c679348e0fc547a3ad98fe5edf18cfd3aa3fd1dfeb748ce12f1fc45c1fff30c6fa554eccfda97b63c4df7b31edc9b331e2a78218fa4c7d63a74f96f5a5f5fee24accf32bf7c6f00fbfc47cbfc8de18fef449ccf3aa763fcf67f68d616f3c31dfaf66f951fe400cf91f8fc64efe33eb47f14f6d28e6ef53de1a23fe298a793e66668cf6cc88b99ffd608cf315963ff7aff7c6680fbb1efa0cac3ce8737813733d8ff657f14b7d6a8cf396af62ce3f6d31d717d55eecef03d527fb77376fecca7fb5f2e8cfd27e28beb95b1ac37fbe11d39fd989b99eb710d31fac8bd15e05bb9ff11ec75fc8f3e34d63febef49b319eef2c89f97cd146cc78a029e6f319b7c64ede1ae5d5f9a0afac98f19cca677f795c1b637faf2de6fb0aaec45c0fce1be33c8be4e5fb906a2731ec7753f2f2f982e151ccf3d2ef62c6473762ee7f5b3a7fef94f383bdaf742be6fb878ac678beda13f33cedd818cf4394c5dcdf9919bbf2ce3d31e4b9b3fcb97fa5faa43d7bb2fcd11f8ab4ef7a9fd2e5460c799f76c62e7d3a17f3f7cd7bc678bfedbd98f16cdd18cf1755c47cff84678c789cf389e2c7e6c018cf8f9ec58c5ff3c6eefe5e53ccfa9818c35eb2ff446cffc154ccf78744c678fe48f971bde3f322a6ff477b1eb33e5a77c638dfdd11f3f94fdaa398f2b795cefdcbf2ad31f6df0231fb23db2366bcfc7c34c6fbfe7c31ebef608ce79b38de268aafdfc4bc9ef74ff4feae9531ceeb35c5bcde3346f9b48f13ca5f30e6fea7f29ff079ab9c98cfb340ff50ef73babb17f33ce097b1b35ff73e99fea83716c3de2e2d9defcb7916733f0ee3c5f6f75ef362dcbf681be3fcc29798cf23b23cc5b3c19b98e7797d31f29b6cc9fa3d9c9d18f71f0762c6035d63c46f924fe7d5593f8a1f3b67319f17d91be3bcca8398e7350a62c8f7fa668cf5ce8698ef179a18bbf2df597f8af73e32c68827dec5d0a75c36c679e6ba98eb335963c45f961fcfafbf92b5df3612f37cfd8db12bbf2ff9e84f3f2c8c11afeec5906f7e67ecca1f3c8bd99f0ec638bf23f9e94f3ff6c97c5fe4a824e6fbb90ec6989f743fe3c359418cf20f1531e3bf3763b48fea57f160c3d8b5cfe72799fbb52f4b31f707aac638cf2879f47c4f688cf30eaa2ff69f782766fd7c19e379a40f31cf37158df1be6cacefd8fe58211443be6e648ce7f73362b6e7d418ed792de67a52de18fbd76f62c85bf5c5acbfb231d6433664bd7ffe51cce7b7be19fb952531fd918c31d6974662aeeff8c62ebd1288b93fdf37c6fef88398fb61a131d67fa4aff6c376c6389fc9fea4f363eb9e18fa3caec4fc7dc8b331f6a76b62c81fc4c62e3d527bd2ff3d3d1ae3bc9431cfc37d18c31e75c5fc7d9a8131cec3a97ee9ef7cbd8a19efb4c5f4776ec490a7db3386bd57ff617c7627fde81f051d63acff90edfc55dd18f1fd488cfadb4f8d113f66c5dcdfe81ba37e8d21ef9d95c7f5b19e31eaeb45ccf67e36c67933f62fc55b5f6f629edf7832c6f9a39c18f21f8ec688b76a629e2751f98cbf72a131de673016f3bca631df7fb833c6ef2f713eb3fda64731f757a4bf9e67991a43bfae98eb5b9fc658bf5a8b51dff99918f296ed7e3eff7627e6f9f51399fef84bd918ed6fcce7f54ac6587fa888b9dfa4fec0fe5a5f1ac35eb07e159f15dfc5b047b92b31fdc9bab12beffe590c790a5963d8db9218f28c2d3feee7d29ee8bc57f42ae6fedfbb31fcf7ae98bf7f75658cf72b2cc55caf647f533c767732c6f3ea07317f0f6f2de6f3b54fc64ebee2a798cfa7d78c112f4662ae2f778db11e6fe95c9f933c8ce79e1a62beef696d8cf761cdc494f72c86bca79531f6bf2d3fc8d31c1ae3f904b53fedd13de7577bffd2de18f1ed45ccdf5f3f8879be7b648cf1d514f3f7bb1662be0fa4668cfeb21473ffdde4e1fbc22d9dfb3d9c3ff5fea7fb85317eeff043ccf71d0cc4fcfdf42b633c3f5f12f37c4ad918e74b252ffbdfe7c118f1f944cce74bde8ce13f4fc5a8ef06e7b788eb07c38a18f23c7b62c8f3b132863f7027e679d8ba31c64b5b4c7f4cf5a5fe726b8cf77b583a9f0fab19637da42fe6fa2dfb83e2d37ad118e7333b629e876d1ae3fce852ccfeb011d39f65f931dbe7a52be6fe78db18e7874e62fe3e796c8cf50cce1f8a77c317639cdfe578517cbbdf1ae37ce75eccfef126667958bf0827dcdf9ecc8cd1ffca62e4bfec1ba3bd1fc47cbe85f5a97879ba34c6fad8a718f9cda6c6887f55bed603743fd703661363bcff7321667e33633c9f26fdd81f1bdf8cfe217926983f1e4b62fede6cdd18cf4b15c43c9f3e32c679887731cabb3b1abbf216ceff0d6cff785e22eb79d66731c6dbe4c118fbb74532e39f45d3d8dddfd88ab93f7345e67ac0e39d18e9830358f1e87320e6f33f6732fdf3c6d118cf83e87efae7ed480cf97bcfc6aebce71b32e3bb8f7b319f27f0c53c6fd412f3bc94aee77ede712ee67ee39db193ef521673ff682fe67e45df18feaf31dfcf60e5a13e56ef62fa974fc6d82f62fd295e0b0fc64e9edc8718e5ef56c6f02fbec4287f773146bcd012a3fc304766fc55d4f58cb7b237c688072c1dedf7f92ae6fb02fac638ff7525e6fb7aad3cbedf616e8cfd27e94bff32927e8c8f1e2ac678fefd59ccf8f4648cfd979198eb213b633cff64e990675e36c67a96da83f1d04ee5d39fdca97e180fd547c6e8ffd29ffb57fd8d31ce2faa3d190f45944ff1d0bc23e6fb270662c6bb2763ec7f67c53c9ff6628c78f7594c7b5113f3bc6a9bccf97bf726e6f3b313639c6fb474beef626a8cf3cc2b31f4cf1d8d5dfa93a5f3bc26fbafe28dc6a398f1d1ca18e7c90a629ef7d91ba3fc8c18f997d9ff144f043563f8174f62f6ff8231d6dfb662c6173d63ecdf8ec57c9fc09731e247f617c51bef6731d7efaf8d317f8fc57c7ef3cd18fee15cccfdc84f63f85fcf62ae5f35c87cbe23ea89591f5563577e47f2d0bf9b9d8c51fe8798ef635889196f537f7bbfead118fe5f47ccf7b5a83ee8df95df8c71de6222e67a56cb18f1e7528cfac8978d717ea42d46ffa8df8ab9fe3d2333dea8168df1fb2496cef743c462fa677d6327efbe22e6f3472b63d4ef9518f215d91f157fb47662c8f3762de6fb12f662ee67d9fd7c1fc4a398bfbffa648cfabc88f9fca295c7e7171662c85763fd47dc6f6ccc8c9dbc075fccfde858ccfddd7b31cfcb558d317eea628c9f3ac78be281a7ad31ce63aa3e743eb6690cfd1a62949f2f18bbf29a5d31df17630cfb74e27c14b1fdb65363f8f39297f662f46a8cf527fa138a0fea2731cf2f178c112f1fc58cf7bbc658efb0ebb99ec8feaff860d03746fc168ab9be736d8cfdee8998eb6b9c5f141ff46ec57c1ead618cfd5be9c7fa5f79c6b0a7763f9f57667f52bc31681bbbf2de252fc7d37e670c7d1ec47cfebb620c7f5cf5c1f6289e8c61bfd95f15af5cde8cb17eb01373ffbc688cfdcb58ccf8feded8953fff10f3f7a1ec7aee97de89d95fd8de8a77eec6c6aebcc9540c79264b63ac1fd9f56c9f8531e261e9c7f62fb2be140f9d5e8d515e24e6fe6dc618ef97b474eedf7e1863bc97c48c6f69df141f9dbb6296e789a9dfdc18e9d287f1d057de18fd2f2be6fb0f607f22c5471f3159fb7b282f52bc12de1ae37d296531e39b17b2ce2b2fc4dc7fbc33c679bd8618f66bfd618cf843e9fa7dbdaa98ebbd6d63975fef51cc78e6c618cf2b4a7ec62bcdbd98ef435a8af97eb59698fb6b5563eccf305df1c66a21e6f39bbe31ce5fbf93191fbcccc5f4373362fe9e9031cf6b558cf1be3aea277f7eb53686bef762becfb065ecd273763ff2af7c33f2bf2273be7d93fcf4dfbf3662e41f1f8ce1afbe8af93c20fc9b48fe786b2ce6fb25eac6d84f9a8bb93fdc30c67af9a798f1efd918ebe50159fb09c6287ff920e6f34696cedf136c8bb97f7025e6f9e5a231ca63fdcb1f7f9c18e37cb52f667c101a633ebf17f37dc537c6e80fd257e7b9dac6385fb011f3f9a01e99f67e5d12733eac19bbf2e7aa3fb677a52be6f89889517e8dfac8df3e8d8dddfdd5a998fb6173633c8f722f663cdc31c6fa4028867ef52732fda9f845cce7533c31df37da3586bffb21a6ffb81633fecb1ba3fdafc96ccfcf8a31cefbbe89b95fdd32c6feff4accf1d733c6f9d2bd98e7e10664cedf5155ccf7e7778d5d7a55f733be6a8e8d11cfd09ec97fcd4fc4dcffef88f9bc27f3d37af54359ccf8e52ce6f3cd1b63f46f5dcff9ac3d3786bff628c6fd27b69ffcc3d348ccfda0ae31ece58398e74b589ff20f3f3362947f9c8ae9df2c8d719ef94dccf799b2fde40f6e4f62ee57c6c6f05fb662ae3f7d1923dea7fef2ff668198f1c58331c6a7f2577f2b1be37c8ef4d5fa0eedabfcc17324a67f3334467f5279ec4f97bc31cec7593ad7d75f8c5df965cb0fe5dfd1de9bffd734c6fbc20331fdbf8c319e2fec89e98f8c8d5dbaff26e6f3d7efc6f04f5fc5ac0f8e6ff97f9f7b63f8631d31e4890ac6d81f388bf97b6a1563d48f27e6fb42d9bfe40f36543efdc1f7b231ca9f88597ed618ed3312339edf1823feb0f2f87c7f6c8cf1a7fa97bfa8faa7bf18df18c31f36667f691ba3ffdf8af97eb26f863cce1f0fafb41e3ee982e50f4e5b64ad577a64f9631331e6ab59db18ebbbd764ae0f6f7762aed73f1be379f808acf5dde9ad98eb89d762dcefcf8ce19f95c9f4cf025dcff5f8bd27a6bc356377ffec854c7bbedc92b5be3916237d9c07cbbf59ad8c519f3d31fdbf0763f8e71b32edeff4438cfc8a8131ceb38dc4cccfd2b95f3020ebbc8c31f22b7862fa174763ec97ccc9d4f7732de6fb014bc688379ec4c8ef60d7d39f627bca9fb874c45cbfdc89f9bed9404cf9e6c6584f64feb61e772566fdc562fa5f77c6a88f5b31d7c733c6f0bf5ec428bf6de928ff2347a6fdae158c71de6229e6f3353b638c175fcce72336c6380f67f9f3fd4f2fc6184fec3f21edf9742ae67acead31f62b543efdbf97a618e5bd57c53c1ff9618cf7e1b2fe6dfdad2da67f766b8ce7174e62c8139e8d71feae2266bc64e9b40fec4fdaafdf2ec43c3fd413733fec620c7fe041ccf3a22363f4afa198f5f94ed6fa4f5dccf3582d31df477f31863cc63caf903376e921fb83f6e3479fc6585f698851de8bcae7fc1d3f1863fddf18e56df7c6d82fb3fce8ef6f8cb1ff427b2dff2a9e89f97c4cc618f3f38798efe3898de1cfe5c42c8ff2c45cdf19adc49c7f7d31e3ab9e31faeb9d18e59dcbc6f0c7242fdb77712d46ffa94b7ecec775c9c7f9789137c67af5a798ef33b574fa972a8fed7bf7640cffdbeee7fb61d89fe5af0ddec4f43f1f8d719ee95d4c7f6d6fecf25f5c89b9df3131c6783b8a79de93f393fcb5eab3b12beff82e667d148db1df5e1533def68c118f3c8ab99e7d34463cb615f3793df63ff967d140cce71b9bc6583ffd12f379c1b631dadfd2197f978d31bf707e92bf766a89e91f3d1b637d3512f3f7204263f8939f62faf35fc6188f5762c8f3c5f691ffd63b8831fed796cef53e633effe41963bcccc4902f6c19c35eacc5dcaf42fbda7a5ed027d3bff16a64fa675e864cff6bfb0ab6f7ffecc5f47742b2de4f7914f3fcc3454cff2c3676f73f9ec89ccfe24f32e71b1ffdcbd67ffc2732edb57f4be67ce9b5c5d46740667e01fab7ad4f1c1e8df17c455f0c7d2bb7629e57b074eabf20733e297f8979fe60600c7fa32ba6bfd63186fe7332fb4f7f628cfda7bc18e51ddfc4fcbd2b4ba7ffd412f3bcfcd418bf277126d35e545f8dddfdcb2731f22f578de1efa93ef47eca95b1cb7fc2fad67ac5e4464c7f252be6efb7dc1a637c37c4fcfdab9131ced356c55c8fb1fbb95e6be5f17c6840a63db97c89517e5c10d3bfbd37c6f9e39918f9b5258fec4b460c7d87925fefc36f1b637fec45ccf743dd19c39f55fd713ee95d8cb15e2ffdd9fecd0f32fd8b8eea97f349503186ffb516a3fce89bf17ccf52ccf561f677edc7553a629e87ae88d97f1bc6981ff762b667cf18f5abfc68fff35331d70356c6f0afdfc5f4afe7629edfe2f8d0f9bfc70f31cfef066294b7b574d457f9c518f349468cf2cb6731d79b7364d6f7d3ded85d5f577db0be8f4363979ebd16f33c17eda9d663b22d63f8df4b31e48f3b623ebf7436c6faed5accf7a7dd1b637db829e6ef276dc41ccfba9ff3f7312be6fe5e49ccf1f5628cfe9411737df5640cffb22ae6f9094f8cf2df9ec99c9f1b0763ec0fefc58c478ac6f0876331ca7fce19a33d391f6a3ebe3c88f97ccbd418fe822fe6fb91abc6580f1b88e9df5a7e7c3fc344ccf8c8cae7efffb9fe1dd97a8b772473becee4c99caf333db0e6e7bb3659ef671818e3f99d1d99f6da5b8135df7a5b32ebdf9b9035bfcec8bcbfc574cd9fabb298f3e7c218f777c9cc7ff548a63d9b3f1bc39fa88a198f0ec91c2f6f336377fd6229e6fb40585f9a7ff29e98ef036f89b9ff3536c67e8d5dcff5888631d66fea64f903ba9ff3c9fbab98e791aec8b41fb53763d8c38118f7b732c6785e4ff9b33e163932ed4bf5ce18f6652546fec59d98f5eb83755e635710737fef45ccf9f720e6f3796bb27e8fa323e6f9d86b63d81763aed7b17d656ff357623edf343446bae465fd856563c8c3fea4f8aa2c79699f9b0f62dae38931e2f9ae98fb49763f9f37657dcbbed6bfc4c86f3833c6fcb716733d624fa6fd9c5c89f93ebb82b1bb7f9c11d37e1d8c614f1ec4fc3de77b32ed616b24e679b08598bf5fccfe217bb6df1863becc8bf9fec0b631e2f558ccf7f13b7f3e8a65af565764da2b8fe9b25719a6cb3e751ec8b24f68cfd8ecd3862cfb3425cb3ecdc9baff0296fdc9dc92797fd0252b1e3992653f307e638df75395ccfa9e9ec418af1f25639c071e8aa95f9eccf1dd6f1ae37a9547ff7d7163ecee2f4664fadf998c31deffc2fb63dab327eaabf595565dccdf23ef89b91e1b1b63ff7f23a63d1a1a63bcd5c8f4b7f20b31f72f2b629ea77f37867d5d8af97c3cf5d3f88ceac6f08fdb629e97c81963bd7a24e67aa2670cfb4a7d345ecfb131f6e7b6628effb631ce9364c58cbfd8df343edb5b63ac8f1dc5d4df37c67e38fb9ff9274331e56f90b99e305b8af93c45cb18ef4f943c1ccfc767633cdff821e67a815dcff3cf1931eb676d0c7fd8d99fc45b977f5207dbf86b9235fe96608dbfa047d6f87d256bfc6dc9da3f607e1a7fe388cceb276f648e87fe08acf9eaad2346faddde18efeba17ceadfa38998ef8bc81b63be7a24b33f7f168d5d79e79d98e7bf5bc688df9a62fefedcd618fb4d2f64f6e74e598cfcbe96c6286f2ae6f9eb2763ece73c80355f7d2cc45c4ff81073fd62628cfc3764f6efe024e6fc7b6f8cf31ec6fc3dc1c818fe11f5977ffe1e88393e1e8de1ef5c8b999ff4e1f346b3d818eb69a198e7eb32c678feeb56ccf3a137c6988f7d31c64774658cf5fcb998ef5b888cf1bcc89d98f6e3688cf731b4c56c4f670f639b9f5a7932fbc3e089ccf66ca2fd62edbf74bec41c2f5d32ebfbab29e6fa458f2c7ffa8dacfcd1bf628d97f79931e28b90cc78f06e23e6f3032531cacf1ec53cdfd53246f9d44febf3f58531def7341223ff69418cfa7c7f16f3f90e95cff175f18c713ea74fe6f98acfc818cf3b96c53ccfba30c67986ac98f1beea8be3b12279381e5f60df62c5f3d58d31ce1b7c8921cf2e67ecca3b64c45c2f6f19e379da3b31e3cdad18f5f35515f37d151531e4fb9a92e9bf7f5d89f9fea59931f62b42317f3ff7cdd8a5af7c317fbf2912f3793031fd85d3c518e7194a6294bf0a8c51be319f777e3576e9ddae98e537c47cff49510cfd9fd83f654f2e2b639ccf96bc3a7f513276e9d3b518f24eed7ecaabfaa0bd296f8d5dfa742186bc93d818f6c698fe50cd18e94d31ed71ddd8d5b7affaa1bd0933c658cf7d16f33ce4d8d88d9777a7dfe45afe682f24d35e545760d98bc5c418fef21d99fda3d21673bdad27a6bd1889b97e5d36c6f34c0f64b67756f971fcfb0531fb77c918fe774ce6782fe7c5eccf4fc638cf5611733fea24e67c762fe6ef51dd19e33c4b00d6787ed889f9fc406c8cfa298af97edcaa98fa0dc47c5ea46eecca3b8ec97a1e222be67cd735863d1b89a95f474cfd4e62ee1f5c93f5bcf054ccf3504563ac4f86623edfd13276e9cf2f623e8f7127e6fb936ec48c974ec6f0a79ec47cdefecdd8c9db503ac7efa1648ce7ab0f62ca7f6d8cfdcabc98bf97f06e0c7f5aedc7f1bb0a8df13ce7ad98eb7d53638c5fb507c76f3434467b1b73fc3e1ae37968f5278e5fbf6f0c7f12fd77a2f9fef102d6facdf42ca6bf3823eb7c4487ccfa6d6e8c5dfaa146e6f8a88fc5b83ebb3046f9bc5ffdbf933376f5392e8891dfdb9398e7d1afc4b40f5963acc7b13cf5f7eca731f6178a62fa4f8198f6a727e6f3b19e31cebff5c9ecbfd5584cfd4331df072479587fed9331fa679dace73d42633ccf7623e67af39d31e68f9998e7192bc638dffc2ae67e53c1d8a5c7be98fd2f67ece48f1ec55c1f9d1aa37fdaf5fc3dcf8d31fcad43c64b3efe7fea3b1364bc4c988932b1fb4c32d3e43b48fe3ecbcc93f4c50fd7cfedfac0ee5ff2efcbcc2a33cfac93efeffbc09bcc36f9a4d7ed7e2877915e97794fbef749793377ff47e690fc3bcc7c668e995372cf39f9f78f72b8efcc57e6922927df95448e7d921e6676eebab2932b95fdce7d5793cf7da696a6bbfbd6943ffdfb83bb4e72ec7efaf692bcd3fc1e93fa307d7ffa4ef378729fbafb8e584eaa2fe40c71dd9fd63fca4df5803c8d44bf59f29d96739f69fe54dfdfe507bfd1e3f7f34fe56ba1be5dfe3fddf7a3fe890c903bcc3cbb4fcbe9e565daeeba4ef2b1f6d07d6939bfa89f9ffbc93fdf3f67497da4ed1167baae3dc2dfb6573a46322f995ea69f7cfe73df03f7794dfefd9619269f41f241fa88e93f5fdf77f7f43263fe3dfdcedaf5df9ff4efb94cdefdbdf09bfb919e25233d9f293a19ae32d7c96794f08f798df8b9617ea5cc6de6d5cba4699e97c9279f9e93eb353348fe0d7d24e78bc93fb0cfcb4f69df9f41224772bfe77b01af533e3fea9fd49317e2fb3732feaa1efeac1d7efc649deeae1c2ff0a25fd4bff442f97f9cffc0da7364727ddf37fe45f93f7f523d63777dfe77aef9aecf5f7fff6bfd73a4f6b4f6f84df9e918f12699d17ffc3375df85e473493e59fe3dfbc3bfffcae7d7d7ce32256f6eff2e249f71f219b90ffe36b6eb16c927e1c43e8cddb59049f26593efacb74cfebd4affedadbd0dcb9cb38c6df2b7f483b293bf79bb9fe4824edbbfa497ff3b3afef6b3fde1f3abf47fb42db64e1fd58ff7bbe5fef5bc7fef3efd7bfc27d7173233eb1fffb83effbecfafda63e4e6118dffffd427fbc3bf0bdefbbf31ef016d40decd2505fe6dec3eb061237e8f5dd97bf7197b7bef23b9eff0635edea793338bef64147cba79067fcf7b6bf749afbd72e93befe89dbc4fefec1d7fa39ff4d5e7d7f571e5f27949e678cd71bf773f3ef95ffced8fcbf8a34fe1877fa732fc71d97fa57df3bfb9f6e77bd51ebfa767faefe57fb0fffdb9fc7fd81e9c477ecf86fc7b3eb281a98dde7a5f7f600fff395b76e1f7dcd9a1647ef00e9c4bc666c3666efec07c90daad06d3679c473487387993113077328fdcf7c46c5cc1e690b99b67ca6efed9fc9d8dffb697bfd2756bf6fc83fffe57f4ffe7dae3db662ffee53cbfe7b8d16ff8fb6fe33ff914bc4af271f5efeaf73fdb1fffc1f6f81f9b47642f0adedd3f6dff7ee7e355131b5f457ce162869fe690242df579dd77d2024767f752bbf5ca98e2eff34ce311e7977af7a96f9dcc3ba1f357178c45d21828b1375ecdcd2d3fdb5dc55f3fdbd8efcf15e7ac3bb3e97f5c1fcaeffbfb9fa9ff9fe726378f780f3fc8fb8fe5fbabf6fdb93cc55063fb0cfeeef3db79e4efebebcfcafe77cc23d9440eb5c74fe5ff8fcc23b22fce267b77bfb4b7bfb663bfb26b8a21befff6e83d7975af91c41023171f4c3927e033f29aa9bd4f3ef83ea7763fb372f2689e28fcf049e7a1563237a5dfcf5edbeb785def25f9f4bc7e323f25adea0d92bfcf92bf2f92eb5fcd16fe6c3bffd8c787bd5afe8efebfbaff9fb7f53fcf65bf9573fe2fe58d0fea606671c7b7ccb3bfcbef57f308da436df6f7f1d7bf6f0efdbd79e4efdbc3ca77f388c6ce7fea3bb54f3fce233f8fd51fe386d10ff789658b0b991fe708b776e2a56b22c3cc9537f2c65ed6cb7979afe015bd2befdabb493e575e29f9dcfa4930e6fb7e90b9f2c3e4da61727fc47b938f1ff9b17d265edf9ffa337fee2ffca5bff2d7fec6dffa3bffdddffb1ffec1fff48ffec93ffb5ffe25f97fd9aff8777e35b967429f3b9533cdf39e6b3be31ff4f9f1e3fee6d77ea9ffcff5f0af7effc13c92ccad7393fb9fcd5ff3c38f6b913faebdfd52f71fdab290c9fb0fae8df5f9e3fef1efaea79fdbe3d7f3c87f7ecd20f5fbb136b474e333fdb7fbf676fe631a53d00f756b476e0c17143b308f92ff94c614a9fdf6eb7ec32bfa4dbfe53ffb6dbfe377fd17bfe7f7fd81ffeabff9437f947cc6c9bfb37ececffb05f7db95d7fe8d5ff26f834ce0057e10f8eb2074ef2c9a04d36016cc8345b00c56c13ad804db6017bc07fbe02338049fc1313805677f187c0597a01c5482bba01adc07b5e021f93c064f413d6804cda0153c076d674b4bde25e804dde025e826b2b69d0ebfb65ff3c486cf7e595f05d549d063fc93c6482e3e4ad9fd4d6b79a5bf50ffbf2d776aeb7259d71edf735bc1c9af3ce77fa15d110f16d28f6b1fb41bf249dbf162f15b89b15cfa777c2ed6b6a3241ef9a379a1606b718a2dd3fb276e4db1f09764fc2bf5f3dd1ebf99bfdd3cf29f9c43e06fc3bfcfa6fe7b32564b892d5fa7b141fa1df4bd9d5b931a0403ac1d25df57ba2ff1fd6f93cf551a0704afc15b300c46c138c806b9201f14826270155c07374129b80d33a117fa611086e9d392e1249c86b3701e2ec265b80ad7e126dc86bbf03ddc871f091fc2cff0189ec273f8e5e7c24b580e2be15d580defc35a92cf43f8183e85f5b01136c35692cf73925f3bf9ee84ddf025ec85fd7010be866fe130e151380eb3612ecc8785b0e8de93711396c2db281379911f055112cbfc6e4c304a6cb87ce21f6c63a27ffaefdb28ca60ffa1e4d5828e57cbf4bd4b14676e13db9cd449c2b9243d49fb4bb6f4b7e57ecfcb2f9421fd7729adf7a43dd6d66ebffdfebdfc0b5ec6e6f8beb78826c9c80892bf8d5c1bd31748d709bd653008fa98c392be7072f73b1f239afe8eac5927d7b71caaa79c9761de837fdb5c9bb6c72fe6bdff9179447e266cce87b32fcbc4a65c308f60cf41d77b27ffd131e69a49344b7acb3c5a44cb6815ada34db48d76d17bb48f3ea243f4191da353748ebea24b548e2ad15d548deea35af4103d464f513d28478da819b5a2e7a81d75a26ef412f5a27e923e885ea3b768188dc26e344e381be5a27cf25d48b8988eaef4a9ab701add249f52749b7cc77126f9788943364ed29311135d47b53888d39723e6e2f42181493c8d67f13c5ec4cb7815afe34de621895f165c4ffb95ed4a6df8dcec96a52573885b6f8bb7c93c7449f3f09ee35dfc1eefe38ff890cc9f8de0d56b079d64b424736b327afe9a9dfcfef7946d82f6d825f67f445b9dd8e46090fcade4ea7ef6f7b2fd7a1e090671ba527eebe693527c4cbcdeae774858715ac15ba5ed1ccd5cbbcf5dbb97113b629ec934fec4c66f3997a4ff9e51bef93f30d7fd953a9a67163fe4677abb79e4cffcbd7ff53bcb3d04d8aab9db87c57a503e3e25769036223ea7fb0e3687a436289fee757b5efc155fe2725c89efe26a7c1fd7fc5cfce00fe2c7f829aec78db819b7e2e7b81d77a261dc8d5fe25edc8f07f16bfc160fe3513c8eb3712ecec785b818a7cfdbddc6377129be0dbbe9b1988937f127c1249c4493f4ec681cdf4cd24f263dc8339946b79359184fe6934c3a42260bf79d8e9c78b24ce796a8e6e6acf429ff5572ed3a7a9c6c26dbc96ef23ed92776d24b7a77f8439cf2f76b35b2e1df763de1a033f9981c269f93e3e4148c26e7c95792e365529eece2f2a432b99b5427f793dae4c1cd2163daf03facffdf7e687fb106f896d96546dc772f310df342fe4ff31d5b3ba56d7c993c4e9e26f54963d28c8f93d6e479d20eba6e9e48e7c1816be7db4927f5b0927b4ea90f31e926a36499ca3149d7d57e6f1ef9decf1938b9d792937de45fee9f3fb4c78f6719fe47e711ef843d87f43b099f67b037de2bedc0dcec177ce2793a97d0b6a5eb1edb34cd3b4c7ac1383a4efa93c1e475f236194e4693f1243bc94df293c2a438b98a7293ebc9cda434b99d66a6ded49f065e769a74e9693c9d4ca7c9c8994e67e134f6d25e3d9d273dfc6a329f2e925112c7c95c315d26a3221d29f3309eaea2da6491cc13c98870bc0ee3744e49fe7695fc6d9eb0fb7b3a72a29b64d495a2abe926ca4db7d35d78ed3fa536339139b191ceb6febeddfad9ff655afc357d9feea71fd3c3f4737a9c9ea6e7e9d7f4322d27f3cacc7d5aaeae66c18073c03f328f680d47723df35b6b852517f3cc79ddf6cff34fe690acb771f794a695ccd3f46e5a9dde279f9a9b030fd3871ff6aa7406c2e2a9a44ffcfd3cf2dbf5d09f63933963d3ad8b47fe4a3cf657e791dd0f73fe6fe791ffe41ce26c28f6aadd9cf0367d9c3e6506d3bab79f3692ef266d91376d4d9b49cbbfd28695b037317d4efcf9743cdf24ff6e4f3bd36e104d5fa6bd697f3a98be4edfa6c3e9683a9e66a7b9693eae4d0bd3e274e05d4fafbc4e72fdf5f4665a9adece32332feecdfc59100d6761d84c3f61308b268bc4fe7bb378969e6e4de696f4cce8641ed566d3e493c432d1cd2c1949c99c12612e494745728f1b1d5132d7c4c9e8982d66cb49fafcf94deccf56b3f56c33dbce52dbb89ebd9bbffd67f1c84ffe711a83cdf6b38fd96196f892b3e3ec343bcfbe669759d95bcc2a2e0a4e3f99f4ccc0d467bcf387f5ff4bdb9cd671ba0e354c6207b7ffe3ce2aa5f5df4fedbec58cf93f5b5b4abca663dac6a94c491eb7d3a744cebb5975763fabcd1e668fb3a7597dd69835670f7e3c6b79fdd973125b7666ed59e22da631699affacfb87f348fe7b5ef3dc5e7832475fdc19ab1ce29e7fad7ffed01eff7fc523a94d4dd762121b327b99f566fdd960f63a7b9b0d935677e7aa129f7a361bcdc66e7e81ad99730d6b36cba67673969be5678559717635bb9e55a7ddd9cdac34bb4d0df1dc9f07f3a443cfe379322dccd33d8d85d749629ac4d79dcfe78bf972be0a3fe6ebf9269eceb7493cb399efe6eff3fdfc239d2726f1fce0e6826454242364e146479c7ebb11948e8a79324f6492f9a3947a59d1d5fc331d59613c5ba4232b9d63d29115c6f3e3fc143ccccff3aff925f1bba7f3d4df5e9b4ffef77b1ddff1c86f6d57e2b524f7a7f67136afccefe6d5f9fdbc96f43c3f896dc6f0f99d0f5ff85edff94bf3c8cffb33d9d4eb49e680e7f8387ff016691bcc1fa795f9d3bc3e6fa4f313d611ff8a9f90c1d984a4bde6cd648e4b4688d79db7e6cff3f6bc33ef2635fe32efcdfbf3c1fc75fe1616e7c3f9c86b7b87d4134bfc05c85ff95d59b36ece9c3b3fa3e0f46db39f2ce88ffc3be690bf8f0f7fbbaef5ab75e651e6b7fee09faf5dfdfdd8fcad6d1cccc7f3ec3c37cf87d7f3c2bc98f4ddabf9f5fc665e8a2ff3db697d91044c0b3ff3b408dc9ac84d66b70817d1225e4c16536f9f74f6a4c72ce68bc562e95f16abc5da2b4c0f8bcd621b3716bbc5fb62bff898be2c0ed1447bdfc9f72ef15d03efd5cb2f3e17898fb6384d868bf3e26b7159941795c5dda29ac42f01e20cce11737ed29191f4fc244e99c3fb4a6390d902f14afa77179378c9dc937a67494526a327b7b85fd4160f93f36c8fb596f89cb460ee776d79dee691fe2feabf94d8e44ea6376d24231e6b7b6e7fdfc510b82e89db9c8f3ff8d3f6f8f9ef05b6c95bfcb5785c3c2dea8bc6fc71d15cb416cff165d15e4c179dcc9bb3d35799dfdbaf706b5899c1a2eb2d162fb3eaa2b7e82f06fe79f1ba780b568be162b4182fb28bdc221fe5e26051089fc3eea2184f1757d16671bdb8599416b7d3e7593bb1689954ffdfc4233fcf2723ac7b7af7cba4132ffd65b00c67d965b4785cc6cbc91fccd3fff83edefc57fdd7cd23b2651a4317fa7d4bef4c7f74ccfd0dc407df7baa5ae32ed9f9a60befdf72af239d3fa6e9795bafb79c2e678be57cea7533afcbf972b15c2e57cbf572b3dc2e77cbf7e57ef9b1e82c0fcb4f9495fab7cbe3f2b43c2fbfbc56e2e377d2329797456f595e569677cbeaf27e595b3e2c1f974fcb7ab4593696a90d4bcbdd701d0d7a71bddff9f107b76fbe58b696cfcbf6b2b3ec2e5f96bdf48749276e54a471c7f71c92f6fe345e413c82390523268943bacb7e38459cb2282411fc743958be2edf96c379c5d9269c3bfea335a1c2efec8f7caf01ce28ff9cf3c685f5bce2bec09c76750a5bcb3d9513edfff7d9b5894b736b8436075d66f9e568395e6697b9657e59c8ec3335c438c93d17ed5da5652d8b49ac71862fc0f96792ce67de615e5e5e2daf9737cbd2f276955979e1e3caf75f43cf1f466f613d5d335c05512dba5985ab6815a62be7abd8cfad267edf7f5f4dfd797c5ccdbcb62b2febce615f7866dbcda18c89dc9a682243fabd5acd578bd572b59a7657ebd566b55ded56efec73dbc4e3dbb0ed57bc9eb27a13ebb7a8d739d32ef06dd8c7d37e3247d93fc44d33ce237d8c45e77b8e3257934ee68aeb10e9f9d60b6de2deed6deb7c925b0371bea03b139bfa8be9b5eedfb97435907f1f611d63b55f7dac0eabcfd571750a26abf3ea6b75595eafca61695549fe7db7aa6606a9bfbdba4f7ce380f7d4bcfdea61f5b87af2faabfaaab16aae5aabe7f974b25bb527afabceaabb7a59f516e7557f3558bdaede56c3c973e23164bc6a807356a93fdd71f10c6c6131b18b897d4ed7825623af3b7b588d57d9552ecaa66b59495c314fe30ace23364ae252ea51618424692e2e8157164e9211924d3cb6eb640ea9ce77abfcaab02afacfee1915d8a3fc1fee4d8f7ed89bf85ebb497dee4ff3bfd333cae92a7929b5a389cfefce1aafaebcb34bbf726b5b2e1648eb1f7b4e2ece18bb361ab875af740f1c6b5569fc779b795da5cf631f5737abd262bbba9db6dd733235b7fe98b46b347171c9659d49f34ccb4af2bf4fda7618a4fb1f97b5e7f5d7fe3a5887eb681d47c3b09dd6593a1ac2b95bff737595d81d7eaf93786f3d4d57ced7b3f57cbd582fd7abf57abd596f93d8e421f9dc79fbf5ce5bacdffd5912af74d7fbf5873f4d466198f62fe8eb62da974c7e7d48aefb5c1fd7a759757d4eaefd4aacef7d123ba57b6c2eeef58ee9596cefe4f661ae92fbf73fcca5e893d9242df95b6a3126e989a212e7b091f7eeeadd9d23f363cd273f9cd7d23c52a00f3d4aa43cb9358b743d7de5d6b277ee4c54ba4e9572d3edd9628d7b9eae6f24df2bc5206859d8a3f5617d5997fde1bab2be5b57c3ccfa3edaac6be16efdb07e5c3fadeb8b977563dd5cb7d6cfebf6bae3f5bd9e375b77d72fb3cdbab7eeaf07d3fefa75fdb6ccae87896fdb5a8fd6e375769d5be7d78575717db5be5edfac4bebdb4d66e36dfc4db0cc27b59ed8a7789b29cc5edc1c72e2d9dc915b9f4fe4fbffb87bb3366591a56bf8c770cea56559eaa18288080a8a967ac63c28f328bffecbc80487baebeeee7777f5eefd3d075cd6e0809019112b62c50a64b7c6da32348243686a7d73003ec12699df31c12708677077df41d9ed0e697f07944f5b5a688576e8846ee885fe75105ec22b2db4dfffcf6b0b90e7bfb4cf7bedaf88e8ae7e01fd2e67f82ec88f927a12b691681538ad2f715bbb889e8f735cd8163fd59ba2d656c281701abc260cc2308cc2384cf42de58629f9dc3023f947f4990ab573d930b74a84ebe03d218f06afdd844558fabbb00aebf01636e1349c99c7903194fbf5f29f7d6e7ba0203964c379c8858b900f97a110ae423194c275b809e55071ec701bee42d5afc37d78083fc363780acf61cf3f58b103fd1c90c322710d9c031c6ad877594ff22f2d874e019e37e4fa30078170b61d1d6a4b01f6a95d0e0fe75031672fbed7413ccc0f207e24b2b7c8674e5bbe01b947c887bef0b5089f2a0d0bd847f61a79427c56f43bce37215b82f6e11ce7a886d4947e0bdfee7bf28d823a07798fe14bdc0b798f39750b076668c9261fbe87c3f0231c85e37012d15a5f2f232ad2223d322233b2223b72cc508bfc4be4469e2d3a66e49b6174719ae81a055168ab5114c5411d2551aaf5a32ccaa3222aa3caec4775748b9a681acd2226628335e4e8a33946b9c47ec45d6c4d78bf11e748f441577c255a447cb4d46f8668d8c8f63928ba6af1c7c39760bce291c31c4642b442b6d132cf8618899114ada34d24470b6743f991d2d61d3accd1ebfa52bec1055fe3df47fd82f4ad9c9efcc198f08cf17b0e706fe49e56b1ad43ffb315ccae247c06920322f78170b2200f66d013d3a2e8681bed22155dd37d7470a7700d6899a290df65c1fec23542cff98c8ed1c9c8a373d48bfa9412bd39b2c64683e83d1a461fd1281a1bbccfa2ebe542f5d5f05ce7d9f77696e4e14ba2494cc7947984ec398a5071163db40c25d6d0eeda9b47fda61d63dde0030b3d1a86189b261f5bb11d3b8118bb9aab398e8c708faa39b117fbe8b8447220c7d73888c3388ae33889d338a3ad20d52cf03d90a3736377837c8ce2ac5f3973c011a7fbface3471acb247f1128d7d34e4c8b6718e7d50dd72a261ddd47181fd0889df499d1572491b478bcbb842675369725cc737b46b26503725b55dd2eb87f1c100b8491a8ff62c7a2df2c4b027d123dad3e83dc076e1e7a3bd1a37f1349ec58c798d546de4e4316b24f13ce6d055591882e518bc41b9a67132fb311f2f63215ec5a2cbc652bc8e37b11c2bce2ddec6bb588df71a4b29f121fe0cfae8f7637c8acf9613f7e0ca5a5adc8fdffcf77810bfc7c3f8231ec5632b6af152d4d668705c8bbebdd1e649dc7872a9123aa1122dd113c3828a628b4fee77fd81e621caa2ae4662da703b94cb24b1123b71a28fc44dbcc46f6bc8e193ff707eeb4bbec323bd174e828ded207e2ee0316701b92064b9b09dd7584746d7788f7e6f6b2670edeffea38bb9010f5eac0a3fa25d945c12040e92c0a992d03d438d5e5bbcf4c46c92288993c4721264852ea324d312334cf2a4484a834faaa40ed71736b9250db22a0a8eacecae9ef4e443fc67fc86eb4c9657d8e8800a2eba76adaf463b05ea550adc37d82dc07148a638d7e8988b649630099bcc132e59247cb24c8464e5de12319192353a970d3ae44449b68083925da29a74b24f0ec9a723535b974d8e2e0b3c6ddc4b347e60bb16d335adaf801c59c7b3b3e9f88513ed602cb66af95ab876e98814b2ab2e979c9273d24bfac95bc027032f8ecec97b324c3e8275324ac6ba994c523ace520ace22d0607f437e9d52528d4a531dc597318a5729974b0d974dcdd472d6949adafe25387bebd449ddcb8731d1fba9972c523fbda4d73448c33432fb696c2889013e214d92619aa2c865efce352bcdd2dc9a99615a68fdb44cabb47666c132bda54d3a4d672913f329abdf2c279da79c5ea3c78576b4e4944f97a990ae523195d2b52358f0cdcb748363db3295d17706fe2ff225a9926ee334dda5aac9a77bb43f7440ea5d3cdded8e6e87d8866b5f21afe5a587f4333da6a7f49cf6d0e7f4d3376f0cfd89c4d6d37f9c1b7cc623afbee4ed09a3bc9108c9dda403740ddf69211da61f41908ed2f1b5974e325a77332ad3342b3901f7b8f59b8443c5d1a467b2c38bbb0e9f657a6638fbccb485ccd2b5cc46f73d45d80fee9f1f509993b9061f9b869579991f1eb24b5a98c7ec9a0559082b1afd1c65719618c245051f1bada0aa0ac7ebeee8ae5f8bdf3c9c2d6fff6e4e5aee826320f003dcba2c453fdbe610ed2003b80fb0832e3b33ccb22ccfd0e75f76da31d96465566987ac36796010c1f3215b021979c3d78ed92d6bb26936cb988c8d2ca38c3eb279c6810f74e40ce11e5f813c1cf818a8d3e88a8bfc4ec6a3359ce0ff2b997631706f7ee7cf5984c55657acb3d2e60020eeccb36526642b03adb8abe59ac05fb290f7cb44740692e584ef06aff50c3ebb7971b2ced6e8ac36991c6c3225db66bb4ccdf6a6941db24f2dcb8ed9293b67bdac7f99666fd9c073b2f76c982cb28f6ce4c4f6211b67936ca5bd69fd9c46df766d69396d3939a5b3b966f28696eb0857e460f34d37377233b7723b777237f7723fbfe4d73c407e6e95877994c77992a77996e7ded116033d2ff232afd07bd1869289e631aff35b2ae58de96a4be43b429217caa7d8eff55afc34ce67519433396b1ebdbccb67913bfb6a13b1ad04dbe7c53d934fd27c9e73e83b2c723e5f5e132a46982cfecb39f90e8f7cf5251d3fa9aba92bb990af723197f275bec965433024f4bd1493cfb739f2adb91a3bf99eda0687fc80ec66c7353e61bfcea3efbcb9f762227b093102f23f0a3ad4fcd365f3637e021c904ef273decb9679ffba4806288afa3094fc2d1fe4ef9a9a0fcd3047bf27d37c948f4d2e9f14b461a2950eabf98de4021ff8ed97c373dd977a537b5dd17ddfa0d75de1b1a09c2bf01fc8f3e0fae29ce1d950e0efb063aebaa118be21161af14bc08dc0381157700da5d00d01ed9e6361a0f773cd7e8122b6c2cafcc22e9ceb67226851e11aef8517d78154f8f9b9b8049be89c9d733bcde07fc5b5089c2da584459b5b23fe3cbc602d23ccbf8d29eeda146111157191a04f4c01c142f5acb50f66cbbc40676d6c5cb3c8ee8f624e7971911745382ecaa2d2d4a2463b68a31df41bdaef0b74d6b77c5334289a5a187c312d660513d6e8ccd9625e70c5a2e08b6521186ab12ac4424af2625d6c0ab9508aadc75369b12b54eb54ec938fe2507c16e8bd8a53712e7a45df99176ffea51814ef86560c8b0fcd45f6d0376d972d46c1ba18eb8d6b40aec5e48a49499794553a1b7a1fbe61fe29177154536a38678739a8a55e1aa5595a971dd4d1c196e13bd9d64a1eb92d147f2b975d6903962a518458baa557fae525285a6d905ecb1f3a3ff986effa33bee291474f1cd87b9c8fd24c8405e6e5b50c8ab80ccb0845a50ae490cc11b2dd23db2a634b2b13932fd3320ba625c20f65611fcbd266114e819acb7b595d742a45b13c8acb35377d77b9b2a685f25636978db3f39b400e96e5b498eb5584ac8af666d4e5ac644ab69c979c390cd964e74fcb45c997cb52285766cfa6033b1fe18aab635b91807d05f6b3249fd5d699bee09147cde9c927b78fb07b601d95225e5f0ef95f29e15c998ddeefd9a73fb2f28635727c17c2bc51b9ee2c19610601a32831e1fa203fc3c1ae8944ed006bd41f6a2a649ecb4d29978a1940b48670155f6ed1df76c5a9548b416e96fbe77e2084d38a7b7d24a2c7e5c116cbcff2886251c31f00a38f30f9c8be2f4f5d850d9fe9d3a3e1946782be906d3d92bd8c7eef11ce2cda695ceb19fbc6ca72f429c4b5e8cea2e796fdf2ad1c94efe5b0fcc8eb72548ecb49cc557445555aa55786f15e999555d9a55239e9d1102bd7505ca3f220a22ae5cb32b735845f4cbef2f50bb5c5755752171950fbea62d499843e57b6b4ea5a05c1a40aab88f20127215c95b6361bd761aab84aaab4caaa1c7234c4d695275c73c70c46f01d70c50bf46331ad8a7097c455595555ad2ba1013517c89fb4d8e17cd76679c4b97f8647c83937f79f4f087fe49452ddec895169fd2b8adb81655935109d985c3545361406d08fcd7e30d38ed5cce023744d2ac672a2ac62abb915b7b872e49815572d2abe5aa68e3ed2fa9590ecaa95197891c95f114aae90af4536d8a92403e13ae89331b46a0d9d00e87f9ba0a8e40ae1856a5bed2a3531008380cfb0ef58e38593e07fe747daff3f67d45f0e608656fbd75cd893efa6ec2f7f6fff463dfe47f063e7ffd1753a90ac0bf828b0e2856688d104dddb37d891f877589f22f24d22f24d42f5a9a168ce3c5647f49d4fd5d9faac7a559fda134c8df1481fed97358a49e7d55b35a8deaba1b18738cfbea0386f534af7b8d2bfe72c1e7502882b315716f76ce0bd6b60fe2cd85e38ebc474e0bd901faa3eaa51b5f2d46a8cce64624e6a145d0596191653adaf9db5634dd55a88ee388a851573a11dfc21dafb28fa8148afd603a6463b17af60dbd26ab3b66abb766ab7f66abfbe54372a455145494da922ddd0c374101deb6b1da03b3a41cf0deba88eeba44eebacceeb22c8ea1276545737a9abbaae6f7553879504dfcbf5ca936b828d238c78b4628ec87323f45a4feb59cda414c4af388722b7793cd05b3950be2bb96c68f897e4e4c8614ea5eeccddfc52ebfe8247082f0a672e39b2531c29762f4e64d46c8c22087437f1f54ca6e87bcfb115ea5753e2eb0c13d960aee6ea45cdd74bed88ce91bfd26618d7b51068995a8cc38f7a553215c29585657850a7305c43ace78662235c558bb504f78bf84a7382ef1fb2e16950af8b65ead79ba244f703ed18f477c910a133a0f3adf755fbedce78d4471e8ff6e3117c03d53ea2f554cbddff3b5ff4f4fc97cf00ae36c6855daed1ba9f0fda21b5d2c600542901e70e59f696a30dcfc7d97da3dd5d1db702769307b9b69aaeb7496a086961f0f5ce146bb5ded7077b0d7ba4fea44f9e501febd355adcf75afeed76f955a0fc0f3619ed2d3956863c97b7cde1d6d4ea38b4b5ff84ee8d3dfeb61fd518fea713db9d137eaa6dd90b93227650cfbd83c427d02e2cd9b09758afb5e17a209f2416362c3cdf1cdbaa1bb7a736eeecdbbf99673bbe8f1ed7a0b6ee12d825cc52da656b784aaf59d26dfd208ed44dbbf65e8fd8eb7fc56dcca5b75ab29e576bb359444cfef36fe4c7956739b46e16d766350f03beea22c6c01ac1bb29d4572636ff31b97f76f0b6a47ec0bda916ecb796de8b333bbf1ba7e5bde38637013c251368cceb755c6dfc45fb4a57ec52351cb61257d8612f24b5b47be49b7f56d6338f91823d8611aa16f2cdf94627cdb22cbc111ee714c3b576437258bb9ed6eea6daf5f82258ab3d9dbc1b16f9fa91f4a805bb08fefc34ab0b14f041b8a563bcec2de8edd7d6b6d6f00f1fded743bdf7ab7bee1840c7afe99d86a0bb8cf17e3e97e7f8b3fbe1c687de8b6959864ad743943bcaedaf7b1e86aff58378f35d5f9a9dbdbf37a7aca39b6ffc3fd3de3bbbf014e377efe6d606b6d5e0de39bdb80dc531249776bd99cdcded13144d7f7e336ba8d11f6aa0cfe36d1fa0ddd5045047ba4d128aed11ba331cdb0b1bcb8b1b543e398c706d87d543eba63117485485cfef011f0ed1fb6e2be9b9e724106f63135ad1d1baff1ad65730938ed68ac6d2db013b3f50b63c8f8b5b6057d2bccc94536c0a651c433b44dcc871ada7a7345f65433f74da0cf9bb089b4ac899ba4491d097ada9bacc99ba22993aca97ce41410fe114d14af6662736b9a66dacc9aaa61dc4daad1139a83bc3870a1c0fed37baad7b0cdbce1021467bb3e7c2e3a07b4bb9b45c337cb46685629157d52aa3ba352e09cd2db966f8a79538dd848cdbad93472a368c051e29b2dba8e3bdf6ad4a7fe91dfe19131c541ef0cae7b9c352b7d6ff6cd21d965a2356e3e6f3877646c2ca7395a7bffd49c9a73be35f786d5f40cafe9bb5ead9893e6ad19586fcd7bd26b86b1d07c9429bac612c986d81782a76085032313560ce91a83d5d58c1ef880d86eafc07d310ad48b9ab1e31b6d5f4d75c809379a7af221def3fdff03dfa1dbafbf7f89aa9a0959edc83a3e3defb10b1ebeebe9f5ed2ec1533e47f7f7f3c07fc0417025ac2782186e03bc6e35ec43ee119c399cd2f918bd5e9c52536d8aa0c0d44ccb298a6fa6f6d469565397e4b530e36430f5a88fa93fbdb8b7e9751a4c4343c491c608f2d5049be0bd6a7636a5b50dfad7f8b28bc6da476a1a355773126bda51eb19f414f90e642bb45a41bb0f7947d81dc4777431a66bdede5c739a002620680f6c80e14ed36936cd114a3dea3cd461a7c5b49c56d37a7af377d326bc421c4f5b613a9d4e6753c65c4fd9e9dcd2a61c3a165a7fca4f97b7657020dc597ad5fa10cc9d453ec19b0acd65ba4277c3361c175028b235b7e1549c4ad335f21b9be986f4b7a0e7423d01708c830f529b76ad662a4f157465b79633dda147d51d4ef77f098f34ed017d877b6aabc9d3c3f433ab918d37507c8daeaf73d50ed3e3f4942ca7e7696fda9fbee108b08bcd35845394e960fa5e54d361bd997e4c47b8a7d202dce015088fa16bdc71966f03623b496ddcb0b214dbea21be17a47f46711d6215c1d7e3ceb331390f627f3b1c405effe77ee4b19a5f7089ffbcca91df7a43ab746c88b0237eadd57fc121deafbee8c9422b24826ad722743638f811eeebe3f9a46f68389dcce81935d30a29ac2ec3e070755df622cdf4489e1933136a2ca43ea2abc88eed6716a5ceec9993f50c76866256a8a142af1ece6f41bf046d5bddaec1fd1670d5f4e7bd4df0c9e391e0965a9979f03c13a1f46832f3d1df34c889805d03846f229b6d9e482480bc23c23dc48f10e48c6c028a98e08ece2eb3ebed6316a4e7f25363117e6a6661f4119d2e9c319c45b3789650b4afb8ec75e9b2b3547383cf5936cbcd7eaecd8af09c0c67e5ac0a6e60af757556538d55b57568a869bc3bd2ec366b72ca1031fbdd2b25c3450838f7171e0f3e47dfddfb29483d1bf757d063dc87f186b0c8a13ecca6cd6a364bcb193363834370c3bd0e6f7f561f217c5eca875a72f4eed7ba309bd734d8fc720d36efb2d3fac578c6cd1633be282dc0467d633d5b969cc921b030018c119be631ffd0fa33c1c4780e61490e1fc037a3c1ff9338dea2dc0b8e4028926935ecd90a2c12c404b582112fbafe314df24436c4f20e603adcabd9ad58b0cdd4579cf03b5ff2145774f9adaf111abadf9d1f79f88ce775d4ae2fca7ee098675cf3127de1d76a2d3e76804f07b948723de0bb90cf34bbffa3758522d77026cea450bf1898a77da2f71a7a0b743f10dea468ec47da3e3f970d96b3f50c6181343470a7aaf9d41f81eb0210d75dc999747bb78b4bbf72639faf1078d06aea0fd05979d38cc4b4717f2627f94c996d67bb993adbcf0eb0136c0dbd4f974924d9e731ec4a7388f00a3ffb9c1db5c0655b8ee806dbdd9c3a7479246a373be9d7d9b9d2673d4705d65b7c9df5eb53359fbd25d7f200f502c2e7a16fc0416b7101f8850bf43fcc06e8fbbf1b0a7c5e9169c7d970f641e55057c1b8c3beeb94603e41db774ef8600dd101d615f43795dae90aba9ee7b6aeffe77cadd36c145ef355c4cfc6d5cc3c829a04ae1ba088a172c39bb59c4df24f86662883af5c40d6c8c70f19ad10199d31d01d47889c31198bb1cd23836e10e3929c8eeb90b81bdb54ca1fc0eaeee2f616f729d38c6080c4045f4156ec3469f396d80e8385449ff161288c17b7999be798e1ebe33778e40f7d0cc96be1f3a2be721cbef99c679ff49cf77aca9b59237f50a3fb981559c9f8a091c35c982b13405ddffcc096de31df907546d1381332515a32f1f5c824f412f387a15fd66b79ce5dff480fed1764c7a625933299e538a1396172ec3b0cb035b053a02e92184c911eaa6d3033846006f915438403f90011f62bc96b11fc71e7caa22bce94e017f03eb6628da98025cdd4cc2d1c320d336566d6bb76601874c63d1241c0de7ee45a001f58385e64d8a9e932983f46b79c4e2e82feb53eb2e915ae49abc944538b29e4fad16344f5c33ebd0f0ae00f3073376ef59f0003ac09b70cfc67cb92e6184eb3980503751c11459a3cb364042bc15110e9c786d78ddade6fdc774efa62303ec1ba1f1d478d4a9915d63779239cd52f35f7d3173c825ee32d19919198758aaebdb106ff1a3060df194f3b963eb36164cd4d878c125880134caeb8d56766cbec18645d1884c89903f3c91c99538d6c3e73cec78035989e6b927a4a7b2f4c6b8c7c08c9e9f8e49e9a3da6ff72cf70fc0f11cfbda671b7bb17d5e4a2c9c3c7bff88aaf59db97c727bedb4b16981c45e69ab58c7ed63b7c7b7f4efb394fe7e24336b75d1ffef33a839d862b0c3837178acc5ba95c46cc206399f7f08319321f5981b3171cf85ca88b30a362cc8c994910514ad8a77c96662956837bd6aea7966f87fd888bf3f1327a96ce1aac6939ac059d3196761b9a1cf0692c03edc92b6beb39ebb02eeb5ddf589f91d80b7b35433600de8c76cc4443841c08bc8e0d21176558571dadfcb321428e1a3c1ed44dd808bf9fc3c66c12aed9748a6ca3763204d780fa0ace5b436d156b92b4b6ce31c7f8f3336add72ae4ef7de10afad7138585f452e5cc867c1fb251b4d65d1f95a33b4ab4ec8fe57c0d86fb5df635a68fb1436f73e01c2e5813e97b7dc740ed75da8b1c55d93defd0bc7ef9ee7b59804fa30802bed815f02dfcd96448f8b1e5c13b6626b0fed904a02de9921348e21405d593bb337b6217c57768a8248b8d34b9631de58969db31cbb60797689ee83c09aec0a678a1d52bb267581472d9bfc1d2c105969e8ffe87e8402f159f87ab7af238fe47518b7dcfffe78bfc7dffff8f1fe3c177d265a0f90c72c745c0d75708e6d04e7c1622b4bea68f7f378fa1e6407403d03e73a3f882e81897c450d99873760ab987d165d3b766df69151be62bed68eddb072f819abacc26ecd305db23b569df6d93d7b8895cb1b955b657ec0da35b8078afd6c7b563acedbbd7f843d6a1c7b62cf75c9f67c2b1ab2fd621070ec1b3b60df8b253b347aec073b62c7b6ca4eb47a4ecfa9b9765dcff5b9914a73736e9962bd2a2ae3ad8eacadd19bdb7367eedefa73cf9accfdf9657e35f479808eb05806aea1cea379ccf4e7c93c9d67f3bcd6e745b19c97e67c5ecdeb7985fe1f4eb3f96d7e99add06b6ff07a74046c346ff4c17c4a6bf3d9aca6eb39c39e238e8ee7ec7c3ee7e68b394f2de8f5c5982f99f15c08dcf96a2ecea5f97abe99cbb3fe5c713ee6dbf9eecab8bbb97aa1e67bda9e1fe69ff0bd6986f6690af9150466905dbfd0de9c991fe7a7f979de9b7fba273a86bfb360f3ffd3478dd25c05bd6f7ffe361fa0737f9f0fe71fe8f7d17cec2aec199ddb845e723447711a3be074ceb0867309810d8bb30d9d73ac23e772defce8f3a935b7ae6a62993746e37cee92e4f13b77e5022e0c58cee1222e46af49d06bd2f985cbe0bab58fe83a72395774bf37a36602f705ee07573e9effcf3c3613ae0a392ee30a2ebd9db91a7faecee5705ed6a496b82270b91b577305534d33fcf7a0bdfff87cd1776ad07b4cd3607ee3661c83d648ceb1dc9ce3a61fe1d860b805c733e3696f36e496acca09ce915b79334eac4bb414b7b7c079e7a4eb1bb7e636a9a46d38b9bc700ab77578caa2636ec7a9e83e35e8fea0fbcfed69edb10ef0233a081e6935120197805689cf1d667ab0e43ed1f53f722733bcd5dcd9931c9d23da4636f045f53dc4dc98bbaf72fdc22b22ee8ded7303ee1d450789a595b18d3008b65716b101906b3139c023e0111907f913ccf9348fdc90fbe046dc3814c2253769b37963f23aec83902f5ad0d97941d1938546faec4c17638b4bdb6701bcd6c6d116fa656a089093825c5cc89afd85b13067e542afd385b5b0178ec7229c202f1e7d975f754b7af4043d1eda9ee9eeef7fc58ffcee20b9b098e09685b7f0eb63dbb3a9b51c6a89da70dee2b2407ed9da2f82456839c89758866cf68351aecf75dc8be32e22ffd208999f8996b388b1ed3ce60af860747d12b0c3c83e7799fa31897cbbeb688eb18e187ec4518949d02c57b43f8fffa947a8e0591ae9cf21bd9e100dc17a68cfcf3107b7135e1f67a893ddffde3ecf5016a9e178793e5a64fe0070515a2cf2405e1497e1a2bc6617c75d5dd6d04bb2a816b52dba03dfa1f68b1ba55617b65e34e85a4d17b305e3e8c0c56a670a60fd1d882b3a1d4c7cafb4effaf75b5d14dcaf80fb41b0ee1295661aa5eafe822dc666881ee70bce652f3695769a7910afa1e7d1c091d26c7bbd58506ad42f8d385df0357bdb1a477f00b92f73f4c871e01aae3cbfc10eb14657c376101eb731431ab3d50c40f76e97b933eeac37c875e3daf06eb1b445ffa23994aa99f7fe67dcc382753c747a9f0b0b41fb44a87f0499656b5c72e80aadd0ba13f56a21a11db35e6cf2033a5f19624e8421fa4f3ddba4eefe86f952d04b78809e78aabcf709fe8707ce7ff5713da65928d460b15dec1c01eafbc866819ebd41d1a01352958bdd42b5cee87aefb92b3ad7833f88f9d25b7c425f8a236966e42d8e95be38195625911d04b99ab68f037a331c60a9741c07f2d8e10912f59083c4f270ed6b7a1e60bcd9fefd9f7a845c13d45702fb713edd7d86f398b61883bce6f9203b19d7cfd0ba49f7861239d74f5ba414cda4e8c599f2173d5028227d208ee66ed0f5f4b3c5f51c1e8a31d48916fdc5db02cf9d69d70cd6fcc2dc06ee9e6bec636cd93ce905bcf6b363ddbe56539dc4fbe86e526b2b5dbc175e3271e40583794efe535f42a7c50b7d721ed6791ae33dea5fddc570f1e1c535dde6289e7835b8a63a6975ac745cd3c67cae8eff65bee18e9da71c06c9b958d8a658dad55a8c6a7b315e4c783aae28bfedb7f3705f5e4d5d753938f014af41ee0db3da4c93072635302f2c8ad4cc2b9fd7a92d6f20db8d35e4a147e04907a39d9342f257f719557fe768757bb1df38f3266ff136eff0aec75136c2230ec148e8fa215c7491788ff7f94bb6e3af7c60f27cc847d51cf9eb0038c07c7ce1f9844ff92cc7be017aea319b9c706f2fe604f3a89eb84c5d6dfbae5c317e45d860ebe797ef72533fffd8ee14cbc5681bffbdab34a3efc2e738e3631a6dddc37e79f4f2abc19cd15a71bcb892f9822f2905e7327bee99e045be02ce755b63da2c6e7ccddf700e908b35741d9b4b83fdc7a9f5235d9f0de92d7af88c4e43ffe51e12de2fd6462ae9d37508be44dff3536ec7cf52e52a8586cb3a6b9e011e24e46f70ffd6892ab16d3cc32c28acbb8a7b12813b0cfde2e8a4587ece73c0c962ce8f5c05ce57219371f72db82a057977d2478e19d4c03ef0da2bd8e5d6bd7ce4daa49a652234ce2f78de68f86585bc29ee337b871c92ae82ff4b4ebc8090abd7f27a26e8aa7bfccae8f2eb9a8d223c5ee4a5aa4657f91df91292777ad5fe38b9495b0b7fb3aa7656c8dfd5931d503470b97c9f5f2fa6fc86972905f992069f7700b51a646d544a31d71e35337985df166ffc8e575997df9b36f86a4acd4d332c13fec09c1d1fd8e08c07954ee00043ce8ad48e71ddeace836a7f6feb0b8f7c63773f20ea9dad88d6cb173ed54f3e9ae4fc1022ef13f63bbec774b74b603d3413e2375e7d6077deb6c5a0282c13f94f7fea8a9aa3599444b41ee1dab66baf847e7e74ef36b4aab9fcd18b2d1d572f94a8e24fd4c774035d66ae0c3c09a2f788f5004e440f8026bac3cd771a5f6d3f3bc4f36d8f3455f1677ac9f7f8beb3c05333c91c8e4ee3dbb9fb911eee7b83d7e21ee030837a03e86f68fc82e1df920f7ee0789676f7251e64155d737e697b0468609910df023c1a525fb965f8ef2f7e04e7f827d0c786190311c9912d926b3fb2728f7fe787d43be0247ac27f5c3ef81130500c8b1ff3939b9d8f08af0998dce4ee201fa3e8d3256d83fa410fd7c99ffb063b0d11d2533e683562fe9e7e53847be70beeac8bb9b5a4969a259ae152a77cf784f35b9d1ea21b1a4b230f8343a03972f4ce1745349bf0a55546d0e7612ecd2241f1bae9f8013042701d03f8686db5cf831c511a927ad6734de2e1c7ad96d3dcf5c680d542f8f0c9d7fc0307958f20562874cb595aa5bcb48167d19e07611da1f3e7f3878ffb95b78177f369e92cdd787591bafe9856d76b8a7385611bdbe09997d476e92d412dd03684e5c50c9dadb3585ea94e5b06c73e78ad13fd85e7f923dfcc1d6bfbd9dfeef5dea3ada0b87e870f83269adda7968f8ab54f5a9bdb69f461edd8b6f7aed3ae3d3992bbd6dc65b00c9711dcb98e63097e64190357f55105ea389cb70c74ae302feb898f03887d9968476c7f80d7e3c26bc166e25e0e11a1567e992e3357a2f7cbfc7a2e18f388a22a1a7ade96c5b2243e0c344f902df2109a27eaa35c39e4df97555d507aab2109dfe969762d9e87d8fb4d8dfc3fd024d70f75b6accd309297b765d334cba93348861460a85dabd592bad2c559ce968cf5994e3265c92ee74b0e3d2e169325bf5c2e0563611e0dbbe5ae769d091ef090c8ea729f7bca7fad4f588f7a46a7ed023592e5ea1ff521e871292626ba57c2525aae196db9998e3bf6cb9d5361e1fa88f7f01dafef83beefc5d098d3525e2afea4d8a2f84160e6cb2deebf2fe96e6ec93b9957ac99b1b744eb02b8ca4b75b99f968b08eb4f9edb99302a59a70f4d7bec8f8668fd437579ff1b3ff27b1bd8f564bdf65a3feb0d3e748b5e66d952f9f2106f969f866628503bc7b6c0ec5807cfbbe4a996dade59e87bc67ca02bfa96c7e56979d6fa067ebeebdded20e85e5da182691e176b47a67694b2ec193c2058e70a8c44623fefbc1d1f7c104190e97ed95fbe69fde5206852a59d7f38686bab832fdfefef1f5e232edf59d33c2e8785b7fc588e96e3e544a00504c551c4d7d9be8fca7003411374ed28a0afd6bcf1fc5c3004e8a5343f4153463b16fa73af46e7638d2e32f59efece811203ba3e98e183b90ab4ddf19bdaca1cc93d113cf2acd4f0d307e04ec33328c14cac602a58da01b8ca8ffa78db3ff2c25079c6338447666cb483600b8ee06a7dee9dcd048fcc1da03b3db56efd9d0113071bedcd3c0abe7011ae18473f7486bfea663ef0c7abbec0abde6f978379e847bcdd7b2b54bcaf7e9d31f45d0ea7d5eeebf4c71d91a28580e18510578cac34823c95103d756775b8e1a5664bf219d8a7a0ab27c44222a45ed2e541307f0cef10b8d3086f88c6da14842c3908b950082566be78c0a600dd5e63e35ef02eb16d3a9a04cc4545ffb70d679e987da1d28ee9841ad107f07d4473891e113db1fbf13ccfef3f7c041d32ad116ae1668642e3b2c214f993caec4fb7d73761368b7dc55e098cc01a9ae5401f39d4d9eb77e01cb898c5d3d5bf8bece9badd7bfbbaebf7aa35d9b2c33daf00be5b1759bdec069225e909f3affcba9f7d34ac32369cc410386121f01a56a7031e195af70f16890778e45b6eaf77e7e8426ed3c32a4fa1b0b40782501fac08b4e0eefa01db6e9e32323e11bad62b762c882e779fb3f53c53ec9937f7e03ffc916efccb6cbaa79a41b7f75e6deaebecf353ab0578be3fbf9b5984edb22069fd18d74780a56d5bc2faabbde8721846cbfb825c8d81d974c02712362125c88282fbcc311b12987e6405003ec1b97ec97284adb0633e4ddefc803e67882402660ab9f70f58658e0fb9a0faddd2bc9c3fd4a2a026557d16f68557d6a08d017927ac73e8fd32d7f5effb11d75b0987782a7ce6c2f2201c8593b0e73401f946ff2cf4f83290b291b531559ccd9d405dc71cb926e0a62e43fa0beff5c9072766f7f7ce72801f7e589b674e6cdb797def2785eb7b3b3f47653fffe804425f781306c2bb79840eb1ca6d59b12d97d8c2751461f84ddfd1b3bf241876e40f04747f8591301626ee00787b5877fed1af6f639c3ca6d478baa28b08f7f7136edcabe6d9f3faedfcc6ebfc91d7fac85d4be31bbff0dc97ddf18cd4d6beb6fbf33e0b90e482486d01b403a754b9a256da4a5f192b13f85e08c18f566dcea5b55ddff8908e5b0c3f8796c9e7d4ca5e392dcfc826391bb8bbb03b3a5e91b159b9ec2a2bd3b8eb4737ac15c21fc6e696411fe1ca07351aede8a33b15555a9f19af2eab6b335b05f5de4da96615028f17ebfc15bff8ccbfa99d0f1af6c54e731d0172faab68aaafe2e8b44aac7d3089d855aa8f78de58dfacc0cec736fe9e8605fc57a80bb55803ecb2562bae552bb81fe2de674ffabddbdebaa7dc15f85ae0b9619cd75edfae3e627b6d7f05f623088f3c7a7dfe8903b42cf13424e0eb619fae937ef37bffd1b31ff9b56bcbbbbdd501e6039b89b9cad07dcdc3e1aa5895be807560865ffcc41be4b61c71165ee7ad36dcb3fef1579ff33c7f64fba7f347ced4b3eff855afe3f5ffaf7e85d44a3a5da24e9f1162c486ea4d6fab6a555b6b435cddc08fd88ffee35f39c2f79f89263b891a568d4d749c02b4e247e6e4e660659923e4bf01e583d63ba8dae478820e7e7f607f2be6d9f04216bd7eaa57abd98a094db631de17e565b862b9fe9475e9d59c7fbf8598478cf3249067bffb90e867fc08e6c20147d9a60277eb2d57dc6a7171fcc38ae72e97b1509ac704fa34d06a5f2da1e7f08eba119ec01d41bfe4793a1fdcf6f1dcb9bcb86fb4c51d242225c7437b12fb67c2c526fc27a5c523ffdc817020f4c1f32bdb5a09fc04d4fb5e7b123b3cf2f021d6f8e5f51eec10a2f16f4eb4b3a6ae56d6193a02eb034c67f8b23ebb99572d076ba1bdcc8effea475e75fc7f8f47beea406d5becfffcf7f39763f0f2fc7b8dfa49bb7688fbeadee9fd4acce895c45d56eb3ab4a8d5e6de73f8d21ff0128f6ac051edd40270975741ae16f6333ada0dee4a2e4a5e8b498f2207391de8a5809c16bc1fe94381bc0dda21ca6abbda314d76d0ae2b95f2811bb0da6bc2eab0fab4dcd531baae4ed467379ff1ee3f7ec55fffe9e309cf0ae168d24995069fabf3aab7ea476366a801f716451058c5814251a44de278e8c3867a51243c7cc41d47786d2fe0dd7740071c5c0712a19ab8dfb0cd11b63d83b89fa2ebd7f33b9f0d7ea49648e6f88f7a09ffce239e25a9a0fbe7d8a6e32f45d7fadaff01e784f35abfc323786d10dd0443b69cd59bc7547ddf8ba5d5e0620373e865fd92fb36d6d53003fd50fdcf34f51ff7f8791ecc573ff23ccbdc7ed9475d1eabd3d17ecc237a7ede8bb620dea3033cd3b069e72e297cb97ab7d5d570f561f65723d28ff0da07f0ec43b042d9dd66425d04ed18adc8621a45564aa1d75661afc68b77974de6ab8948bba64810fc2499624ea8256ac4e7c4e851d445a3fa10cde62c5abea52b58afb1126dd1115dd1ab58d1172fcd46ec748abd2fdfff27f04884af43806ddac5aac4400c6752e95a8e18615b6e41e4c378c42792de4b5cc7f1ba3eec76ce09f7920bbcf702e20a2caebb13ae2d46b7b813b7b5422d2e203ea4c37b98530dd98b7b9dfdcf6be5ffd923447bd0e1007d805d1dec19afc0b9433f7b1b257ea9b1138b07df0bb47a101ef1c538bdb9ac9810ac81e71274331e5bbf4df871045f5ad557bff0cdf1e7f3477a2f7be949abf6373ee4ab2f79b6b9646fc2d943ce9fcc3a44be64f12ea6534bcc801f944c0d0b8ece93bee64220dfdff6cc8d882f801abb98070cb0a2c5422cab21330ed6da15b44796bbf97a696907604ee24ea033f12984e3554a692042bf8a532696b31c8bb5b369355f3fc45b50cffa7e2436e2549c890c9ef1f1f51afc7d1fd23ee2da134b5d40b34564afb33a3543ff5d9c430ebfed42bb3333304e38137d123c61cebbf7cd3dea1da0928376086484458e6488b5b3b8107971290a368ddfefa96f031839310a76eb85281adb87ce803998e7c034252c90e77e90d696bfe083df689cfcc923d122b134e8bf2713f69ebf2b796fc0230f7e591763dcb531711d052c00ba661233056d50719dbaa085f3c5df434c73686744126ee1b09d4df53adff119673ef4317fef47fe9abdfc9dbec7ef6ceed3f3759952c58d5ea5b1a5d532ce97b7d36e7e9797ff5227c6357aec2b5074102e45593b888a7012b7f94ddcddaea2aa73e21e452d1f70f5ed6e7e21a0fa2144228c633842df0caf6f81a07b78528141e640118dfc467466640ec68ff88d5ffd08e96f81da2e701242d05489d12e99b7196dd0f2821e7f9b74984daac610bd0cadfe438b2bc8e40288c7bb595b4e753027712f5b39a6f8994ec29b78144fd74ff12cf6421bbe3fa92842dfa0395c249a7aab6786d88f57e29b057d25b897d0fc30f962210e504027a411447b64873a57e27fa0ce24be8bc390133fc4913816274435e2b73da7bf3d7ef3bc6e075eaaabd9bb1af998646a40e9c31c054c9111553af8dd70cde3f222d1fe0e6a4af444a224edceb5fa89fbf6bb7930ffa5f9ec141d68cb9d7e339c349a61958764da696574bbe40fe25a9ced84aa605b1b46bb2b64795ecb245d322453b2245b722457f20ca1c013dc10a257718d01d7f88db5214abe74a974a794ae52203af3fd9c27fd85241ec5b3aff6cf5a893ffbfd5b5f02b3a1407b7f4a959a2d855224c5a0fb84b50acd52c2fa31734301fd45299152295b4cd1ef1699cb08ff47d70145518c6728cec59c2c0e5a5f020dafa95448a52048953595ea455edc48f485eb22607f5de9268852a3a1d8bd3e4ad3a269d53cd0759266fc7bc6d8a7ac3014dbc41903af21bcb909dc1b89991da02601751ae46b9c079e79c6937f13b7a09d29b186b2c890f56cfbcd6f8352627ada11345dec56bb31d94873ef04b92a7a683512c7c834e45827dfd63dfe5f1fbfea2f3ffdffbf345757f62f8e0d9958b32f2dda0c2fe6717d930fffd606dd992b28fe86bc3ababbbcb45c1c25613934afc1991ff2ef6cca1ccaa3b49244e86103a502587592549febd5eda065d9d6df4a6b69434f9087bed1ddcc95c76c8ae8e9f71ff523981f14408f239efde883f6462423d029e39c93025c0149b21c4991b6120f9a97e154da05b5a49a41dcebea1c903535275037016e34f20147693f2d5054ebe97be9902f419b51fad45de9289d0c0173816ddc912bd49b8b03585264a4f37407bd8a04db184bf6902952af1c1a225cd716278a2d470eebe82e52d29382f1d0e53ff1217f76c0b9483ef26db8afa8d54f80684ca9dff943f34970a67692fade8d6861ea7b2d95dea441a63b3a257d67fbff83e3455fe0173ff24ffa901ece174dfc436cd734e438a4f7fb4c73acad01fee14ff4991e1a1ca42ea027a6799686d2473df3118a974669a94566288d132db1a4c99a3644ac7e83eef89a5a6bc13239146f6b9debad0d3c1ba94f95a6d3ce951d3fe69b7773cb7ffc3a201be5ca6bb3baadadb5bd76f2bedfacddb5171b6be0ef3af1225c4b7c99ad2febeb3a98b2e6d67284557392ea75c82f452914894a1fd1b1250cbf155a4145bee4d6916621bb3a81d927c84ff93073c3f7d3721df3bce1826e19608e75b24eed35faaee63ad3fafc82e01f63b3ce6b3b76d685191a2ecca977db9a7eabea40724e9041bf63a17b6ffc3de7f45cdffa8f1ebd7569725900d560d8d5ad763c7a5fe89f7742146925dab1f2d755b6a754ac41b3359d1445ceeb7a7d5b37ebe9b7fa65ff89afffa37988ffb41f417654f8d4de2c60a67beb19d150c23d04548733fed88f24a6f1546fcd47aba5c9ad9935bb9e9bfd58d30e8b30f1b2de9a5bad71b54a582fb06eaf27182c02c7c8d6ec60862bd14f27fdf0ad1f19dc6b3bddb97e5367fddb077400edd7bca6ae97442ddc825ef523f4001a0ac384a7b5e05fd62b3bbdba56097d9dbabd5eaef3b558cd032988d6d27abddec426c22907b4926dc7f7724b337a69b62633bff6616195ddac2a382e52b65d2b507701f55773b2de3a636a073cedcb9bf569f0698cfdb292c6285ae3bd98614081fa86eb1644c1cdbeeb4f4136b99b4f8fe70bd35fea177fff706c7fbd831ecafa1df7130db126bc0dbe63add6eaeadd7d077fd9cda472e68bc17a1f52897b5d3bfa8fcd67ff77f1488fdeaf0fb5578bd0f730bf02a311b4305ed48eff0c8f743930ec47ae4635ad83f5e7fa68acadf1fab43eaf7ba93f134c1eb84e90ff00bef0baef585e7ffd46c9d88672944cf42e604e910db98e6e5ee098cc6dfdc7f0c841b3627f3d3016386a0196a116400fe67a5ea68bf57b3cb5d7a0d982ce6f72b135ebca696e355f0fd71feb115a0d637f1bafd613ed60d8fc01be9b39b0b48564868be386de501bcdea6d74f4b351dd3666fa4ea91b2bf636f622cc44f03db87fc3d9381bc8500c35db0fae878d476600c0cc978def65e6116cf7e64274a9f075a6a0a68ffb2f485596c6f342beb95f7f178f90cfdb5c899a3af82cdce7833051f306ad4b68d71fd03d635b3d1a98b3a66f82907226c127581477f37f008fc08c8fb3231bc85f04f62ddb84a0c308ca384fdccfbf9213f19f70890b9a19016348383e06ad8c2168a82f0ea0a50eaafa9b683ddfc49ba49d237bc69a49b8f6dffa113c1f11625988e7ef7ea4e3fcfeb41f1d534a1c183c89eb8133e0f837c73c96c34498d958efdea3a690cfdfa49b0cfc81b6dce48ec16fcd70536ccad4e4879b0aead5d662536f6ee13918078bd0df349be96686fec618f486d50e95bf9917e562bbe1a4a1281b5675b81ab5825638a51d378b0df4c5788d1aee37cb5b064ae5d0253dbfa09d12f98304f7a5a0d5f9a8c1e03c1b28a3773a671d53e8077d08c63797fd46d8ac3622569f05ee008a2fcccfdac9057a42d5b7186b5e9179c03625ebd6465aee37eb763efbcfadd37f138f54f45e63cb3c36818fb4d940950cb3e3ef3ee22fe21192af6fd5d1808785735813dc4f827ccb46c61e7a02ac14661c48330b7396dbb980642e21cc88c598e34293fcf9b99dbbdad98eef34deffee630fbeff46d13ef1f9761c5c27bb4a7b1f2642408dbfc639fee166bbd96d54ac47bfd79ce8b89138891a6ff68bf7cdc167b563246d3ed7c1e668ab4ba6543727e388573468fce3de7fd02e43d845c4bab9d47d8e8a631c357573a6f7a6cb339b9e41275398c505f9b4f90ddb6e0f3221d1cabed72ea02b0de6d0c30e01ad47fb077cc6778f26e71adac19f49f34833c3529dafe799c96dfaac929b8e0cbdb1a44704cf74c4f36e376feb25bfd55c8c2d7f32f7f8efe191761e88b8d5fa218a7b378336e3eb77b9ad3ff7238413fce837e87e7ee67d759ae8b5b97997469b61a7bdf5742e4fb5587ad5fecdfdc3bacfcf7c7f87ee6d3e36234370aea42f06b43f36e3cd24809953583705f3121c7a20d3de12f77c82e6d3869285938c0271e4fb36de2954645d36a213a53a9a6c961f96235b5829d06a2bae9af5acc37c8f4eb14e80c28f589ae80dc8b6ec003bddb00a2d6038abc386cfd7f7c97f7bdfd5beffded1e970420e2b9fc86e205f8ec1a7ece547ff22235fc8f8f2452fe52b601032cf19b014ae656da86d365c0eab378fc731c2cfe521ff553c02792d777671b24b38d1ce5c06dd9bb701e1b23e76c89ff89247d4f5a2710edc51ebce023487862d0772e8abda9ce00e9cb7eaddedf9bdd7903db51a193f9113f9b3ef3fa587f6cc3b302c64bf6dda700d013466af9f299dc2f354cd82998430abd05734d75d538a1c896b39f63772320bed14e6a653be75925339bb0e608e9f9c8b8345dfd22ca2e74bf00285fb648ca588e770dc7593a1b3cd1cd43c3220f2a2e7b2725185e6c9c25a8ed164ed3f6aeccf35f0e79cd5d7daf9173cf1ffee3bf0fb92f3964bb9926bfd44f9ee5cbe99f622921b791abecb3399a17cdca789ef15e5a3e84a05bd82f81c4e963d8443483f7af153b9c77fb33e4234530093e4b61972ac6d0536f11f9dded25fc323c66b1f45e74f082b03aa8b4e3535149995e7d790bac81cd64524ba17bff000eebaf1fff07787cf9517289e76a977dd5acfa197d01064de0cad533c9297c82ee68e2c0bd9525ec962d1af7ac8df1acb9c52825896e4b50ebddb17ec8bced2a730b9340e0b3a0394ef97f2a63a697d0ef42da1c7d1c7a897c37591b62fa3cd19c2842445af655956e42dfa9c9dac9a3cf4f2802ab9c47eb9de5fd546fd2ff7e1878e76ce0b74def5e5bd7cd03ee44ff9a8a3d52a9fe4b3dc93fbf21bff4138bb61417494e581fcceee91fbe1f03cc7a6e56afd94bfff37f1888cf6fc989e04b7f5581eca1f861bad300f14c5cbb85feeafda209f445cb592c06c100ff78e50ddbc3c9c95746253ebcb2389a37b31f48294a0634c7fc3e1658f4f7ee41ffefe9777ea42b1142d8fe589c4afcccd52a1154ad1143daec56d3657d0a5c818c5649646cd8ccc50f617f3f49d52f2839b0537a267bc001d5a43b11a0914591dc957145b71a2a1e24a233d57bc6bd934e550f1610624cc0d01df0a9c0313cf0d41be96360498fba75c946b36550273d0e10c257ce08c363a7b66087dcbc5fdbb8fede79984ab5c8b665f89ae93708f75f6876eaac4e816f34aea7bc0c7024d9854733925a369056a395ae9670b3c93be68f95aff7fc7237896abc6430e82caf9b899193cc2250aceb58fbf56a5fec8973c735e9f700975351cdcb308fc23432c43a5345dcc8d8a5a2cf46bfffd899ab579f5ff021eb9254a85351fd5fc7a61255ea9d71a68312a37eeaa1da1f3cbfc348f356df6619e64ba3043a5a1d445a42b948c736258831673596bb09b584ba5d5c9776484fad5eb5ab6c56d7852a658fbb2ed2b21b887f4fce15cd1519979b1324391d707b2e190dd002ec2e4c93ffcd203f8cddf7ef880ec4595e7ab36f788356a6c496116d7c25590cfa464651e2bf12890a7673134c375ac70ee3be5630c4734b57ee63efdbbf591319909085a8ac8fe2daa81c1370eba53cf737bff8a0dea6cdab39a3eb249580bdd732f218bc2fa631994a0050ffd676a3b2be46bdcf9d58ffc13b9ac673c027a90672a5590815888dad18bccb0b10d5e3b2b4bdbc63ef13ec1a07e37797da10869abf1011a94a68bcff5edf27e1db6f3dff79484a0884cfa73289d9f2e64975556b36b683d5faf6e3625f0b06cc37688ba28649e097b120e217a4c83fece67b458efaff0eafef2e3ebfb9ba3e9a85a52aa5537f9d403ed9d8be9f5fd80ebbbaccda6a97b2beb85aa888aa4acada3f16e8b9ae5ca44ab077323fe0fe011dc83079cda2bd8416fa96cf8a5222b8a6b82fec99fd66c9f718847e2ec7b4eacd5ecc273993eb4e3f5733344ab718ff32139ccabc2fa4bdd793c7a5fcead1ff9b5a7f21f39604e8ab25576856d1e816b0b732f0097183af852c85c004f09e6af589aa22a7b669c07d41a9f1be867429dde468f57d094c4d826c01a021b9cd7213a6036b5530e1a9e5bf8c43c27bd7e683be19c9706f345ac313fa915c2f8443be8d18778ef01b45b3cf367f8e4a70e93533e175bddc57a94a09b4966d3a3ef674bf544392aa74b3f37aea17286b9f2300f062626d127ec777e3f27ecffd9dfffab7824c7b9a537e89f08df28cd95624fe9297d2f3394d06af1c82f3a50775bd3dab0d7397c24e3698d615606d45bcc9e975e3f2915661b221be33b9abd46bb6447777341bef4befc381ef9268ebd3f8eedb5f2a60c6628a2021b0efd2cc09489268641664a5963e0e84294c4affc8121d7567651dea7e5ac72532ad54c2a85da80375286ca073d7119970d73cd5df4d0aa9a63bd6045b3e5ab32d28e3857f89c9ba2dadfd1f5e4c7588b442333a93056a12d4a19bfe0913657f865e2b3f78a53bee6babad7fe95dcd7a3abf8eea37c43cc92a0893ea9267cc33a27133223cc3797ba32b9ceb6307e727f8519965bc0b7a00d4a35e05f2117f87f80afd5f52e76bd62a085777664a9f6e2fc2df2f51b9ebbc7911a745737e97601b933d03fb0d570ee0a77ebe66350d4c6fc210ef2335eae1db7ba23b7bea3d35922bee3dbbefc7b7de427ec4ff4d4ab69b7f68de8599ec8bc2dbedc1a57f0216f044b614df58d217e67c32da27471cc29339cceb7a6a203272b0ffcc60c9743cb61d545b0b5ac7ef27971e22a2eabdbd6de3a5b57db6907e0c19527e25f31cec3190dc81dde32c06da01871d76af460debba55913f0e504bf00b717aa854ff5950e07defdd2a30ffd3173aacb4d7efd7bf71ee4ffedac2c8c25bb47f2bcf5221830bcaeb773bf3a2d699b92b69ef1d1ea637dbd8f3f7dfcbb78e4fcb457b71483ae04ed8869baf5b7976b59bdbb0630e74c6e7b85ee9a87eeabad937c7d7972411f44293243d80690eb379c55be0da1eeac9d4dbe920c479f0761ecda6b645b86389ffee835dbffd27b3678aa8ffc04de803accb37e535f079d785ccfa724d044f62fb9ad1d71c4f3ace3dedb46f67dee7ddbd70ff58e119e43ef8126cc36de26b7bdc36cd37a63acc89c2fd7b016ca689b6df36d7151d6e2aad80289b13424aca7755f9964c21b9e63889533c8b4e94e3f007c883934cfdb0a45bcd8a6132d5ec837b6b9c2ceb73fd74ba82f3e847af88abbc6e2f7b3962d323f9dbc2fce4dfaf79ca622f2757c5dd36fdb9ae87d9a2ea0f2ed6dfe8e735dff78eef15fc723cf750887ce708ecb75b4a571e1bdba39cf649890d9e10cb7bdbbadde16f12b94211a2b2540b6389c5a37b6096f577974bd88dbc2dd36a610be17c34ca094b64fc37dfadcdfd89e1ff423a7271d00f23d71fd1759822b9c8ba3c5a5906fe6b9623f2693610d4af023edccc117bc45a625834d8f26e631ab0cbac8b7d3c2f407cdc281b97730c7e5a89d881292b9b41c65eac599640e03fb6a10fbfcd02b039b1e5a8db29d7996ce987df303b8c3a41a8b2255819bb7e7f07c1e2ff5a7a728ec2b4efcc5577c538bbfeb163cd7f2f121323df2d969140c82c9f25ddfdfe2a907fdff28dacab16dc7735bfef1f549e2817f118fbcf60d530c9e5b6a6a566a6c9965c33aa56c08f53b5cbd52ea9447effc53d83103ed28f3fe4ccb02b90cb6ac5f6ee75b0ee18e18c5ea4ebc12f6ebf7ed62cbbb12b0dceefdcb7f785e773cf213dfafd364eafc12fe5d578163946a9a2be4915609088b988909eadf6093891f11e60fedc4474d9bcc30866c762921cca2803a2bcee8e2be703205bc9d1909aacf4e4d6f97dae75630b6f918f26384b74b7a36c9fb19ca76b51503833f6ad095001afc26ae2729d3f15642d1194dceabc37d6daecdefa2b59759c9dd0a7fc6287fa684ea913ea1ee7dc86b80d98a27678c2cad5e98e1760dbc6ccccfa26915f4dda9c69bfe50fde37f1b8f3cfb118449ec2dd13e829e0a88d3737bc56f375b1926b54026d8bafb10d22f629e0c9e916eab8c879980ba82e707b65c2c987b02b17a249b6135c7bd13f039afb6e0db3aec8ffa91878eec803cb6b599863e0707fd9af0664870d3333f0dba973a0dfd2f6c1b3c2710eb549a8fd741c7aef9f6d046c1bb8bac7467ab6cb7db5d281578ae4ba738ddc6fb28f2897b11c5538ebc55b7fb66eb0fb6071ccd01a797931644959ae00e524f79f4eb40c5f60b3ffbdec7f38c53befa8c571c6253dd67184f5343bbf7777cf363fa71596d3f91df15f1b58339955885dd2a9ef292ffecf1efe291c17d6fbe613ff249353360ad53dbe3351404e8959066da11c7cc23f7f2d5236f4fc5767bc63ee20dfac1975bc88f113e16f4a13beb6d6fdbdfbe6df17c2264bfb777bb009ffdabf6fb0fe391bbe65ff73dfb246fefae5d3690b7ef81e59a985735b23597ac46acde0378c4bc23e847fc0ef800f7e16fbad9e88e4faaa4a09ee49aa0b847b428c97470e03f6f87b5a78f2edb90257e046bcbc0fbeaa4e69e0fb34bb1df1cb383f5b9fd30f906d9f0edc8ecc72697414f8beb02eec0ab96b61e2ae21ee10e775c86ce7fb4b3755f785ddfccceed725914e9ab7fe4db1e3eab569a6b753014bfb71dfb0ad6ca2c71dd43be63ca9fd1eeffdfc72383bbd6aab39d50c0a1bae099e6f28ed6822270cc1d658a0103771bcf7fbf6ba1e059ac613ac13d840d8e4dc9ecc34827da4a17fae4e83b6da7ef8ca670346477e2177dfbef34faec3b5febe7fd25d13b1e500e25596532de999663f206d126d4c8e408e24b006fcc2fd083f76d9c0f338549443476fc48c07a241e4c7e9e2606e9426a357ee17dcc93d65f84d55b207bb165107b3d4d0812ef72569673e9079123e79f3b4bf777763ab91dcaa379dc3958d1a19d616c1ebb19601d9ee9f0c9c3b7774aaa5df6b6f3334f95c8975d42e68c10d5d9a7be53bf7b5f4b6bde762eb545f7b84785e8fe35d30dd6b6c49ad19873f7dff023ff2e1ee962f40e8fc0cf7d7a6855445b3e96765ec6ef7c7dd46a8adf7580f1951616e2b2771548bf39ce9b0fda3e74bcf7290ee63f15d76b9d1ab817e4579dc56fcec7747e108f7476a8c35d273cfbd09f96bb0b42d5933226b91eb0ed9dee15d64db43b3cf25437685717eed7c0fddda0f30b73d571cecfc30a75c8b663dd5f8ad86ed7056d2d3ddf5d77017018d08ea441371f7006d4d9d1e7e2dcd62edc45bb3846d73ad0f3de2ed9a5ba2d99cd3c67f38dcfd6d66562b0e178310d66c87f8dba7e91a7ba54e747ee7f6fef13aea77cf125aff511ace34f30c8133f8ff0ec3873e133ab9852f0bc1bac2780a3e9942633427e5e5fe07f138f3c38fe0e757bd285c435936d4f9777597ef02f8b89c13ff85bed1c444a1bc71505dd354bec47065867c4a7768e0e3aba7876474ea99701d1ccc01ce3ae46716a7ba03b3f02d8a1d7fa917fc687d8ad1fd950dbd0e74e86b3cbaf465b17e8a214623f47df6824bed8e0a77992f7e7e095f9f0238f95abc4dcae007cb72b41e384a8a142a48a50bf0788dcd8048c94857bd95fb061bdab164d3cf22497d566bbbaacbde3ee167bf9671e08e2aed17a96964cb18f1ade73644fb92cd7061c71355c82fe0957c234be9c6bf73a72bec437612dca094c6e83ddefe586625089b79be6e750dfcd9efcfe63eecd7fc3879035fabf8047b02fd94ee8de8baddf319c33923665b563626fc7c2ac2662a3b0fa9a6708f54cb3a81cd9fd2dcc6ac4bab96887d86bcd6c75c1df29df8181375b32a7285230370ccf29a274648f3a3de2c1438ff8ee477e329e6d0fb43bfd80dacd779ca1d8f66ed1ce7dc4fd1c843943547a081ef9861ff5cc9bbadbf0afb6fb51e780bf275343894e3b7ecd6b5124123c03115df56988c8cfc0ac2b50381576cb59a0cf77c22a4751d6aa4974b7cea1d71fae21cc8ed14ccdd5ddeb81616012c69769076dbd0470d55dfbdd211dbfa046048a7f58ab9efa5a478169182e0af6f01c4707b4f1f10cb2bd21ee4453541acdaaa29de4c33d2133d1c86c82ff060ef9dfc1230fad6e0fe191673d76f4b3c6235cb2de6de809b5ddc9d50a56164426c85e39e64492e4776a879f7b059e27cc5ea4cf8eee6878ef5fae1edfdb29bbad30dbedb61475305dd0f3c5792f784d73c742affe6cf68f7ccfd6f639da4e5d15968333da9d6df5491f7f57732078a4d336feaeeef0ec5f7e995ff5b47a61475c0df39dfdb8e6fe455e25b3acb6b5c4e411da37143cf79ce4c02628f212e33ee1065728420bacd8d6f2a7993135e696a9bbfdf49d634163c63599de2f3ac31aa0783c1399328faba9d6df1dd82457cc3ed6197ef17dc65dc9fc0638e9e20f6e8ea541bf4b31df7d2aeeee886204852f77276ab73c609de8e77a48efbfc3a7bb7fd6bf8b477aad1f39213cd2e59a5a1d565c3182d91f038ad6d8dd79d783ae2098ee059948d7bc7e6e8eb304f7609478aec99c523416f4dfe9b75d7ff7e69ea6fbdd60f7bed9cec252b715c8ade35afbb8e5865258436bff5cc3f8513cf23aa7e58d3ed9eba9aaf561aeebd37c15d2c38f7345ad4e16ae8ffcaec7efe9f72f8c42e80b69675ab5bbcfb06032f32aafe3eae65ff8b9c1db9769b41bbaa48eb2b1c6ed0e01f43e01ad14a8e3a315ce1bb7dd87b322f942746f0aaaa677c16d360977f2b4dcee46bbb1218296f283ff053e10bdd1c8d276134350e9c40e26fe3959a8c88475ba261ddfcbbaeba29967d7d4ce89ae6a7a55e5aaae1a4c924c2e4ee4522a6821eb07d574045dc175a5673ca03e7126fe6fe391e7b90f9717bf82e70ee139eb84a7b34f3edd4a3ce02c3051b839a916efe319b8a1cc51227aee46b7553b9bec76d09b916e304f1450de262c361fa9185f550778bf5837fcd58f90d914f63f561f39111fe968aa1bb5baed449392d87f9cdb69f5c220da30f4afd536fbcbe3ebdfbbf7211af2f79a36c239fe00566d35533dd5af78f562f2ccf966355732cfa46aae06e4b6cc8fab717bbf1a5e01b38911d2efa957155d4f3c0f92cc1604fdfc262cd430ef85bda5602d7016e54b0f68199b7d8631683592dfb3bd1af2a51aaf566698c8a05c6d3c666bb5e70e9a926a72a9b3839aaad9e643cd3127c20f0b3c2b1de1521a9889134a6a7b56bb7bd56b67a4fd37fcc8bfadaf75c71e78af76f8a4b3eba42ad8d832e00db5504b2fc62a691e5144d66f4e118be01ba80bdda714e8d28a2ab572dfe949f8d6e4d02f8eb1874ca58ea2d6f15459a837ebe6b0aaa9a25817eb698c9ff0c74fe391e7595ff86f9a55abd112adc209e8d43ef980bb2dc675f693f48e355dbee5d23e739ebf706c9fa3318af48920bf6b2094cdab53799bd6debcde190a689fe0ff9ba48e02b320ad11d878fcb39815ea4c655416dbea41cbcd067fdea7279aed72c9e765a9cf510465bf72afb16f5a79b13adff9c927a5ea32c5b9a9cbaa9ccf686752856c6bf5ad1e9a39d4ceda4e2e624fc9d485cf23dc5861bf0575903714e15de60c3d493550baa03b4ec65beba3f75ff1c1ff613cd2f98ef8cb8c53bc87511c5a91f9f0f459e5d5a5c1c3ec5517a1776483b84c4c0414b7fa3ea52b0aaf0ae1bb2108ae36ef7a0ca94087c99c36e9cfa3275717b40a57b4ba52c578aa4ad097d8e6b73a9d949fc523aff3583c6a178f0a848a7107997f67d6b4ab1ae7b89cb67f847bf515f6ab0ff96e3ee02fcf733ddcad867c4ac9858abaa6d4ab1b8f162be4a76c84edba7acc156a31a48a073b26ee6bfdeb8e529c0f6a0fbd1af89e8c71bf0ac9098ed1aadfa872dc27d3e13aae30ee1ded59ce7aadc9d416ebb75c318ec95545dd9a6161749ced7befa8139bea4e55f300f99bfd65a6a5b87e34a51c85e04631ddd0c89f608ed6e665bd7c9d75f3cfaed17f138f747681d8dc06e72c9eead2948467d60da958572956575c493dacd7eaa7393094ac067b68389b55c6462c7f8ccef629130d21d9a8c7e4442928961d62adc54eaf175477ce2017a22c2e9fea2966d4b3da53fbe879fb7bdcf9158f3ccf2ffc2e4efdab78e49e8bd1acf56145a373c7358da7d54de686201b0bd34ecd1397dc75d87fed017c4cf7bcd71d9e725d541765c18a076e02d979ea9b3a20bdf0ea3bb2241e61a5907e7fd0cbc273887de80cd6fa08428013192e7a6ddef08c711be40331678a32d40f7584fc88f9ac4503d1afc1ab6357054c08d780aa31c72a5d2cd4093fd2409bd8bacf0480d75d0c6581de7e4f696e2ea86769095a31045bd280812a7ab8d7f6ba2d69423b33e4ed7e5d7f32f7f8bf8f474ead1fb9fcd6cf38f42337aeae7a7b631aeccd666b38e6d85080055f1898c9a7e48aa6aedd8b437ad270ccea76b5101cbf8ec1365a65a8ef689821f5628f9ef148afb51fdfcde8fa7fb55f8f19c411b576e4da368f4ee07abf4447185774fd23246744f48feffc82e1a33e6dfc467fec17fe14991712184a992631b2ef6a756119cb20b5781225e523c04168e7f2b771d803b51e7def6ef7d62fb3c93c7c2d4fd0a9564fd880ccbb87395bd887ec55ebc2f131e9d5c1cf8b70aef1a42b17696fb3c14cde3bc0b0bf7751011ee1f6ee86a676e8356d7f3e4de6aae3d9ea54b0f0f7de651a4b54d76784d7c17dc6f17fc38ffcfb78e479af0e7eddab8f581e3f0ed1caf63d7eef5773978e6aed986c885a8145635da86373dc5faabe23bb0b2a9d59504544662ae87c1368c0523ef082891623f62fe9fd1cd0e7b8ca131e79cc65dd7f33a3ebcf7d49f79a964b40c5ee667f35eacb1eb3302e5f7d40abfd8e5677337a6101b63e84fc8f70a0b7d76e57fcae3ffcb9f60db57bf37845087ab1a885105915db592d89425db46a160887ecf601d36c74ef847c07f217fa7e1f52ec179f88af13d5a0eb47df969a6ab8b70c7272d0d156d3d77e71b5d7f4a1d3d9c73e7c88702247abf65a65f6d13ede2725e70feee745a24d659ff26caac1e75c87f483070118a8d96731c37fee73982d42b0ca93dfff6faccfff0d3cd2f911ef4f9f4fe6a2929e669fda2e4a9e12d97db12ff795817c09a875eeeb50de9aff1f7bdfb1dd28d3b57b31cc5948c8b63c54465948020133441195500e577f6a570014dc76b743bf7f9f6f500b45a8b8f37eb6765e9a977258627e0f5ad3b048306049de1ad64f7c8225c2f5905bffc8156ff9631e728dad22d98a6f2b4f259697c1a2e113bf01cff18398d8d32053fb51e0f14b04ab9dec7c885e7f3f7f3cf1c183ddcc8fa579aedd8edbda65bcd9971cb7ddc49a3b68ed45a7a595b4f26230c36c417c9d0ea83d50abbc3d366137e86a55d069a05e3ce028970ad36874c2eb426b7e1549dc02e82321e8825a4dab6b8dbeb8aed839c8c286ca6e24b714ec7b795b57dbf181f0f9eb1a9a2bb1a8295ab3d15aec61ed48ae3ab56b15bf05c7ffad3dfa5ff08ff0b37a2be7735acd3014456ab125314f8223446517f005fd41dfd55ae352185ff248999e6dc369d839d440cbe319f29b195d031eb4f0bbf87eaf0809752c05ec29962ec3f363fd49f4115ed3fb9627fc8e2dc5baba4f5e2cce634fd7da60d7d23a801a0a369e34470f722c69ad74ad4bebab83ad895f6974bcd2a67923f8fa0b1ec279138b97a238287e54680f3a43ad1795ecf1f684fbd047b9a8aa0dcaf5bda4a9c2d8f6f0bc76fdae8d883d6bfd80d78305a40ed68fa0d46c40cdfbc027d1f6aa528b43e5007629e120c4f87735cc438a490c83b6b10575b1dee5060a4143aa13dc619209809e62db519c02a9a99eae3b8db98b0682369c9a61077857794db0fca9ad52f8ffca3fc269ee5bfa4892b36c2bcc67c2e4e2a9caf0ddfbca61e6ef506ba48db00470b6735834b68369fc02f555459a0f48fc2c1013cc30c5e7833af11faf1239973c4bdd25b82896f0eb5aeceff394d446c7ee23ecfcb86b42d405b76571bf06d13320771f6bec4e87605b09dcd695fa14d033964c344d4716abaef6eb0ca60c460c48358a7eb05cbf150cd1c5b0730ea6222b4bd937ea8029426ad106843e1709e65710a80ff8786affbb8cce8d39e609396f367762697122754ccc843ff338ec0ba3f9fde55e887693c38b36b18dde90d60a867c18b044efd1b90eb5bc6e79300a9607cdd04ccdd224a147781cd5eb625667fd27f8c87f5d1fe17e775a179e4a4b807d41f803c1ca90a763b059452aa653f6621a954af6a16f1bfb0d523607ac0916e0ff8457e421ea5e2c10fcdc3ac1f12b8aa9fc4b75108de48f8cc56bbf4696a7fdcad6f5685ca90d06ecfeeaf834dda10641ea76d2ccd79407407d1488d7a2fe0a1e8795466fe0ef552da7e54fcefb58edc4b24cf3cf89de03d5444f987f0daac7822657d41dda085ac1762b6d88c7c2f3b2988e493c6d4ed8f81dede90a6f808e9bdbb6ea782dc6276f7b7002c76f6f91116fb567a19bac599ef856205697c7c4150197c676e7baf6522d96f48608f5a968659f85e774ca0d617c5f9f59b82839e0595a517b8d6c5d7457809f45faf0d332ce7f531f916ebe3709863a7f0fb4e9c268db4ca4b53cfac26eb7e80d965ab5e5a8ad6866305f2cafd37dc17c07d3b2ee4417bc916e27b67f8fe93998e6333e92e503a6705f67fe77f1b7182e8a28bbf1a8b47c9d698cc6277913807a40b04ae0fd753e7b9a0b98d3a78eeacf0f12482aefe121d3bae657f151be17287ac547b9fd517776f338d411e61f2361acbb8185f586107c13244f12e620146e6d47216041d271403efe34d4f1eeae4021c692eefb36897958cd0a6cae289e724872cfc1af027e8ec1e9550fdaf585ad87ab223220a7f28825473d1a74a80d32e521a49eb12c4eb1f4d780d35253f4190a00b115ee9789dbfefe3dfa5fd647b2fa007cce7cad84d6f15c42b0a32f38eea270a9b485f1e6499fef8430dee5406f2178284426b63d7db17fd197c3c8912b5d7d35a8e8f106f9836dc3764116b73d4cfbea58a6e6f5d88724a6f8312ff928fe16e78d437a9dd785f16515c6584a79f532f9dc2775f77252316f21a7a61ca1346f3ff187043ea99a5d47dcfef5111ce490c51687e4ffa43a8fbed637ddb1be6d2fb6fa0ead0ba7315a628a51a7f53c98fe56b4eb37eb332292138b91c6af37ab89be833c186faeefb70ad80749ec75ba1e32bb42ccae49f953dc779e5635418d84cb7ad4b475a851a51ff4a37ecae0618d93b9d36a1541d7cf33a45fc4bc5ea2be75e2f3ff282fffff431f79ac0f0499ef7d4eeb6115b1dcabe965bda257175ddf267924f059a01ca2d9a2a9d72ec330d6eb7aa3dac3745919964eab407035bd3978294f859dd8003a8965ea6582e7640aa9bde59e37bc3f3e2bc18002391ad3c899afb79042d12c88f61a2671b32141a0eb1c3a4eea69cbe6f6b1b85ec243d0fbfa489a374e7c21758244379d3b5a7f206d57da623d4080a1a294167a9be4dbd371537b5ff4e6dcf3f16bfb9ca31cd648e9bec421e87e44bfe33a8b45ed4ff83305741412fb551c998146d74f18e99dca45afe9dd7d80d7a74fe67d41fceb54df00de8ef5436130dbe93db105b64c266dcf990cf1337ce4bfae8fbcfdfb94d68c48cc6f95e91c0bccf1c7417f230d2b7a7f6ee903af171474b555ee3b3b0f2d4ea25b740c7da88f76c5056402cd1c176a3c0553bdd6aa361b420130ff84035ed503b1a1c1fd8bf8fd22892bfb7d0c478be838443e077c28dbd7c7c782eb134c2c16b7c5f2cc299a85a56b04bb9dd8a43c312015273c07acc59043f89e1e925c531ce414a391c416a3d76317ec5a8e7b69ac517ba7ebd110d3f16c8ee64414123ded560fe375e507fa6451b273eda36ee826d62798cf22f1ab705d4462798339513be123a15bc46eb659ac7549cf5dca8d068d8710c1f65825d6e33a7bae16a8584f9aea795d0e2e83a65e1026b46e0c0ac4dfb331fe9bfa4856eee7b967d21bdf333a4ff24862c869c7f2aaa53f950fd57e34d29f9d82fe726a3b358802395e500e593497cee9bb36d05a4ccbb12262e7d68daa33021caee239162512eb456b5950bd27e523b290f5a9bcdfd27cf639d19b467ab1daa215e9481dc430e51bfe1c7ffe8a77f185c6067be1dc01cbf049050d9ef9c6c30ceeeebb8ddbb602c4f990837513f40ca811905f32cf358ca0cafc13291f891ff2912c2e22e605e5d7fd4a393564b4f411e505690c35b18f79c967a6a08ba6fe3a112702d33d8289dd9d90daf41a7d16d65b2876d682e06a7ac2022f0b7ed67a3e962753ffe85fa62af86f84d856a6831fe223ff6d7d647c6363e29ff336b6ddacff81c9a994169ae2ebb6a15627ce0479dd45d75e0d4aa841a3f67a078a6b9845b301ff418c6cfd301e17c2b3309eb8e2eb50a47147a2e9a9cb6d868fc899f6ab71657dc15427d12846a3edeef4d5cbc4833c3d909aa80f1df789a0512369783c89a4b24e0ec90445d46159b81449ee63f5cf93fa85bcde7d694df5925291443592137488913153e3b021117f43ca4786643dd2f8283e0e6e6394087f158358182fd6135fdd4c02afcaf801192fc52216a19e14dc47079ba2df8d04bd1014dc83ed831d4da8839f4b2ce06b0cb8f0e2a839a7b110334f508378aa564d41ec8fcbcb4d68cb6831093b8c474d35b067fec0fefcafeb23597cdeebff5ce59908dcff40306119edc7b488e088abf380e4b3edc745d73f3f517b11d0eac0a7b85d595c2a54407ab89a440b4b18e3cb4c1d0a2ac965b8aed5ce79c34779086f21a9e187f912e0c5f794ad5129d8c64954f45d916428b9e10ebd9e103226b3306e1f97e7e5b353b32d7c6ac0bf2170bde283f50739924f52c71e2cc16019a0b1be30def9d4360efdc91cd3f2e8b61ecb6491c9217fcc4738afc07c71a74c9658a791139e11dcf090004b9981d08358afc96a50099ef0332fcc8616329f97426a87ecc066b673bba7a08a7725e66993d83d0aaa164ed6f5a1dd9c525c949fcb43fc6feb2357b6f21b1e72ddb80d65446c52c4fe055a1d790fd172e27a32d9400e03d590d15310d0d392d88f425a3ba9d646cac5532693eda97c294f76c75c50059bd7644f7c29d7b6ad8ff2c8b4ff1ae17731c16c196bc2723139d8b97ed151b71d645cf24e6bbdb1731d6372ec0c27a7edd4b556d5e5e9b0b10d64429c16e721b7b9890fe3b528e608e49183cf9e4a5df6490d68140cd481f79c56f4d49bc711ab59226579e5f0355903f3663c1c67977e8e750bafd72894737187f1c98598e6779834ee4a2c1ce3f51cea4ed96e6788962dd4cef96d6243d3080e32d5fb446160bb9bc2e43c2e6edbdda39e3f1d44824be6372717cdf2bb62c153a71ae842ff5fe58f70faf4285eebad38294aefb8eccc3e67f1bd03ee9367715aa4767750550347a1d594494ebc8ff5003b13474b2cac0e527680cd3e1b21c5365dffb019f42725c05ed19aac8ebb27723de87d3ee2b3bceb2c9607e175ee11eafb0596306c3c350cbd32294f2a93aadec127a3b21aa0aef03c05fe05f91b6a69daa8eade2a6af5492e9f9fea2feff112d0f0299244b343627fc34a82040779258a8e1a935ad011b43b8c183cbe49fd866f5cf9aac87b9fd89f80fe0f087d0f921a93168bb966bc1762b6a2d63ad8e353a22f66834903e5268abb11e5e988e4f0503f0a89991046a568e52265d2ec5a93d6a40dff25a70cfc6303d069889fe9ebea54bdbf47ffcbfac8addc7f850fccf8479656537b499dfd87e235c6e0ef10d49e7eea637dc4075acaf07149ddbf144384f2930be0e882643283da51aebd6938a7ce50180783c4277fad2bdd8fe39ae7a5588dd49753a57e1cf74864f58d8dbb33829a7e8a309eb7ec606b0baaed4f3a642c049724e84f8dad1e993d7b548c4512e78408b6631a97f5f00a982734b6b6d95923a8c253911695d23a16797cd8613d28950ec298d463c9113f12e7919a8d44e126a6e0dac6c56d5545e23319111fbbc5f80a8955007f078dfd055e31afaf62d768b5bccea45b6e3895490f19ab95a82df3ecfff837501f7750f4d7a383a36c4fb5de1a72446dda37ea73c17a4b2dc3c31ec542bcbdbffeafea23f49c527bfa2c79fff1dc805ffd8ee661fb602399757b613774544283058ee7e45cdb86c0de83f908e00bb3f8298275b83f4ffa905747741cc07c67b8ef49be839960ad50daf9d806977e766b9b4bf5ae80c4cb16333c95d2f78b6f07d549695a051e07111c3c868bc70abbacfefa356ff123883e2158fb225007d0bb82d025e39e3b489b0c2aeda64e6275af75ad90f421facdb9b76ec665ddf09fa2a04e54b4d4aa5b6332b473d1d30424e215d3573ca8e1d8ea78ba3d715a8db5d39a8c0726de95301ff03dc16661facb8add8fdc1f6a5c41562fad09f98bf8badfd93bd9c6630e6ed731e523dfdfb82f3d64571e3f95ffecbd87271ad32b38bad46fd31a809cd602af20988719cc72a28fcc18a24e4469317a09d0b632d16c2fc107a1f633d07926949692f86199f19571665ceff5f19666a52d247a15cba1c47cb08ebcc9695ac13c0e4b5cee4b261658c8ea27995c45929b3177f61ba83142aa6fbb4104995dc10cb0ac1c63ffa43c633ea5033e4c269e81e975781ce1a7d7f62676ba535d1cd65db49ce893c9c4682ee3ee748429ce1efa303187e35e30b19009e8aca87e9c4ca4490effaf296a586f7965f1db4f5b7b023160507f5dc4f3b22171c025613f91212289c41ab3e743dc008b09a8323d95efabfbf9fe65c3ff0d93d88b747f523e426dfae6b75dbd0c0d0ee31df98c37ff0bee3f27fa4a7152983cd9b9f9147618c50d863c6fc0cd85dd023c03b15a4d8e377906dc2982cb1ea2574052db3bf658bdf85366db0a19ad02f999c73779497f8b8c06173fd4bfdb96d0aa728a654bbe037bd0ba88f52989f2388804a4b58759bffbf47338dd840746649ca11320039383ba3753743851f0fd048ff9925f4ac706d4a6653919c5741d78ffaad617ad73918d8fc43b4c8a2bcbf5a3c278a49d0f0dce7b824aa33c793544a78b5ed750050253b372417f0e4acbc57cd9888ef5606808868df5c25ec727b9a2704fc8be56882db344b071a85f863e6f49d686f3f994e7673ffbc8fe243c11afc783f5fa093ec27cd779c0b91204630a67959c57f94bf8485e2889f9e920e81f1668d9c2b414b09cf65bacf922c852f2e84ea38da011819455df631a3bc0bbcb63df094ec7700cb4556cd7ef0b11d862081d2966fb9ff20d42b38c8caff9f7e815c8de70bdd0b9a0be6f2c83bf4ec263f3b8a37d82fe4364395c1dc4c744c6e5d2069f392dc3353cc33702a0cd066040e2713add0045552382f82abf43e2a0ebe4590ba65fdcacc7e7d600f77fccd682de4b5b088dc88048c6d6c69aa2a90a050d8338a86e4d072aa6aaeb1250267cfe835e3fde0891313716c652ab453d6305fe9649cb88d527e2b3c7f2015e13d0570a44ef845860acf788af7e531c0deac69af1f711e00513cce01427389fd96bbf6e57eb91596781f21171295ec465f9f45d57a16cd7f1eb19963943b1242af87a1103f81e3efffcfd7b48a888e5a8d80c6b2d63e3be9ecd6e7553eb56cfe6e5d5d89e06caaeb4557670bdbc2abbda6cf25cdf1b3b633f792e6d5b4f67e36ce2f7879e691c7bb5453ff68d53b53475a6ba581607c6395085f2f0153f2bc2fdde93712cc5157e6d8b0e7e1f90f7bfdfef36be06c605ee639cc58150364a623b6cdaedea603c72c6caae2ff746ced4289f0667d39942ab769c696f74798571f9a14bae67d3a838cf4615b79a513f1bc6d67d353646e3a85e2c43b117e2b46a607a7c5177b89f67a162346bb9bbf5f8d4fc6b537189e7bf84e703ae6c5dfb0aea19adce93d18e24a323148cae88c44658367aeed8e8a39a31c073aeee9b9bb2161b43dd76e7c6c8181bdaf942ee1b8a5343174b35dd98188661469a61cd3b6255ac18929113a76245acfacf0dbc1e46de16c5397e2eef4fb2afecc6c7f757bc23eb51c2eb51baff9ec85aecec7c5723e714ece74073c742e3f6bb4fdf1fcbacf3ba21b740171950c9a422391d9a71447debc02f681c2da9945677c698dfc894a740b613fe3cd7d1b607a3b031aa8b6d6e7e5c3d41cd93489daac4463f2658c289bc4bf84835e52fbf3317777c644af264a0fe9616d48ca7e80919fb8d5be4bc90d46591086a1c4187a0fc91d62fdc6f6ddd78365e4ab3cb08f205d7581fc1745a191dc6afa182fbfd8279484e7c1437f0703dfe747db3b417f80a58e1edd5611be591d1b8ec87425ed860c54a9c380dadb2757d6d8272db8eeb373a467199335e97727030f142ee66d037acbb0c493ee265d26a08ea2614d6453bb0aba6ed0fcde9568943c0c4c1bc8461b25cf3e847bce397fd97d87548317bb2ffe57c246373f99ee665e43bcc43ee7cb89fbfbf3555e38de9b8826b1f2f4e9aaf11b11ab6dc86853f077d05c9e780e82df8f4e02bde7dc4afe09bc87463bc13679a6d548ae7fa3450fbc2d01fac26247f2f2231ae5979378be5f2ebf1dfdb50a0d9ecbfdcdf5014fa8b89e91d36501f12aaa45eeb1f1c6988ea57745cbda1e96f0bf341138fed325174b788143330c392c6e2a3cca4eed72aa38ff01cffec7a7c768db90da90ffe8fe55e505b15473123943b16cd594d227a918a7a68b9a821a594473973aecccd055ebba2b93457fbaaaa330c8285b06acec1df6537cdd850fcc2ac622e3cad550d63736d6ecc6d65a00e49ecd923fbd6a379ff75dfafd7e3917fe436d6f3abafdca643fde1619ab72e5edbb5fff43a16a2a0bb1d3b12d6044b199c59e65fe73c24b1fce29d75b6086da6df23822d68731f3cc93797cc9d531ecd268766653b6bd6471b61ac625d25b17b64db7bfdbbb7eb831f1ef2576242cb9c0c06882e8cbba7f30c698cc7bdd0dc42379bb1cbe2be4e05a8bdeb74961d731f6319df9bed8ae6016bec8de6c8ae0a1b82b14f6d4360fb7912799ec7f57ac49f9fffccd8c8180856d746d899c745099fd893ebb7907db111c45707fd295a8ee6fa74571d967bd1481807a5866062c151999825ac63507b9b6996cd8a59ed8ffdae7da90fe60db376515d7fbd4146b8def6b4a359ef0c83fa4616a90f6b78d31ffefe23eb93f28c98db19b3e3f90fc46b7d017e92b08b0fa5319ebddd350e3bb509dde4f241547af16c222945eca1f54152bf36c52244c64e85bc0bdb404bb331747dc025d4129affa7f390d6d5e2f141c1f55884f1ac8e5a586af469fe08f58f507f07ede3b10498ed4e682ab1b8761c1f8fbb4e2ac315772f9ea7283b24a86291208d87894f44121ef96edef78fbcdf6efdf3e433f021cd836dd36c3a4acb325b11c48a99a43e952a8c04753531db7382cb295c74dbecac43fba526da0ae17580d10c68e60bb32b9a612bf2cd9ee2a2e5ae0e58f64ee7384146e084b1269be0d30aa88753b89803a1f9897549e3b5aee6e987e2b5f29973197ec867fa3bd7a2edea27538daae8f53201ac7686117815ef94a9e98a4fc6e535392190476e93dc408e8dc8b0de81ff101e642d2a95cafaa2063d77b109fa899c9bc5f97daf9f8f62cfde880fb2d146d87b48816aa1a47f535e8724c5dfc2a7a47eaa994373847224f2dd823a23b4aa9bfa12b7cb2ec44751bbdc1bcfe75834a97fe44fe7ff36ce8bce0df1c197dda03e3ea0e5d634c7c146d4a603c05f16c610cb4d304ff07fdd93520acba1bc3304d1ef884f428d488775e6bb077d2f6f6abde2fae9729abd2283c42004900f641ba66eaf829adf9dd70f47c1d9bab5ca83fe7cc4f79e5d8f9b79fa71bc5f3fc99f7eec8ffe930634449b068ee2f4c0ee9ee0cc321e91a901c5aa9039e8a8a5bc85d528e419b5117fef319e4268b41ae7f08a4c1a07df16780cd72dbee1fbe3bf6e21e6a919ac1681e6db4bc265e998c62e706d381d9079e566b0e769ce22ca0122a9699a560c91373364948a247a536dba8be3c226b8ec0477fd2a1ee07ecec307f9ec7fbec694a7f0bc12363f41f5b8322533a73c9d9b44a7537de89f4cbe2739f0eed1cccf44e1321db87bee6387ba88806b4031edb526d4061bb42aab69c951594dac27b0d85f2cdf890453360be693f91c580cef86f6e9a37804e97a84f7ebf523f15a577c84d41ff93a1e22d1fc6bdb335f2607a4ec3729b608cdcd835858ea4be7f9ded04e03f8cd4d4dd86cadd84c7d3f8810ac587855042cb40dfc019177ef72247f8b8730ba456ad5dfce03f8f7a363ce2c6e4f9e1364b05478ff68ddf60099af16de04a705a921d50fa0f6fbab653b4a7b6e4de7f5040be0513faef9fa57ad73966667e3a031cfa84e2d6734b390e5964b5ec7f200cf1feb5e225459724f5837e37c8fe3acc9cc3712531d4a387aaab00baada5c6f2dca9e087a27a688b96d68e75673cb0f4a806310f4495cf31deeca87d6e7bfc347bca4fec857f1119a170d397f2fe6da51a9ed278b0eca30123358bac04752dcaadbba5099da1950c539ef74fc3996ffc177dd3cd7b136cc6953c068ff9ff3915bf9d7649f17a76a8c355dac673c25f9ea290f21f10180177c76c3a515d018e1930a15d53c77f5ea9c2cb82fc44b9ba476e4aff848b61ecc6779c8db9f17dd832e0772a93cbb7865b4d4032bf2517c2631c4a476cc6824f4049de1ff5f0017056a0840bc318b9f0ba71ac4500be3d5405943ade2a86acd26136bae55774aac12ecb080e4a5f271ddd626f8081ff977f511b0a75bc2c65a58cb6d27b16185090275b6462c93e74f832bcc914c4d7186c9ce790ec9eb23b56cc565d551763b4cff58ed5ee663ff58fdf0c7fa404ab7b2f4be208841390efb6dceeb32c810781c01ab8e8024279c69d60a2a5b5b31e86187de02eb4fd6dada001f21f16616f1e1ff828f30befe953c24c502e0311480077cb1b6e2c86f8a5a75ba8827aab5b3f680296c1dace3185927eb6c5dac521007fd6edf2a5f287ecb7e992751347592cb78045d4d5f941b5645dd9f0f655918af0dabbaeb9e8b0d79aafa6d883f7ec0473eba3e26b3b9fe3d3e425f878f632b3fc747a61ae48fc707ab86163c7784e777d37ae3a94d88fa15ce262a428e1eaddb41eb13d24a6820f7677f4fa3cf1d778fa598c62bb16bad32b822fe27facde5dfec3d081db3eac22a9ad8e3a5eb84691e09c77f677cce77004d2244d04f2f56ac06e8521ee41ce62e6d82814563cbb27987f7bcc4177e81f7fb1b63f9b5dc2f91186a88a5f601a1563980ff0468bead805e62295613b03845d36a59ed4177a352ec15c24b006b4d165f016f4ba45829da56098391e137209f51341797de76d1b23a8497787fa48ff0f5881ee10bff887fe4868fdcd9a0e54fde1f6ae811fa31f31b4ba8cbcb6abb862c4337cce661505b5569cb7def148b84d7ef23a7e325a9322326753bfab6b1ce1f1b80fd486282b97f57fad0f81ff1906b3ec2ef03b58189dfdd76b7258a2a9de853cc0647fb0b35aaf00004f4dadea2d7a66b752b12d4a9c2ff6954f58ac8f2290b19bcdcdbfe92f78c8f7c6e7daffd11fc7edc0746b0b7488d12826943f4107c52b0447520fa862e6a9642ec58f9cdc0ea05155e1b86e4a500b6641474a1d60cc36e2ee2359878a0f5c3ff9fbacd83d31f0a2f565f88ee62b3ac0ff69fdbf8b27e3bf6f97fc03ff2f946b19ab06c6b0d46fb8ee1a8e18eecf4b0b44675a8539eea23dc3fa2ec782c708a4be5dde82f697e06d411b7546bf8a535c3e51bf937f593ac484d95d11041bd956bbcdfeb1a56ccffe363dea1375eac111ec76be03bad522d3404960fce302c57628ae39bcd7ff1bf441ff9e81ec83e279dcb50947725a88705362de6d309852e99a328b4acb18e16dd7a8efe96e58f0496e697131ec6f371b2b6c6dfad1ff3dfce67ffe495c43a59043b508d3b467127001a35ad1d6be95c9e4ffc232ef58f707d84dbbab21824d779e4c057f6eb951da94493ac2739871fb199dcfa0faee577ce47f2599a07d9621bdb9a2c8bc013f9e978bbfe08f84666238bf80d02a2d9037625d69b4067da91fc4cc0ed6d5826c3b4029c196e931b8af18facfb23fc0246af49866e84fb89e7d63d0b3ae073d1fc4cdb8d46bd796bdbd48eae655d2a5e4330302fc1bc43970575260b9be920339fbfc245f8983ef55fce67ff5c5b313a0039eed1453bee512392c1777e963df7da0fc21084d0d9e4b569b9ad886bedfcf73c7711decfb4e0d0c909aa7bbc19cb676af565f3a7398de57e17bc0314c3519c21ca41f4e23b188dbe13d8862559b9d52be82fe869bb1f3a80cf42fc2d50af762068f3a5950f4a09b6628a67f2185febe71ac92135cef8443401331eb09a859ed09f07417555d83e59b2eb4fcfae5f9d5b05821119631dc48a07d653b5bfd389df3e13b777358f7fbe1ef77ce4277848f6acbe455bfff46a729f2c96e377eec17ad6dafe12d0a7a18ef8797b25cfdff2912863d3cad641cfd06a246d0fd64bdfa810bb4926b77efc41cc8e473c33ab8f0c33bc84dc4f8822fd3c9b8d1c15f20adfc3468138e09358db2d5b4e073ca0e80519914e6ad4939868b5ea0fce5dab3808062b82a32f676c3fc32ff48f7c74fcd77a1a9dcf1ea93523063d41b55efbd2b822895b4d1262c5f14f1ddc909deb9eec80c45e032efd042dd78df55379c378626a4bbbe655bf2be3fcbd7cf6efd547b85d85e03b2df7a5bd64bbbebf74dc704773f26ef511c8678728797e2238cf48af19dde4c55177f9b5ae53aca74b6227bacde3fedd26dfc46b65e387adea69bf4639544c6b0afea2f990c74ee2bbe6543f193ecf8e6c3e227518b78dea79284dd1727eb69b22c757e4f8c4efe1fd7ef7be20f6b7491bf303f0afab235b72247c222457f2249fc6660364bde44b584723183263752885da042952341b6c3ce20b7abcd7386ff9bdf578c447fe8feb23a224a67c490efa912acd56f6365a1602b4acb2cacf6fea23a9cdeb210689807f279f2cb503d854d331d8f933fa83f62179f73d7d64423ea7f71c9398d9281051eed421080fefd71f817c7d1fbc9c247f5fddeea5b9f24ceeaf8dfdc9595a48cb6a17e5a49514635abde7797b8c177e3e5eeb77d65fba6fb83f23a28f08426487d23aae3bea4994b04ae67440c74258167005a4acf33d57daf6c5e6f362796a383ed21c655f5ceb780c79a65b3dd67bfea78f646806abd1de17464155bd48bb46db691d8377f4113809d36c5cd7adbc8f8ce5299a417d26c8c7e098b5098dfaf318602effa67c84f126df1ef4a5bde75e45c4ff025f0b501f76c5dd4b6ce39dd453dc296025822f429ed5a4035a969691bc47ed8a5d1574e1487c3bbcffc18fe8236f6170d236c712e019e2b87a6de9b8de1dc353c7b5a1162fd6afd4c0078bb667873bdb388ce68d755b3af56ab108b1ce8bf25ab59e052d890f33eff4bbdff18ffccbfa488ee4f0d17c085a43ef35c0dafb6a229dbb2be62f79531f6131b5496c2d8bfd4deaa3a3fab6b3b200b716e47862cf4feb61a57ac457e92384f609d17ce7fa9ed76e5ec56b3dbc927111346d4c6b8d8b215da412c4024cc7f89444adaa6d386091f091b218082ae683fb4407a0cfbbfcd0badff3113ede22d68f6c3b90ca52656220856023cf582d9680c900533f829ac1d3b3a3686ba90a9e6288c6d99fa5da2a60354d681e89763f9f1fe8e7bfaf8fd096f57b838f415387cd50aa435ec5aff591c4f6c5a20601eb1050500173049968696f85b158049f2ecbe3cbda4e3eaf8f5cfb0e08f661d331f1eed87d04ef97e083396e8c1ca5931f5abd813fc03c0fea15ae7c7b798e1145739d56a406c1223eb1dc498b3d6bfb037ce47a2facd8fa04b42619e42d4aca3177d687cf8eea7904cb86d4f9a231d840ad880586d8f0f0096aeda734fb6c6f6369ec3298cfba4195d63161fb80e36ff1b8e7df5d8f7b3ef27f5d1fc9d0271243c5f80944c02d05a90979eb6feb23895d2bad2515062160bb1f4be4b356b3bf6a506c741697ca69e3ad2ef4a7fac82dcd1bdb6edc915a330d7ceaefe1fd128c46c0d66acd0fbbb2d40eea98875eb044b5174df7b02715b0b19e124d5fa225d4b067f585599f084ee377eb2337fe1091d45e2798bfc162238cb70d7f30aaad6ca983f59002f5479df38b0a3e251027e79078b9a42631f00f56398244764add5eadbf8923f740aac61593980e6e7fd4aed6eaff677dc413b33535787d5bac97ec8b505ffc57fe9124e6374ce2a1a00e14727cc07fb2cded64e9b0fa4bbc96ac250449fbf3fe5efb474c21e14d04fff77058393dca237ec94798f5fad851ed38020c76829bdbc17d0d8eb975b9b1869d64eb2b1b7f5724f14efe8feb2357e306ffc654f5edf8101fa55e6f3128ccc7e64ac2a71cc92e9e77c80975181e3e791df29a2a14678ca079708ae6cfa7c818d5e7557528682810a89d2cab8f7c948ffcdbfa08af4b42eab0cf9f12da8ce5fa7aced96d4feff84742763a927828826fe52f5d548fd1e8280d8093d37b529fbec87180b53b5bca9fe823d2cdef8a24876fdceb2163e9beeb1f81fc1675bf39b9dd1389ea83d8d7fda02eece7f5c9795f02440ba75529f437f356c6bfc3e5eef10fea237c9c58ff68484a5552a5617537ba0c14db00f177ed80c714a2fc594e285e1bfcda3e983cb7876211a46b466483572c9de5ba457d3cf4814f666aabc8193ef23f7d44caf0111e0344e4fa6d73d446c67bfa489233c2eba35b8e8ad5015f1a1db6ed36c144817bae8412c3a8e7314f9fe9f3adfc9bea3710b3142887f3f818711ef82b3e12207feeb907691f90ba90b41e23cc45d4306c1d34db96238d01db85e46a5cf3ac9ff58f907502dfb87b50b7dbc9a8eb885009c37526cf9b95e303c6318d32e5fc9de82190496d53fce64c2c047b0f36af7664e72647499b0724ded94b629e7f878ffcdbfa482a4f67f32200cf7c3c0d241d2abffd3a5e8bd9b4d8097102a7e5349cd3caee4e572bf740f13c80465d76c23123e78e699d910f8dfb3df9f73ac60878e078613735ca037f19af45682c3ef1cab1067c848c9dc4d36eed66d511301fd1ecdcfa15ac0e84cea6cfcbf2f5ef5e773e2ef22c61234d7ab2bab7f56595a057b89b051d872b04335ea188561b5a237a4a2e7352b53ba10ef03b86b1f9825e912c193b6fe697dd4c7d95df89abfbf7f5919456a4762d598884d1d091cc77f491eb18da0e9a38ca76307b3ece84b16f0bd99a883ee623d45e92faa93f8e5f7e3f2759ff48d6be35277913bb993f9d23e37d7d04f8a26b5bf23e2076aba3b014e2738cefa1b63a688979a25ff29498c6c512db5c363636f8b27cf677f9077f0ee0fbfb83c6ab232eabbb97cbdc83f04b6b6fc37a78f6aac56a036770c4a8851e9f9029d81aa99dee2c43f50cc6537cfcdbbc535b99a53dc3adf1afc6f97bebf1888ffc5fd747b2f9002c8f0cef14c85118db7dbc4b24466f33fa48821b9f8df18dc02b15c6aaa088d2845440aee39d7680fc7282b94e6bc3d3ba7ff0ec31f1117fde3fc2e38de4840f022616d61f26e7e919d0906e6391794be2b53a9dfa60b3ca51bb15d6d6f7b302eee7585f0cb761bcdf853ad4a467f5d4d3da9372663d7e62fd135b93ed369ffbeaba8fea47fdec42cd94da0c34f1433745dfa063245868799a3d06bc9ebe67bf1320c68054f2f3e13f585e50164dcc4b9dccbcff8eaffddfd647b2bc04e8704920b96bf360ba3a6c889d3d93ab0ed88dd50e41302d82bc4b6befc28a1c0347b93ccf7ca801fb90fe3ca2b75fe11fa1f749ed72f01efc3b3e5aba53a89f48ebad03af031c2d6f4671c4f07b1fa24f2469d1df2aa4d621e16d0ce7de17764d3d684a398811c8c41467fbf135f9ec1fdf07445fc4fadd585adb06c49781d67dbcdcc6cfa5793c473df511119c7f6a874cb16cf0ffe1a48045b8373ccfd635c0f14a7c241fb53d92ba637778674466f827f4916bf93ac1801576b65bb9d806e47d53bb08a33d60632708a60e44a1385e24e56105d6259473ce8b81ed339a9ecd55fb6cffde937f25669383ef207e0bea6e8c56f261c970b6a6a9be742cb9583af14490c32f12e687da60b339637d0374241dff7708bc643a26363893e681b33e68896ec0fbf515f85aef5d535ace6c6a8218a9a3dac2253cc0cde20ba419650c9b46e0717414ab99e5f7739920cdfb213ea245657b6eb7ed2a7d168903b3584de6b7628fd31ccd1417e5c656f98fe823d7bcc4e7f2e86a22c93191b452dc131adb7b3659fd114c8f1795cac1732ff3b9b3d1d0725d4c68ee77cf49aa8f58577c847c8fa52675e92ca556e4a84027d3bc165acb0ade877bc73f06b63edf9178325a4f90d7e538115e7461b55252fc965b5c949fd047521e4fe9b52ca851d47b2e2d19be00d30f337c82e81d503d228b029ed82033ba18f70fe1efd5a56be7b692a0c2f8af6c5beff310daafd91d3e41f08fe823fcde59b997c8dd52415980c60ebe683adb1c9b11701a39dd6a87581a134aabf616e5a42745c5b2fb7dbefd67c7fd2b7d244bcb24126ff644ec6796303ece94093269056db21ba8871378c8133e21aad2468af41c6f2295e48b3c91d83589e94d58a7811a2322c7f84d62a31facc777af3b7d2ef35d0817c189c315ded1047311af0dd8193d86f742eaa73074a48a7485ea94da20134bbee3b2982ea2c13b6de925027b16f0e4ac5deb57bc5d62fde27867d97e8f45ed1fd447b86d4b16a278eb28c76ed6dece69d151a379ed64963bfe1ceaa63b7e5c1f6f96ce959de9cfed56efb56cfe489a8bc2fd3b24c70350d7e6bb4e03e5c9ee493c693086c0777cdc7f75244d2abeedae5040fe43f1f979bf69ed453affc544cff97a7cad8fee013abe9510db4d6138f22488812015228ecfa9be48f52ee01b903792d4850c533e42f495691677003c8f1477c0f7aef8c8efe26b65f92c5d9be23fa58fc8895d9cd885963be975596031bddcdece6c41a701ab26fa9260cbabbb53e5d5ae66f2daa41b9fed77e923a92f387d1ec57ad934a43e660d4e6bf54a24ab6c5c1944f775a6e7bdb7b0833ecd6581382d7a1f62c3a27573b544e7a14dfb717de49ae7335e29a8d2c06c201330fe034470334946db1a793ec98c83fa309ded096ac32478676e6aadcfc66a9fb7e04781caa94a636b462ab337666d85b77ac86dbfaee31e12be0b717aff8c3e729b13087ef6f14075fde3255be79c790941fec5f22e541c5ba3b3dbde3a6a4ec8d9b9a9d0e7755cafe27ebe674eb2fa48d63f42ea30127c10cb6e2a879c93438e82f5279e93081ec357f4ec843977ad747242d49c137cc290611aae12599cf2ab740db2afb3ebf153fe91745e0361073e128881809d4ff197d725c21b7d778a29165ebba8ea28b649ac2b2ac14913a9fec2e2b692f53c98e809780a928785d241c8621c7f540ee03999b7f2c3bfa28fa4be544a33a85d285aac73deb6933921bc462dc38d27b510318dcaf9919c0b769dde19eab7b25cef2c4dff2ccffb883e92ea53795e5b96bcc7fd693e97eb4e036aa4e0fee3b140e51e67e0a887cd7cd2038baf4578ce85f8d02516f3cc7410c045c93c4f13b3f5477e4a1f91c4ab7960f6b6cd2ad8ea9b06a9e80afe11c21791868cdd732e3ca897d3c93b1f5adb5cd4583a95dccc36402f838c64f091c01c2451a860c900ebaf671b4397d8f7ee7dfb591ef2d67ae8a290600d6778c93fa38f6469c78cd455b782ea746e1b409b127b3a956bfd53612f202908d133601c2a7abb949bef269887c889ffe07b7908a5ef541fb9c583bac3a10aaa81880ca73777b0bc1d9aaf4ecbced9fa69b43cce03a12fdcc6eddedaad7eede7f949ff48c29f09eed7408876b930f697c013730ba4b9bed4474bed3ca9eca4a04a72d707244a73dc1b542fb9a5ebeff10102ea009589180e338f9df0372bd76f1fada1727818bb70dd176ae7e37863f03a809a59558bd43fb9890bf8a7f4112eeb921c12afd7772bb1d3a6742acd5727396efed940f5dc0ad50307d363e95ccdc55e0f0580e974937ff0207ee71bf4917b9a9be6278ee24e67d328b9fea6d141b9f5f445933571e735ebb90d44f04dc734de39fd7df29cdb79bea5a13fa58ff0f173fcb09860116f82de617e2a21a55fb48df373242d8ddc363ef9836829447e8763358ac4c7b110ac5d0be576b93de137aa1380ef9d56ca20b99a3e324ea361a82a342791e4fb643117b3e3a7f8c13afe4c0bcac05b853aa9bb05f52907f75837ff9c3e02f60cc0ffc5f26eee903b625a738f9785b975eed43ee7ceb9cb78e47bd5f305f9d32436eb2ddaf3f573721d1f748fed91e0d36f54370e0ab37c2e8e437538f3d5218925037ff28a8d393b07bfbf1e3fc547b8ff8ab6fed699d55696fe126f4a918e84b13022bea928ebe722317298b66baf3363333a147225c04af16cac7f402cb04d7df1b972fb3cc4648fe993d49ef7e67c0026817014bc5c85d52b29da0a60d8072ac1f7baf1a7fc63fa08a7ff80dba8da5b4774ba1c7b916abb6077df8061be0ae8fcb9da255e74b74a50f56d51c3b323d2e8f16f18f77bfa48f673fe7cce174ca077c2c64650a71cefa031ee27d8de8ac24194585ee130f3fbb778f4ad4de76fe823f0fc1c5d23c0c9aae766fe6a12548d9ced063dcc1701635e26747e2f925acc80cb88e97c4ed4fc5e14aea4c1663b878c5e88705c2344ea5842fd32476db7832a99179edb93f5ed5f8d1fe2f0c4d154130d6301b5e50591d48eb4267541102e57f514ff257d24eb632739e74b6777e80d1d35883218f0e01391b0c0e2e4ea585b5ce61aa131070c912e96ebbba4a6eb6d3cd39f61fe7da43dce677f84ff4b6b39d1fabb7dc8e1034469868beb135cf5eb9a8a6fcbe16fadc7f7f291ebbc47163f0d3638884983532f0c720aa3ffab441f4c7542900ba02689e7db4155192ecd5cd3f12fc5b9437cf381a3ee1d641c874b9b6153666317565763a557c8640e21067a3a40d3a8eb5794833fc57a4f84cf488a3b96fcfe9fd047f8fdb86d1bd31f1bf5835c0bd0d9180f11a87d1d7cb7b3113296657c42dad16c1212f9136b87c4bf9de735fa92fb7ea53cfe963e2265e8dd98bd4ee76b94e4d6913a1e50731db00a99ffbcc8f0e1adccff86495c564a43ffa63e92ed03e80a47c6eb8b986f00bd2f0a62ae436c8a75d6ef27c24358aecb4aa5f54be07dd00baaad4aaebb5f23e3b02638296245dff6b603d75ce648ee089b0fc0b1c9cc41c6a6e51ec9bd087ebddf8fdc5c2fd70f0ab901d661c2ab3a586cddfe117d84c7b4723e620ad1aa60e7d6253fa2f6776ad382ca03a79a6dacfb3bbfa535fca14c6bee8912c3e93059bd8bdfc5f8fbb339e1fa88ff40a7b8a57f21f17ba4d8ef3ef3a97b045f3dbd278d75a5afafe2bf7eb91edfc947a42b3ec27904d11bc97864e2db294fb56088f9058d2d83df66ec4e09963cc4a3c9f1a151885f14032d5127a7c6addc30378adb245e2d169603ce0beed72e995b52b784c6b2f59d67b4aca27351c8635d644bf26b6e6c8cff843ec2f908a7c1f833dbcf8d1d83d8b26c6affa048029b783d3dcd5167331aabed31a991fe94c439c98c0e65f59b8fe4b07d561fc9f29107f679f2ff1ca931cb7f47fde8f7bc8ef3a27b3ef277f5916c7ef988f61feb199467138c809c26529c2da8035ce4b8f1ec3ffc2a133e0316e14dd00daabb56346b4ba5d2c226f98751326f746c5a369fe86e1d0097c511b59c9e9b9cd63923388c9fb7b6f694c9abe1fdcfff33fa48d63e84e9d46eb1d49102158a0f26e47b830fd7b59b1196b0cc455718e62c8237fe995aeb9f6df7f547de9ab38f7dfee8bbff863ef2b85fd79f953f7c2fa0f14477710f801f130d499dde88c90109de4046af58311e7c112566c7c2ba085eff3ed489f7cefd23d4fb0d4af81e9704a32bd3ef7f421fb9a19d801faf09cea13370310f3974793c694edaef4fe3792f5245adcaf3f1a42feec79fe8235fcd537fd58fbfa58ffcea8a1bf2993fe42d1e9ce181787d0fe4eacc9c9191cbd98b5c1e6abf8bb929d7ddae7f0fb9a4c43626e8605926759891d75bcfe7664eee15375bafed37858d3025eb71175bf1cfe823595bce4c9487935ca16cd30a37145b03e5734fd35dfcc264d57222f7fe2d3ef266fef45f588fbf350769fb081fe173457414b04186a15f9b95436199db9549fd9205a9307a3d4e562f136c8350af17b708eb2ee3a6140ab9e7fe93ddcabd10dd04f399404de622b32eff843e721daf9587d8d7a9bed9b93dd7869ab3b40e0952ec7caeb86b092afc36f79af871dfcf47ff8afebdc553df8a1ffabef97fbc1e7f8b87b06bc247dee2c1999c50ae8b093551eb54ce9dc5292ffaada99ae872e9ff595e08bc9f8ef16bb0a15d367650ddaff242def68c0dd6491667f195f8db8be296e87cf0ff61fadc7f421f49719424e69b8d8793580d84fc94d51f111d3576367ed90b3bcc0e547ed0b79f6d6fe239fd85f5f8eb7c446cffc6ef434ef761cd67fb7117744b5a6397fae46fc64ae2a8217f0605e517df6e17e68363b5b4c83bad50180b3bf195e0c5e0ff0995441fb9e5233f4533be4b1fb9c150124ee293dfcca361df518f5df40ab821c3853d8e2eb64bec1f580f017d84d460fd8afc908f8cfb2d9efa3f7de49a8ffc8a075fc75bd589afa587db147800c43e63f96140af573c135fdd13f58b6ce4bc9bf7ec5cde77957c20a8a41e4091f89a004b672dca577e2a729f7f461fc9bef751900f072ff9c8e94532444d0f17f9596916cd76136ed710a7ffd34732ebf1d7f9c83bfac875ff68ae25593fc39e02866691f9528aee9eadeb35be097c2f432c567eae079528efa32596ba35d1f2a19af88ac566acec86f0afea23927825af8a6301e517f96554a0b59db0b4d552c5ed589a78bde980c9ab75a8bf27523ef213e37e8ba7fe4f1fb9e623bfe2c169fff32cc640c327a49efe9ec661257e113eafa486b070c152b61a96f32bc53feca7e614eabb6f885f5d26be27b85fca5387e973ff017d24f5e326713a8d553e6e1f517d07b1a1a1e3c792539beff2ebb4ee14967fff361ff99f3e9269bfa58ffcde38a534d71362b2c02702f1c5a46e7d366f472635869358eb749efe097d449a3f919c9121f7cf06d563538b91444e887b2a389dea6287661ea317f83f552343b77e62dc6ff1d4ffe923d77ce4573cf82dbcb3ece7d7df5fc72a108c66db05ccca1bac4a7ae57988d97c24f99fd047a41b2c254bd066ddfc46f708ce2fd4a3ca0d9f979a7298aa24d694fc4fdd313ee2ff4f1f11fe037ce437fcecbf3bceab9c4e21ad1d63de7c270991886ed623e5233f4533be491f813c3cc24758ce403008aafb97fc561b3bbe13389d4a65631d7319cc5ef85f9ddab7123ef2dde37e8ba7fe4f1fb9e6231fe5c11f1de735364a5a0fd9baffbd30657cc4bafedf3fa18f2c6ff4918b3070e3dddea9ed44a7634f7687fc2ea862f97325c42e64ec04583bf3ff3a1ff99f3e92699fd047ae72cfafda639cb43446fcfa7fb01ec29b7ce4a768c677c66b59694381989fd7abfbfcdef595c63cd7dafa832d44bd4990b727026e8a26d613ffc8cf8cfb2d9efa3f7de49a8fbcc5136ef7cb23bde3d178d358f0340e8b3f67987c47df833e62de3fe71fd04752da90e2a21c85d030f287c5387f5cbee44fb10af97b4286e730bb96f43f7de4ff943ef2d17e3e8e7f4ee280d97b9a8793e27e65f1b532fffb17f491842f319a02f537f05513f2f973fed218e74bfeeb5026d8b79737ed5a3f4d3b7f5a1f798b160f7f431f796b9e1edb941ef2f8876d9c598f4736aa8fdab2defa1de70d3c363cc5f3cc8e2bc58dbff9ff8ff0117e5e299651561ff96afc117abf25a93f82f9c458ca97f3957cb551093bba9caf2df75395d8346475472a15737ca59fa0dbb77233f0b1efc4d07fbb1f743d4c9623ff317dc4cfb45fe9008f5bb60e318fadbbb231e1f5e0fef3b7f48acfd4307e340fb7afb3ebf1f3f85ad49ec0f157c32b9af45534fce65eee49cc4f07e29350135f3b55af7d32267e589faa0dc9eb410e5ad52438ebd7f2e8775e6fc74a5b98e8443fc543a49bf518b3f5784ffeff55b3def99f2cbec747f281caeb846570cd6eefffe8391f6dbfde9ff7eb91693fa48fa47c24142f0fe8eb17d36a2126f9de34275a225827940ec904fbc4237c84d22c9fd4e9f8391a7e3ddeefc288b9a7e38f6833c43c0576fd837dffc8fd6faf1f6bb82fe292c54c3de2236fdfff16dbf2adf6d1becc1edc2fd547beb371ba4069c325433bd3bcedaf7806cf1fa1781a9a38142e538de06f50fb46917c4e9f6933ecdbaf7afec7fac7691360b7431efd85f4f3279e9f6d2693cb095db6eb1ff84f5e949379cadfbc7fffbf3c07bf4a303493f7599e6137d8da980f9ff5b167bc7d7d7f6d603d86783d86f779453fc6472806229ccbe8863e7d3d1fe1b488f31022f7428d756141f29d57c289f011f21dc341f9de764fd7a8bfffa7f491ec3ca7f149b43dd20f6f9b7cd756cce7b07a976e4ba4a6d692d91497fc7de633a85db948d6427ea71fd683f6b8ef69ffde9f23ba1e9707f7a27ce4573682afb8ca62ca4786552bc114e432e7573c272bbf9a097ed3138b0386185f8d60f031fa553e913ee493ff7ee7f8effba7114c90a131bd8a0ffacc75fccef7e93c6b09861869f9fadd7adcb634dee96d1b5cf6b7fcf743f1de3f71cb43987d89ac87f98bf578b44fb8bfdc14efe7f851ffdfba4a045b8daf8776751f6ed72a635a52c634eddbae98932eb16e1888911818174cc323dc42b1fd35f787fbe0c6de0b157169378472be413e5f62fe5912eb6239af8841adde08f019c5fdc837f1ff9658530c4401f7e59bc79fed1f3c17ef8836ee179e0bfcfccb679f0fff87f97ceb3ef85991b8166336efb1d8c6cf0ff095ac87a8885311b146be4f7e37157ba4f9f83b3ff90d629fc3f7118c0b7e0ff7c72dfb9c645dc4a9b085f742b9afd1fe0a5b7a9faa49fa875fe75bf8bd8bd7c91185db7e90fb07f479ac5f117d3eb9cff5efda99e7b6afe7fdcdfd73b31ed97d09ff4ff8c8773656cf95e82143c126677528ded657fad3767f9f5cf219add9a493384fa0514fe2045fa13ec933c593bda2a13fd828dd223cf52be6417b380fbc9131e2f1f271f2f520b1d24a89c41d4cd89a641bfb1cf2fc48aedfa3f7e9ef9f32cfc9f64583385b524f8bd17e786d7b42c43ea3ff7f26f7a3b5638677f7cd5e7fddccbbffbf3fbfd2cd7adcec871fd447680b983ef2b3fe658ac9047635c065c42ddf66b96b7fc7cf4d1bcf57f8ea3ed07a88728a2322c4a4663dad590eef8fd44782758259adfac0e771af5370fc5d22e333fc615e7791e2f79e389600f9ed8ad445e1723eadf7118a69be798aed2ec3ef31bfa7be970bc164a4cfa37da6f79ab3c6c7e067740dfe0c6a174bf19a3976fc47e7379b3f92693fa28f709990d2ecf8dbf4117ebf3bdb382060028e2bc95bd626ae1005a6b099d721db9f61ccfe843e724fdfc32fd347b27a42f619f8fd322fecc312cbf7067c749320e81cf00e9c89b978f760ceb84d88df270f35ef670512bff0c4e82ee5cb45c8c9110ee435a9e58b9f738b332933db626a83c2cf104412f340d64c3860699cd8b4481e21d45439e2d725725fa8c37b209fc5640cfcfffbc45e16f35ac2cc2e96ceaff6a1f94df7677ca797fd1c1f91aeceea4fd36ba85bbe82bc6704759f76826a5735f3b2c977f25da57a87a3f1530d685ef42d7efe55621b92d99c639a0c7e21c05e67b6218831003b928fe5eeebdf4b499f78ecd22c638f9ab3df917c72527f71c19e49ff47b1f72d429522e69722cf6158f184cf08c7734c4e288d89c03c41047ba39fc18ca73c875d134c4d93f08915b3abf98cdfc0fb99282518fa9cef7dd17a103ef2dd34f4dae6417d99d9cfbfeafe6f359afb3c52abd1cc5cf883d5601c6bea2a1ee255ccf732f4f2bbc77f6fff09bfec39591b93997cae11ec5cd353817f046577253898427860e773576201f351a09d6ff139763f12ff6602dd263adc13e0ed923a5163767f9954d5d9807e11f46c77de12c6912a8c176b8243b3d17d71e46d883ef1446a585589df2a8fe79ed81601b3a4f60235dba15f049514783be0e36be535d65b3cdbc59f6ffc8ed72375a68a3cff03f051c01f063c86d46261ef3336b38faecf2d5fff793ffb5bf9235f1daff5b8d17ab383a05a9ae6fb8781ebdbf238dc3814d552f879be96d2adefcc1f019a5c64fe21a0f93d4183da82c2d01f28077fa03d939ddd2f439cc1bdcf81c65451ba4ee47f42a38b04a7be2f8c822adc03ea69cdba04f710f2c4b5dd24a8c6dba3d219ce4ee3c3a23f9f98fe7c725c4e1cfcec1ea9f3e291da2923419dd7481d15a233f8767e405046699e79405eefc457f8ddac8bfb7a094b8dd16e01fdc7cfd2d86fe87e2a126cc680e8313cde2bf58f7c7c7fdeae47f2df1fca1fc99eebef8fd7baa7d99a80f784bd8d2a950aca39bdbc9ac73b05d3bd5122df7eeff81fb534ced4fce4fd6ffe9fc419e858e2d181b60b634ccfc7929a1f356bf9f1d03d343ac361c57ab55dbf37ae82dd0930907913a6f8f4e8995c3d9361eae39dbbb1cda3d71945b6badb6ff543e3ac4dce7b6d30ef29bab41ae4b555751f579a613c50f2faf4d45f9dfb4eebb019945a1ae6de95b8bd9ef4dcd2586d35472b2b3ae527ea36a8af2641bd75995ba5a95ae89e26e75c3cdb1ecff8b35dde681879d37a3e3470bfadbce48f7a9e35693ecffc4643186f1b82ba36bddeccc37d2c10dd83e92384df5defbbf7d7275d8f9bb5fa413e42cfa57f95aff0557ce43d9b8c9ccfada47c14db9e7b7e723adb95dec1f4b481bfa731c23f35feeb16629efa1dfa08e8041752d703eac5ee4afb5561bc6977cfea76e574fcc051679a6dd85a3e7f3ecc06a367d0cf0856885acf2598211ac311497ddb94fe8f877e6e9e97d1325fb00dd4705aeb81b6e82aebcbfae828b6e5fa3b11e5b627545f56a0b2a7d34179473d89c8e80df34fdd7369624b8e32f15c5f2d3b8a53cf3fef7aa6b82fe65fa6b57c942f22e358b6f595b88d96bdfcab23b97eae19a0c0418a3646caf4ec280db1f47cb196e77543162b17c9392f64613ab09bc0a7887526d58d3ebebf6ed7e36a9d3e943fc2fdab5f41534da1f288f67d01cfb88e191d52bb3ca18b58063faefaaf4e6f8d169ee322bc4ab22d061b526f84e526de8e97cbabd9f6153c8ddf1fe45e8ac3a1fd525ee6beea6c9e351fe398daffb17e01f27f046325be08ac6f44c24aeeb5b74250a8acab3b7bec5c8607bca37d5a47d0733ccff16dcb51764779da1ced3535b8949a23e7d01c5d4aabe7dcb45591660b3ba86e0a54af001d23345579e7c9ceb18514a787958417f4eaf9e815aa4103fa387a71fcfd86d44a7f452fe809ea17e3cf425a3f9da2ca220bd5a12625d457a7cde99c6ac89091e31fbb91dc8e1c1f2b1fae3b75fc5307bdee378abef0d6c8f3e700dd5cc4cff1f1772ad21c75db414a472b3daf2cd96d0ad124de1c9cf2aa7c943d6103f341f598a42ee23defbd97376eebc164f3d96f65d16c5defac7c9a7e9fc6ee5899989d22b36d739ec1e85aa6ae50d0d792fb5ee713143334959f7d7a7f6287279826f4391db8129b8c943c6f85f901b7ab139ab755647fb79b3d47e6317f29efcb9806f91e02543ac76d394b4d0ec45762e7b9cf470c327dbeee239f0f29f98fcfed3cd01f4cbf13db3df80b660556af89de9b60ce82c4e2db7633b4e4b01e4e816e5fd873c3cc98a15f17a8614e6573ac0300ad8c092e2df1f3802e013a861c4d8abbc232528ca3b393b6cdad1287ebdaba2ecfec1ca6d9e2ba6febfb29a6e712aaf31ac3d0f02eaeefa7c8d837918126b899f835fe1de60198e6db7abfdd189ebcf9bebadbc9f25c5e4cb6d54d13df7313c37d3c179f3417ef5d17e613ee8bd895d52ebeba666a1a939a94b7d7f9f46cc209f317747db2f783f750cf32fd1cfe87ea709d4f497d4b63273aad4bde36d683308e9e9cd3ca9d9d6cb51f970ef25218e2b54b6a66b1bab932f511111bdb2259d7d43ff2988fc809bdd4ee68e71d3d25d876cc66228ed8556376067206792d3b567b28fd2fe52379c0c84b1a7926b197a7e71b9e4b7609d49510a97ccdeae57903669b9778fd55627339800d1f9e3d71e515eae54d390ee3852baf97036d305c38eab104330d18f2fdd56e1fd4831ed61ad39c85bbba796fb66b1a948e5522f55fb98ec36cf6b88f03db0d62a0f3761077826abbe30f1ab2bc91b7f26eab3a85e3210a5be5381cd98ada6bcbfb5debe0ac5f574f4ab4158fb5bcb9685ed6fbf9a23b35a2705ec374fde45554dfdac9db716165a1a57c6878f2d1360e9bd171ddec9686bbdef3f48cea40c79d3ed0f16c6d61a80b09ef1d17e839924e5d07d1faf59e803f17e077f0b9d372045b6f885d657f6a94e4d3a2525a627e417eebd1fa9282e7a6f7fdd32b9c12273c0dc83539c1bf7b1fcca74438654e1fd5b727a7654fd072ee8d66f259be2c26b60bba4b80e76e6d825d0f743588e583daf6ac2e31e5d961929b9862a9a47ce43ed7eb6ddb00b55d333b35b78fc395c8c1ac0eaab06035e7ae65705fdc5ee5b4515c2c6ec7a7d70bc3c1ea131bc600eaae0696d0c3f235d4952d62da3b20f436e03589927e503cf1fef124975a553bb7779d4eb7ebb466235477455239d4de619a746af4633306ba2cccb97ff8a1eccafd06d6ddf8c34cff891f9bf59bfb81e13fd1726f377713d4558c756b3b5b2b95cbd23c8cf7e548420b90df4f2b3b87e5efdca621976b2db7e134ec5c577594a86a1b3b1529589ac03412193196fbe58aa31c36276b591c3cef4f8ee2faa4fa696e8d65f593e8dae7279473dab651c67a02de25be5ba47557f889b86d40db6157d566f834456ce7b3069f631a6d2ccab621576c6336723aae434f08e121c9eee6fffd448b40fa3a6ac01be05e595ef7d1fff33e80f4e716d1ebba84a5bc3c9e8f2ed6bb4c8495ff69f5b4cabf46d2eeb044520ff3ee3ee5c7ac5e09958982aa2164eb60b25800c2476e6396eee5fc5bb92dfddc24d887cc4eceef417802a9972a74494c148bb711f64249ae667308001b8bd5404debd9be08d1465e6ce55a77b92efaa3d9935cdf3841bdd108aa935050a3a53fd814ecc0efd96e43c2322720540e40ef00f9d37617f6b078aaca8d4dc3e9c49856e20f552c23e39de2398147b8b6222bc20678d0a07eb9f533f3bc81fbf8d4ebf1b3d7980ee5f0b8489e3cd4f303dc2edb55157fb0b0d7fa20aabccacd4525aabafe768f0c38ad5883ad2319cbd4b2dc22fd1389dceecec6a4de16ad058c8056af11dbe5aff01b0705c8899c0e6e21dead2a8c07d3fed76309768767b7b7f87702192f9684e084042ea5f5b4a6306d641e444a7b815fd416f85e61c263e0f7c813e13ba8418c4f5b07fa4aeee993e770da1dc2ee3ce7f10efd2c2fc1e3b9bc523e02f3403fff0d1e05f52e23ce0be9bc8124e84df17b1ff426b788f98ced78280715c7e5b6dc91bb728fca434426e232c2e54a5e6075de091fb9a5ebf74dba8aff9f5fc5efc8ccf7594ce46a8fc8d16057b1589dba22b9d2f3da6379d437d8de98ef34e9d9750f72ff7894b7fda33cb08d460e8f4a8d9f26c38e793ee4e63b6fdd528cd9f37479cc6f476b7dabc5ed714f1e0ea2997f9c355fec55bbe26aeaa9abc8234c8b7378669e306dc1b486ec0e1774927e551e035e38f0102c97fae2bdcd29d537aee7e191fd8cd77e0d7c5be8cf03596b75965aaf379a48fea61c384ec79fa3fad2c527a048a41fa071f563c9b5370bbaba0733080f265ded2062d291c0e83ade9db21e844e3f16f18e342e81d369ac515d9e805c7ede9e65229f3fc1ee3d5e48ed6018ef2b919c42b8774a736f6934f42be5239c97105afc047c17f7d7056d1c346e7a3af895d26f72423ecb4742ca47ae7992f77bf788d8e91758fd642c2b1c75cf5ea3b943aac622a042e8153d3bea668f96f95d1ef4423d8919a33ce351bc5690f847ee73c3241e170aafe74f0fe92acd1183bc0c380122d402025bc2622d8c83ae1d6c0a78b77bf63cd22feb4533323a43d988f4682e9bfe201ad2264d84b1eddb41d915d48d8ce5f62e5822a3d9e6509137d170295b918c34646863644455a7851b9638ec5cb83ab8ce652c4c5fa62fcb812ced7a726e7ff0cc6304dfd9bad290f3e6080bfd2b3c7bde793b9c7be2c1a4bb06d344e570c67d061e5865b6744bbc9643b36dc8e682eb1fa71b3c27fc5fbf236c56137fd0aa18c572278cb1a66c38116896a9fc8f5ea81c7f960f3dd8195e2817405f38cb9486e32b3e31f4f76719de7bf6aa15ccf02e0fa1ae23ee3f3e194ee79c87131520321e52ef113dc14920bb01f409cc2bc33dbe0f3e6da5f547f59144da12fd19d05ece3328f63ea1cd02bb3f97dea2ac0ef137f511ce1be93588d83ad3f9861a664f5083c6b6b0045b959fca65f9797126fab348e49fd47698fad933364ec647a42b5eb1baa193b7f23ab77145c466be035f68531feffc81fce20f94289cb4b6d573abda1b9ffafb72658965428bcac90bd75176f9d2f3b20872b55c742e7271fab2569426d865167d7b355d58cfd3557527bf769583e7741dbfba845542af67079049f1aa16b09422396a9c43468049219a603979009f23033edf3b2887306dc534c327920b60c70b9c2383b5b1a5f6ebb206f5bc135fb4959143b3e37ecc4356496c299d0755186e9b0d63ef1f06d3722cb1d380980d660e2b05348eb5d0f1b9a4521003043b035615687cb8872bd71fb87e809ec0928abff7033cfe70cf258b7487111a0cf70ca1b21d3e815802f3222c9961698956defe953ef290b63fd113017d3f6fc9fc855c12e2349ef195e26fd2fcafd647a80521e527841f018f83b985d7a05fd986e11484825d98123b225ec35941e860396295d1bd7de1fc48a648fcec599b70d64f3014537bd798fb1ca88f539ae88b8d24d7e393bd2a380554704fdef274d8623a6f5cf2207b3baabf045a4a3936ec1864d5167827779099b6b881944b3eff241fc15e1fc6abae53d13705afe0836d06aff634004b23e6982057027dc0eb32c33b0decef1696bfe13dc89ff87bacadb9e43b44a40f87d312b23b4192c1f73cf69cea3a57087a5867688f83baed635e46721c6c379145b3ba47d6d6c6f806e840c033836e50ef0cb7b3c358af290df013cc9d6607e4613f82534276a840b4c9a720a2340f788447d0ba0b7c77c3dc10e9864884a9c421721b12fc1fc6e7711b14a3f9a067c1fd027c7c024c32c8ce06393c24a72fccea1f8ff59166fb863663bec6ee4f6c5789c61fa6f7e1fd02de82c7f957f511bebefc9404084ec7394ff82d3925784fa895e24a3aec0575e2420e11d61f63634de4819467e489cdf5813f8bf091d4f7c16d4cd4260f7e5615da3c1034e5303b0bcff6343e8dbcd6766b15a2b3ba2cdab9fdda366209d3702c11611a0a34de9f4f31cdf7c0decd46cdce37d08acb2b9563a92c4b1bfc9ef10003ecf3a93d9fd1083603dcce9edacbf93d6e6924ff8f77fd5e60d283539a146668316d14e6954b45b45e49ec9146b4ff5dc6276232ff0fcf45a0be67988f31c42b95a6ca7e3b7314e8373eed2ab1d7733f4142d3b23ce1da26741ad0fedfdafdd3eb233f8177e52f603a4bc86926ecda3562cfced2d837f511c7bd93ff93f94ca4aa30194b763c7042844ff2914feb23292fe3fe96ec7df03cf9836a6181a5fa4818909a8921b7c3c2ba92f5a6f1c9ab7c9de8c4a98c40ae704682186cc6b6bbdc91b81ed5ef79bd6dc31fac27274dbd4ccebb5c7fba1aec76dd526159eea0e5be64e76c0b73f2c0b5b194f3ba2ecd9df696d272624378b9a301219f6507952336d361429b984d82cac0995345393ee501090de3b483d39aecbd38ade3cfa77238dc33b111c1ff7cc705cf993b75dc53cdd60bab423c538de274be97c695386cc0d84dd09348bd3c12c31aa9604bf3074b67d1517d7fb444f3c9f2d42b34da2e9cee5412896edad58e6327988d11bd0c57888f37f3ffab6b98d2563eafe915f833b1e5d88c6fb8896d873c1724afcb9ccedfdbfa483a9fce1bf3c95e474963cf81138279c96778087bde67f491ec7c5cfd9ff40f7f2e14d62bb7ef605d773c94abc6bc777050af10f4adc2a6b0ed8bd602ebcf95a0ba38cfdc799dd627e18ddbb566fe6235f367c1cc1ff7c77174a95e1aaf7b7f2b1576b9165a821d7ff78c4f85e9b41665a7b377c01208f23e9c0e7cb48a4e86a6656968b6517a091e1ee0aa284b0313ba91da24ae572a43cbb2f267c227e07bb83fdf25e4b32b5e85180da6fd839d51d8635e05b4db38bbc4429c6b97b096dde8f50b877e6df6b2f797d6f6793e695796fa59dfced6adc9500be7fa71afbc84f14eb08d3dc2bcb217c9e12ecb13d395a6cf83f1705e91f208ca63090df7a9bfe1b63da2a5e91c65bfa3cf813e807491f161cf818f004f794c93aff4912c2fc8f23ffafae9f1e79fe11d99f6497d24bbffb2bc968c9bf054f41423c9d87bbbc3c92bcc0753a4409c59b98096856363beeb1dadf9f8ac7b466336deee83fc6ed12d9c826a7c9cf95b25a80a433823f3c3f2e47bd2cbf4657f1855edf140b17507eb088103367c6a1bc7a7c1653a80ebf9e0d304791faf3f3fbbd7a722bc692ed54960366a67d04dd625a6574cb9fd9ef30cc2bd53da754fc3286d4b7cc2647533df319e1331793c62cff5186d89e84eade393017e8036a6bfe08f589720c6084b7c58dbc72706fc184604deb88e6d542ab6313dbbfef44c74acce097c159ee7b6b76bd4ecec5e52d93f634312186d866bc49e1f71bd8ccf47abc6b460361e2effa7361a4621c25bdb4d665e927141fcd3355582f94de693edaa3bffc8f99af75ead673adfb7b6acabefffb27f84f1e6f4ca780b9f7f3ce73102cb11329cc1dcc9f96b447830023f13f157295863c829a3c2b9302b5cf6457c128a2af2bdf9a139d2443823288769a21a2388d1247edbfaf9c9516763c73d5e1cff58a23617bc93ec700f9e2c2ac782d512ae819fa129199e91364eb3d02bdc07cbe0aff8be99b3ce79c4ad7d22c33b6eeec767e65efee47db9d23f485c4f96d6a3e271eef4a9dc8ee9af4f251af40a14002802f70b9c9f6077bb36c4ae626ad1c17a938ac7adfa736a33e3f145f7b49f3f1f766896e6798cd6319ff02bff7f627bbabe267a40c22733d4827fee513dede13c5ceb0b6feb23cc5a9a95096e758fd0bbf9fe9a6ffe79fbbc7fe4ad383126ab105907bcae78bc4fa97f271df7a9e0a89b18198552806658afde33ee40f563382364957c90dbc0fac8ffc9ede24043ce5b4c2b67f86ef8c4105fb00bf62168a9d5f10d9a9f440950add415cb6dea95ca9cf53b3d223b03597d86495391e3666850fa5ec8d05c6aebb0b99c4d6d1c74e7413fce96e316cabb17f03d107b5078e882cdc87da1fde0fe01b8029520d21af8ea8964e0844083a99d8cdb78eeedf4ac1f191e91d5a3e05aa8b82f092578bb3de2cd6172bdd95137bc48e0fd794b1f69d5525e71adefa4a795ffff46ee4ffbfde73c84dde793f15a0ffa91ee0dba8e6e91fb4df83c0411dd1f845a415c01ea169ceea14bd69ae9d53056382364d7ab0ec227012293b12411109bbde30ee7e959836b10b1781d81d01c9fae42966e5dd39d2bf93aa2bb13ec5a49cc67422baf6942a23fb0d8d2eca949e57c6edbb9b5d3dfea388c96735e454e49613f072984f397446a497c18d9bef9099d7da17390ee5eeaffe0b6a6ab79b896fedcf4cabfe776addbf9bb6f9cf73c1adff5b8bd07bac507fc23199e91b59dddfe3e2befffb62ffcadf6e978adccda3db41f524f00f13be1d758ee09f973980c60fb740e3a856a2c6299e17a9e23382359c906fcb507137cbc984f902809f0e17a22e12f9c265139cf2676feab78a08ccd292b8f73f999ccc6e525195596268659b996fb4853db441a63caaed998d32bda7c2bc7826d07f314ceabd80ec2fa889ad2f05b9a7b6dcbc1f4c649ecf0dc6f70a527dc3ef796d6dfea17d407ee45ccc6776bef7fef9a9ddf69f6fb0ccf0a6f9fcfef9fd54740a26cb6d335b8b9ff039e7e25e727fad307fbfdf0ea7c501f79f3ffd736b82bbd8efe9fca09c9fcd769dc424a7db80c505a17c2d56b90a16c74fe081fc9cc023f7fb7b4ef23ed2d1ec2cf23e51dfde5151db891161edc47f8d3e767696b761cd097d653626df815ef7b6f4cbffcfc767cd7dfc3f3fb724abf7ffdac3f698fd6f5fa7beaafe2fdfcd5383ed2bfb77eff816b04fa4866d7fed17d3fd32f12cb50e727f59ae7133e42ef267edb95f11c90e3035febded3b46f7efed595ee88422dd15b7ef8f974dcc0a35d11eb23e28f8d3b13db4bf535e2d79fb556f77ad4cfcf47a1f6b79ecfe603bcaeb3e10acf4978dd0fb778cb47beb351ab2ba35b7fa12534a30e748bcabde83573727eb4c1f34137fbfdf8a4cf376edbf9bbeb91ee8b743dfedebeb85e0f62b562b63eca47bebd17228b454afc23577e951f9b0df02390678710114efd143f7f4248d439b5f145d46ff303edca4a4b6924899f93883e721f13f0014bc2573562a1794dfd4677fdfe81f9a1b184a72ef363257632c4ec5a8fe284bef29acc84caecf1fef73eefed7ef0f70e3a9b105706f91c7fab1f10730027153c9c3f356efedea5fe1f9fe78ffc9df548afc85276d01fba1e3fbd3fd2f5286dd3f5a0b62ff89ec85a1eb1f9bbdf7545cc370291daa75a7d07be6cf23d6fdffcfcf4ca7d02f83d450ba8a7feff1fbe7ab033ea1bd2971f1a77ba1e6c674a8e7aaa9d7a576bf1d3f3c0d683f0758951b0bfb21e8eef0c0aa40f10af909d0b7246486e1cf88ebfe74a7622c40243d667a73ba0f91fec7bb8aadffbfcd437ce9f872463b3079ff980d2ae1f7c3e9d0f89c43a93b93806df3efeec3c135e4e693641475097adfbf9b9b97efbfc2099ae07b258ccf8c379fbc6fd89d703d6a1d0b85b0f1515e08c9cad56ed6c0d57df75755f5bb5daac5ba8bbb5e5b255506adb53ef6c35dbdffddcdbeb7603d7cab1beaf2d0bcd6e5c7787c7f6cb4ff7039e57df9daddaa2eed60f8546e5f8fdcf3d75cf56b790cec3a95bda36dbb5355d8f9f5e87db2bac47fd4cd703e685f6f7e79e5f9b9dbab5f5ff9b73797208223e5cb361f2cee54ab5d65c009db7fe89</data>
17 </pixmap>
18 <signal>signalTz(const QString &amp;, const QString &amp;)</signal>
19 </customwidget>
20</customwidgets>
21</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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#ifndef ZONEMAP_H
22#define ZONEMAP_H
23
24#include "stylusnormalizer.h"
25
26#include <qlist.h>
27#include <qscrollview.h>
28#include <qstring.h>
29
30extern const int iCITYOFFSET;
31
32class QImage;
33class QComboBox;
34class QLabel;
35class QTimer;
36class QToolButton;
37
38
39
40class ZoneField
41{
42public:
43 ZoneField( const QString & );
44 void showStructure( void ) const;
45 inline int x( void ) const { return _x; };
46 inline int y( void ) const { return _y; };
47
48 inline QString city( void ) const { return strCity; };
49 inline QString country( void ) const { return strCountry; };
50 inline QString code( void ) const { return strCountryCode; };
51private:
52 int _x;
53 int _y;
54 QString strCountryCode;
55 QString strCountry;
56 QString strCity;
57};
58
59class ZoneMap : public QScrollView
60{
61 Q_OBJECT
62public:
63 ZoneMap( QWidget *parent = 0, const char *name = 0 );
64 ~ZoneMap();
65 void showZones( void ) const;
66 // convert between the pixels on the image and the coordinates in the
67 // database
68 inline bool zoneToWin( int zoneX, int zoneY, int &winX, int &winY ) const;
69 inline bool winToZone( int winX, int winY, int &zoneX, int &zoneY ) const;
70
71public slots:
72 void slotZoom( bool setZoom );
73 void slotIllum( bool setIllum );
74 void slotUpdate( void );
75 void slotRedraw( void );
76 void slotFindCity( const QPoint &pos ); // Find the closest city
77 void changeClock( bool );
78
79signals:
80 void signalTz( const QString &newCountry, const QString &newCity );
81
82protected:
83 virtual void viewportMouseMoveEvent( QMouseEvent *event );
84 virtual void viewportMousePressEvent( QMouseEvent *event );
85 virtual void viewportMouseReleaseEvent( QMouseEvent *event );
86 virtual void keyPressEvent( QKeyEvent * );
87 virtual void resizeEvent( QResizeEvent *);
88 virtual void drawContents( QPainter *p, int cx, int cy, int cw, int ch );
89
90private:
91 ZoneField *findCityNear( ZoneField *city, int key );
92 void showCity( ZoneField *city );
93 void drawCities( QPainter *p );// put all the cities on the map (ugly)
94 void drawCity( QPainter *p, const ZoneField *pCity ); // draw the given city on the map
95 void readZones( void ); // Read in the zone information from the file
96 void zoom( void ); // Zoom the map...
97 void makeMap( int width, int height );
98 QPixmap* pixCurr; // image to be drawn on the screen
99 QLabel* lblCity; // the "tool-tip" that shows up when you pick a city...
100 QToolButton *cmdZoom; // our zoom option...
101 QTimer*tHide; // the timer to hide the "tool tip"
102 ZoneField *pLast; // the last known good city that was found...
103 ZoneField *pRepaint; // save the location to maximize the repaint...
104 QList<ZoneField> zones; // a linked list to hold all this information
105 StylusNormalizer norm;
106
107 //the True width and height of the map...
108 int wImg;
109 int hImg;
110 // the pixel points that correspond to (0, 0);
111 int ox;
112 int oy;
113
114 // the drawable area of the map...
115 int drawableW;
116 int drawableH;
117
118 bool bZoom; // a flag to indicate zoom is active
119 bool bIllum; // flag to indicat that illumination is active
120 bool ampm;
121
122 ZoneField *cursor;
123};
124
125inline bool ZoneMap::zoneToWin( int zoneX, int zoneY,
126 int &winX, int &winY ) const
127{
128 winY = oy - ( ( hImg * zoneY ) / 648000 ); // 180 degrees in secs
129 winX = ox + ( ( wImg * zoneX ) / 1296000 ); // 360 degrees in secs
130 // whoa, some things aren't in the best spots..
131 if ( winX > wImg ) {
132 winX = wImg - iCITYOFFSET;
133 } else if ( winX <= 0 ) {
134 winX = iCITYOFFSET;
135 }
136
137 if ( winY >= hImg ) {
138 winY = hImg - iCITYOFFSET;
139 } else if ( winY <= 0 ) {
140 winY = iCITYOFFSET;
141 }
142 // perhaps in the future there will be some real error checking
143 // for now just return true...
144 return true;
145}
146
147inline bool ZoneMap::winToZone( int winX, int winY,
148 int &zoneX, int &zoneY ) const
149{
150 zoneY = ( 648000 * ( oy - winY ) ) / hImg;
151 zoneX = ( 1296000 * ( winX - ox ) ) / wImg;
152 // perhaps in the future there will be some real error checking
153 // for now just return true...
154 return true;
155}
156
157#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 @@
1moc_*
2Makefile
3lightsettingsbase.h
4lightsettingsbase.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 @@
1#############################################################################
2
3####### Compiler, tools and options
4
5 CXX =$(SYSCONF_CXX) $(QT_CXX_MT)
6 CXXFLAGS=$(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
7 CC =$(SYSCONF_CC) $(QT_C_MT)
8 CFLAGS =$(SYSCONF_CFLAGS)
9 INCPATH =-I$(QPEDIR)/include
10 LFLAGS =$(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
11 LIBS =$(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
12 MOC =$(SYSCONF_MOC)
13 UIC =$(SYSCONF_UIC)
14
15####### Target
16
17DESTDIR = ../../bin/
18VER_MAJ = 1
19VER_MIN = 0
20VER_PATCH = 0
21 TARGET= light-and-power
22TARGET1 = lib$(TARGET).so.$(VER_MAJ)
23
24####### Files
25
26 HEADERS =settings.h
27 SOURCES =light.cpp \
28 main.cpp
29 OBJECTS =light.o \
30 main.o \
31 lightsettingsbase.o
32INTERFACES = lightsettingsbase.ui
33UICDECLS = lightsettingsbase.h
34UICIMPLS = lightsettingsbase.cpp
35 SRCMOC =moc_settings.cpp \
36 moc_lightsettingsbase.cpp
37 OBJMOC =moc_settings.o \
38 moc_lightsettingsbase.o
39
40
41####### Implicit rules
42
43.SUFFIXES: .cpp .cxx .cc .C .c
44
45.cpp.o:
46 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
47
48.cxx.o:
49 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
50
51.cc.o:
52 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
53
54.C.o:
55 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
56
57.c.o:
58 $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
59
60####### Build rules
61
62
63all: $(DESTDIR)$(TARGET)
64
65$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
66 $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
67
68moc: $(SRCMOC)
69
70tmake:
71 tmake light-and-power.pro
72
73clean:
74 -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
75 -rm -f *~ core
76 -rm -f allmoc.cpp
77
78####### Extension Modules
79
80listpromodules:
81 @echo
82
83listallmodules:
84 @echo
85
86listaddonpromodules:
87 @echo
88
89listaddonentmodules:
90 @echo
91
92
93REQUIRES=
94
95####### Sub-libraries
96
97
98###### Combined headers
99
100
101
102####### Compile
103
104light.o: light.cpp \
105 settings.h \
106 lightsettingsbase.h
107
108main.o: main.cpp \
109 settings.h \
110 lightsettingsbase.h
111
112lightsettingsbase.h: lightsettingsbase.ui
113 $(UIC) lightsettingsbase.ui -o $(INTERFACE_DECL_PATH)/lightsettingsbase.h
114
115lightsettingsbase.cpp: lightsettingsbase.ui
116 $(UIC) lightsettingsbase.ui -i lightsettingsbase.h -o lightsettingsbase.cpp
117
118lightsettingsbase.o: lightsettingsbase.cpp \
119 lightsettingsbase.h \
120 lightsettingsbase.ui
121
122moc_settings.o: moc_settings.cpp \
123 settings.h \
124 lightsettingsbase.h
125
126moc_lightsettingsbase.o: moc_lightsettingsbase.cpp \
127 lightsettingsbase.h
128
129moc_settings.cpp: settings.h
130 $(MOC) settings.h -o moc_settings.cpp
131
132moc_lightsettingsbase.cpp: lightsettingsbase.h
133 $(MOC) lightsettingsbase.h -o moc_lightsettingsbase.cpp
134
135
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 @@
1 TEMPLATE= app
2 CONFIG += qt warn_on release
3 DESTDIR = ../../bin
4 HEADERS = settings.h
5 SOURCES = light.cpp main.cpp
6 INTERFACES= lightsettingsbase.ui
7INCLUDEPATH += $(QPEDIR)/include
8 DEPENDPATH+= ../$(QPEDIR)/include
9LIBS += -lqpe
10 TARGET = light-and-power
11
12TRANSLATIONS = ../../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 @@
1/* XPM */
2static char * light_off_xpm[] = {
3"16 16 4 1",
4 " c None",
5 ".c #000000000000",
6 "Xc #6B6B6C6C6C6C",
7 "oc #FFFF6C6C0000",
8" ",
9" ",
10" ... ",
11" . . ",
12" . X. ",
13" . X. ",
14" . XXX. ",
15" . X XX. ",
16" . XX. ",
17" . XXX. ",
18" . X. ",
19" . X.. ",
20" .ooo.. ",
21" .ooo.. ",
22" .o.. ",
23" .. "};
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 @@
1/* XPM */
2static char * light_on_xpm[] = {
3"16 16 5 1",
4 " c None",
5 ".c #FFFFFFFF0000",
6 "Xc #000000000000",
7 "oc #FFFFFFFFFFFF",
8 "Oc #FFFF6C6C0000",
9" . . ",
10" . . . ",
11" . XXX . ",
12" XoooX . ",
13" Xoooo.X ",
14" .. Xoooooo.X ",
15" Xoooo...X ..",
16" Xooo.o..X ",
17" .. Xooo..X ",
18" Xoo...X ",
19" . Xoo.X . ",
20" . Xoo.XX . ",
21" XOOOXX ",
22" XOOOXX ",
23" XOXX ",
24" 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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#include "settings.h"
21
22#include <qpe/global.h>
23#include <qpe/fontmanager.h>
24#include <qpe/config.h>
25#include <qpe/applnk.h>
26#include <qpe/qpeapplication.h>
27#if defined(Q_WS_QWS) && !defined(QT_NO_COP)
28#include <qpe/qcopenvelope_qws.h>
29#endif
30
31#include <qlabel.h>
32#include <qcheckbox.h>
33#include <qradiobutton.h>
34#include <qtabwidget.h>
35#include <qslider.h>
36#include <qfile.h>
37#include <qtextstream.h>
38#include <qdatastream.h>
39#include <qmessagebox.h>
40#include <qcombobox.h>
41#include <qspinbox.h>
42#include <qlistbox.h>
43#include <qdir.h>
44#if QT_VERSION >= 300
45#include <qstylefactory.h>
46#endif
47
48extern int qpe_sysBrightnessSteps();
49
50LightSettings::LightSettings( QWidget* parent, const char* name, WFlags fl )
51 : LightSettingsBase( parent, name, TRUE, fl )
52{
53 // Not supported
54 auto_brightness->hide();
55
56 Config config( "qpe" );
57
58 config.setGroup( "Screensaver" );
59
60 int interval;
61 interval = config.readNumEntry( "Interval_Dim", 30 );
62 interval_dim->setValue( interval );
63 interval = config.readNumEntry( "Interval_LightOff", 20 );
64 interval_lightoff->setValue( interval );
65 interval = config.readNumEntry( "Interval", 60 );
66 if ( interval > 3600 ) interval /= 1000; // compatibility (was millisecs)
67 interval_suspend->setValue( interval );
68
69 screensaver_dim->setChecked( config.readNumEntry("Dim",1) != 0 );
70 screensaver_lightoff->setChecked( config.readNumEntry("LightOff",1) != 0 );
71 int maxbright = qpe_sysBrightnessSteps();
72 initbright = config.readNumEntry("Brightness",255);
73 brightness->setMaxValue( maxbright );
74 brightness->setTickInterval( QMAX(1,maxbright/16) );
75 brightness->setLineStep( QMAX(1,maxbright/16) );
76 brightness->setPageStep( QMAX(1,maxbright/16) );
77 brightness->setValue( (maxbright*255 - initbright*maxbright)/255 );
78
79 connect(brightness, SIGNAL(valueChanged(int)), this, SLOT(applyBrightness()));
80}
81
82LightSettings::~LightSettings()
83{
84}
85
86static void set_fl(int bright)
87{
88 QCopEnvelope e("QPE/System", "setBacklight(int)" );
89 e << bright;
90}
91
92void LightSettings::reject()
93{
94 set_fl(initbright);
95
96 QDialog::reject();
97}
98
99void LightSettings::accept()
100{
101 if ( qApp->focusWidget() )
102 qApp->focusWidget()->clearFocus();
103
104 applyBrightness();
105
106 int i_dim = (screensaver_dim->isChecked() ? interval_dim->value() : 0);
107 int i_lightoff = (screensaver_lightoff->isChecked() ? interval_lightoff->value() : 0);
108 int i_suspend = interval_suspend->value();
109 QCopEnvelope e("QPE/System", "setScreenSaverIntervals(int,int,int)" );
110 e << i_dim << i_lightoff << i_suspend;
111
112 Config config( "qpe" );
113 config.setGroup( "Screensaver" );
114 config.writeEntry( "Dim", (int)screensaver_dim->isChecked() );
115 config.writeEntry( "LightOff", (int)screensaver_lightoff->isChecked() );
116 config.writeEntry( "Interval_Dim", interval_dim->value() );
117 config.writeEntry( "Interval_LightOff", interval_lightoff->value() );
118 config.writeEntry( "Interval", interval_suspend->value() );
119 config.writeEntry( "Brightness",
120 (brightness->maxValue()-brightness->value())*255/brightness->maxValue() );
121 config.write();
122
123 QDialog::accept();
124}
125
126void LightSettings::applyBrightness()
127{
128 int bright = (brightness->maxValue()-brightness->value())*255
129 / brightness->maxValue();
130 set_fl(bright);
131}
132
133
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 @@
1<!DOCTYPE UI><UI>
2<class>LightSettingsBase</class>
3<widget>
4 <class>QDialog</class>
5 <property stdset="1">
6 <name>name</name>
7 <cstring>LightSettingsBase</cstring>
8 </property>
9 <property stdset="1">
10 <name>geometry</name>
11 <rect>
12 <x>0</x>
13 <y>0</y>
14 <width>256</width>
15 <height>316</height>
16 </rect>
17 </property>
18 <property stdset="1">
19 <name>caption</name>
20 <string>Light Settings</string>
21 </property>
22 <property>
23 <name>layoutMargin</name>
24 </property>
25 <vbox>
26 <property stdset="1">
27 <name>margin</name>
28 <number>7</number>
29 </property>
30 <property stdset="1">
31 <name>spacing</name>
32 <number>6</number>
33 </property>
34 <widget>
35 <class>QCheckBox</class>
36 <property stdset="1">
37 <name>name</name>
38 <cstring>auto_brightness</cstring>
39 </property>
40 <property stdset="1">
41 <name>text</name>
42 <string>Adjust to environment</string>
43 </property>
44 <property>
45 <name>whatsThis</name>
46 <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>
47 </property>
48 </widget>
49 <widget>
50 <class>QGroupBox</class>
51 <property stdset="1">
52 <name>name</name>
53 <cstring>GroupBox3</cstring>
54 </property>
55 <property stdset="1">
56 <name>title</name>
57 <string>Power saving</string>
58 </property>
59 <property>
60 <name>layoutMargin</name>
61 </property>
62 <property>
63 <name>layoutSpacing</name>
64 </property>
65 <grid>
66 <property stdset="1">
67 <name>margin</name>
68 <number>6</number>
69 </property>
70 <property stdset="1">
71 <name>spacing</name>
72 <number>3</number>
73 </property>
74 <widget row="1" column="1" >
75 <class>QSpinBox</class>
76 <property stdset="1">
77 <name>name</name>
78 <cstring>interval_lightoff</cstring>
79 </property>
80 <property stdset="1">
81 <name>suffix</name>
82 <string> seconds</string>
83 </property>
84 <property stdset="1">
85 <name>buttonSymbols</name>
86 <enum>PlusMinus</enum>
87 </property>
88 <property stdset="1">
89 <name>maxValue</name>
90 <number>3600</number>
91 </property>
92 <property stdset="1">
93 <name>minValue</name>
94 <number>10</number>
95 </property>
96 <property stdset="1">
97 <name>lineStep</name>
98 <number>15</number>
99 </property>
100 </widget>
101 <widget row="2" column="1" >
102 <class>QSpinBox</class>
103 <property stdset="1">
104 <name>name</name>
105 <cstring>interval_suspend</cstring>
106 </property>
107 <property stdset="1">
108 <name>suffix</name>
109 <string> seconds</string>
110 </property>
111 <property stdset="1">
112 <name>buttonSymbols</name>
113 <enum>PlusMinus</enum>
114 </property>
115 <property stdset="1">
116 <name>maxValue</name>
117 <number>3600</number>
118 </property>
119 <property stdset="1">
120 <name>minValue</name>
121 <number>10</number>
122 </property>
123 <property stdset="1">
124 <name>lineStep</name>
125 <number>15</number>
126 </property>
127 </widget>
128 <widget row="1" column="0" >
129 <class>QCheckBox</class>
130 <property stdset="1">
131 <name>name</name>
132 <cstring>screensaver_lightoff</cstring>
133 </property>
134 <property stdset="1">
135 <name>sizePolicy</name>
136 <sizepolicy>
137 <hsizetype>1</hsizetype>
138 <vsizetype>0</vsizetype>
139 </sizepolicy>
140 </property>
141 <property stdset="1">
142 <name>text</name>
143 <string>Light off after</string>
144 </property>
145 <property stdset="1">
146 <name>checked</name>
147 <bool>true</bool>
148 </property>
149 </widget>
150 <widget row="0" column="0" >
151 <class>QCheckBox</class>
152 <property stdset="1">
153 <name>name</name>
154 <cstring>screensaver_dim</cstring>
155 </property>
156 <property stdset="1">
157 <name>sizePolicy</name>
158 <sizepolicy>
159 <hsizetype>1</hsizetype>
160 <vsizetype>0</vsizetype>
161 </sizepolicy>
162 </property>
163 <property stdset="1">
164 <name>text</name>
165 <string>Dim light after</string>
166 </property>
167 <property stdset="1">
168 <name>checked</name>
169 <bool>true</bool>
170 </property>
171 </widget>
172 <widget row="0" column="1" >
173 <class>QSpinBox</class>
174 <property stdset="1">
175 <name>name</name>
176 <cstring>interval_dim</cstring>
177 </property>
178 <property stdset="1">
179 <name>suffix</name>
180 <string> seconds</string>
181 </property>
182 <property stdset="1">
183 <name>buttonSymbols</name>
184 <enum>PlusMinus</enum>
185 </property>
186 <property stdset="1">
187 <name>maxValue</name>
188 <number>3600</number>
189 </property>
190 <property stdset="1">
191 <name>minValue</name>
192 <number>10</number>
193 </property>
194 <property stdset="1">
195 <name>lineStep</name>
196 <number>15</number>
197 </property>
198 </widget>
199 <widget row="2" column="0" >
200 <class>QLabel</class>
201 <property stdset="1">
202 <name>name</name>
203 <cstring>TextLabel1_2</cstring>
204 </property>
205 <property stdset="1">
206 <name>text</name>
207 <string>Suspend after</string>
208 </property>
209 </widget>
210 </grid>
211 </widget>
212 <widget>
213 <class>QLayoutWidget</class>
214 <property stdset="1">
215 <name>name</name>
216 <cstring>Layout18</cstring>
217 </property>
218 <property>
219 <name>layoutMargin</name>
220 </property>
221 <hbox>
222 <property stdset="1">
223 <name>margin</name>
224 <number>0</number>
225 </property>
226 <property stdset="1">
227 <name>spacing</name>
228 <number>6</number>
229 </property>
230 <widget>
231 <class>QSlider</class>
232 <property stdset="1">
233 <name>name</name>
234 <cstring>brightness</cstring>
235 </property>
236 <property stdset="1">
237 <name>maxValue</name>
238 <number>255</number>
239 </property>
240 <property stdset="1">
241 <name>lineStep</name>
242 <number>16</number>
243 </property>
244 <property stdset="1">
245 <name>pageStep</name>
246 <number>16</number>
247 </property>
248 <property stdset="1">
249 <name>orientation</name>
250 <enum>Vertical</enum>
251 </property>
252 <property stdset="1">
253 <name>tickmarks</name>
254 <enum>Right</enum>
255 </property>
256 <property stdset="1">
257 <name>tickInterval</name>
258 <number>32</number>
259 </property>
260 </widget>
261 <widget>
262 <class>QLayoutWidget</class>
263 <property stdset="1">
264 <name>name</name>
265 <cstring>Layout16</cstring>
266 </property>
267 <property>
268 <name>layoutSpacing</name>
269 </property>
270 <vbox>
271 <property stdset="1">
272 <name>margin</name>
273 <number>0</number>
274 </property>
275 <property stdset="1">
276 <name>spacing</name>
277 <number>0</number>
278 </property>
279 <widget>
280 <class>QLayoutWidget</class>
281 <property stdset="1">
282 <name>name</name>
283 <cstring>Layout10</cstring>
284 </property>
285 <hbox>
286 <property stdset="1">
287 <name>margin</name>
288 <number>0</number>
289 </property>
290 <property stdset="1">
291 <name>spacing</name>
292 <number>6</number>
293 </property>
294 <widget>
295 <class>QLabel</class>
296 <property stdset="1">
297 <name>name</name>
298 <cstring>PixmapLabel1</cstring>
299 </property>
300 <property stdset="1">
301 <name>pixmap</name>
302 <pixmap>image0</pixmap>
303 </property>
304 <property stdset="1">
305 <name>scaledContents</name>
306 <bool>false</bool>
307 </property>
308 </widget>
309 <widget>
310 <class>QLabel</class>
311 <property stdset="1">
312 <name>name</name>
313 <cstring>TextLabel1</cstring>
314 </property>
315 <property stdset="1">
316 <name>text</name>
317 <string>Bright</string>
318 </property>
319 </widget>
320 <spacer>
321 <property>
322 <name>name</name>
323 <cstring>Spacer3</cstring>
324 </property>
325 <property stdset="1">
326 <name>orientation</name>
327 <enum>Horizontal</enum>
328 </property>
329 <property stdset="1">
330 <name>sizeType</name>
331 <enum>Expanding</enum>
332 </property>
333 <property>
334 <name>sizeHint</name>
335 <size>
336 <width>20</width>
337 <height>20</height>
338 </size>
339 </property>
340 </spacer>
341 </hbox>
342 </widget>
343 <widget>
344 <class>QLabel</class>
345 <property stdset="1">
346 <name>name</name>
347 <cstring>TextLabel3</cstring>
348 </property>
349 <property stdset="1">
350 <name>sizePolicy</name>
351 <sizepolicy>
352 <hsizetype>5</hsizetype>
353 <vsizetype>7</vsizetype>
354 </sizepolicy>
355 </property>
356 <property stdset="1">
357 <name>text</name>
358 <string>&lt;blockquote&gt;The brighter the screen light, the more battery power is used.&lt;/blockquote&gt;</string>
359 </property>
360 </widget>
361 <widget>
362 <class>QLayoutWidget</class>
363 <property stdset="1">
364 <name>name</name>
365 <cstring>Layout9</cstring>
366 </property>
367 <hbox>
368 <property stdset="1">
369 <name>margin</name>
370 <number>0</number>
371 </property>
372 <property stdset="1">
373 <name>spacing</name>
374 <number>6</number>
375 </property>
376 <widget>
377 <class>QLabel</class>
378 <property stdset="1">
379 <name>name</name>
380 <cstring>PixmapLabel2</cstring>
381 </property>
382 <property stdset="1">
383 <name>pixmap</name>
384 <pixmap>image1</pixmap>
385 </property>
386 <property stdset="1">
387 <name>scaledContents</name>
388 <bool>false</bool>
389 </property>
390 </widget>
391 <widget>
392 <class>QLabel</class>
393 <property stdset="1">
394 <name>name</name>
395 <cstring>TextLabel2</cstring>
396 </property>
397 <property stdset="1">
398 <name>text</name>
399 <string>Off</string>
400 </property>
401 <property stdset="1">
402 <name>alignment</name>
403 <set>AlignVCenter|AlignLeft</set>
404 </property>
405 <property>
406 <name>vAlign</name>
407 </property>
408 </widget>
409 <spacer>
410 <property>
411 <name>name</name>
412 <cstring>Spacer2</cstring>
413 </property>
414 <property stdset="1">
415 <name>orientation</name>
416 <enum>Horizontal</enum>
417 </property>
418 <property stdset="1">
419 <name>sizeType</name>
420 <enum>Expanding</enum>
421 </property>
422 <property>
423 <name>sizeHint</name>
424 <size>
425 <width>20</width>
426 <height>20</height>
427 </size>
428 </property>
429 </spacer>
430 </hbox>
431 </widget>
432 </vbox>
433 </widget>
434 </hbox>
435 </widget>
436 </vbox>
437</widget>
438<images>
439 <image>
440 <name>image0</name>
441 <data format="XPM.GZ" length="439">789c6d8ec10ac2300c86ef7b8ad0ff36a4730777111f41f1288887b4b3e8610a3a0f22bebb6dd3d54d0ca5cdffe54f9aaaa4dd764d6555dc7beecf96ec896f54b68fae7bee0fab57a1ea86fc5950ad6685d2646973bd1c43ce3ec73c46903648e79a5624443a27d20cd2b9382704747e124382f11a7c5e30b364b957b331866331b3800c38f70282121c7c628367c098c1e0eb03121ccd4b46fcb0f80b26bb4833987f76b6d6f274de5fe6a1a031d30969f55e161fe4715f7b</data>
442 </image>
443 <image>
444 <name>image1</name>
445 <data format="XPM.GZ" length="424">789cd3d7528808f055d0d2e72a2e492cc94c5648ce482c52d04a29cdcdad8c8eb5ade6523234530022130543251d2e253d856405bffcbc54105b19c856360003103711c4354b344b314b04719340dcb434b31488ac1e1a2020a6acac8c2ea60cc54862606ea232b218541b5810452c3111432c510f550c22886a1e482c115d0c2c88e6168818babaa4a42462c48082cae8e68102011a06b5d65c0041d3518e</data>
446 </image>
447</images>
448<connections>
449 <connection>
450 <sender>screensaver_dim</sender>
451 <signal>toggled(bool)</signal>
452 <receiver>interval_dim</receiver>
453 <slot>setEnabled(bool)</slot>
454 </connection>
455 <connection>
456 <sender>screensaver_lightoff</sender>
457 <signal>toggled(bool)</signal>
458 <receiver>interval_lightoff</receiver>
459 <slot>setEnabled(bool)</slot>
460 </connection>
461</connections>
462<tabstops>
463 <tabstop>auto_brightness</tabstop>
464 <tabstop>screensaver_dim</tabstop>
465 <tabstop>interval_dim</tabstop>
466 <tabstop>screensaver_lightoff</tabstop>
467 <tabstop>interval_lightoff</tabstop>
468 <tabstop>interval_suspend</tabstop>
469 <tabstop>brightness</tabstop>
470</tabstops>
471</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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "settings.h"
22
23#include <qpe/qpeapplication.h>
24#include <qpe/qcopenvelope_qws.h>
25#include <qpe/global.h>
26
27
28int main(int argc, char** argv)
29{
30 QPEApplication a(argc,argv);
31
32 LightSettings dlg;
33
34 a.showMainWidget(&dlg);
35
36 return a.exec();
37}
38
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 @@
1Files: bin/light-and-power apps/Settings/Light.desktop
2Priority: optional
3Section: qpe/settings
4Maintainer: Warwick Allison <warwick@trolltech.com>
5Architecture: arm
6Version: $QPE_VERSION-3
7Depends: qpe-base ($QPE_VERSION)
8Description: Light and Power settings dialog
9 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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef SETTINGS_H
21#define SETTINGS_H
22
23
24#include <qstrlist.h>
25#include <qasciidict.h>
26#include "lightsettingsbase.h"
27
28
29class LightSettings : public LightSettingsBase
30{
31 Q_OBJECT
32
33public:
34 LightSettings( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
35 ~LightSettings();
36
37protected:
38 void accept();
39 void reject();
40
41private slots:
42 void applyBrightness();
43
44private:
45 int initbright;
46};
47
48
49#endif // SETTINGS_H
50
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 @@
1Makefile
2moc_*
3*.moc
4securitybase.cpp
5securitybase.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 @@
1#############################################################################
2
3####### Compiler, tools and options
4
5 CXX =$(SYSCONF_CXX) $(QT_CXX_MT)
6 CXXFLAGS=$(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
7 CC =$(SYSCONF_CC) $(QT_C_MT)
8 CFLAGS =$(SYSCONF_CFLAGS)
9 INCPATH =-I$(QPEDIR)/include
10 LFLAGS =$(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
11 LIBS =$(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
12 MOC =$(SYSCONF_MOC)
13 UIC =$(SYSCONF_UIC)
14
15####### Target
16
17DESTDIR = ../../bin/
18VER_MAJ = 1
19VER_MIN = 0
20VER_PATCH = 0
21 TARGET= security
22TARGET1 = lib$(TARGET).so.$(VER_MAJ)
23
24####### Files
25
26 HEADERS =security.h
27 SOURCES =security.cpp \
28 main.cpp
29 OBJECTS =security.o \
30 main.o \
31 securitybase.o
32INTERFACES = securitybase.ui
33UICDECLS = securitybase.h
34UICIMPLS = securitybase.cpp
35 SRCMOC =moc_security.cpp \
36 moc_securitybase.cpp
37 OBJMOC =moc_security.o \
38 moc_securitybase.o
39
40
41####### Implicit rules
42
43.SUFFIXES: .cpp .cxx .cc .C .c
44
45.cpp.o:
46 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
47
48.cxx.o:
49 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
50
51.cc.o:
52 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
53
54.C.o:
55 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
56
57.c.o:
58 $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
59
60####### Build rules
61
62
63all: $(DESTDIR)$(TARGET)
64
65$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
66 $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
67
68moc: $(SRCMOC)
69
70tmake:
71 tmake security.pro
72
73clean:
74 -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
75 -rm -f *~ core
76 -rm -f allmoc.cpp
77
78####### Extension Modules
79
80listpromodules:
81 @echo
82
83listallmodules:
84 @echo
85
86listaddonpromodules:
87 @echo
88
89listaddonentmodules:
90 @echo
91
92
93REQUIRES=
94
95####### Sub-libraries
96
97
98###### Combined headers
99
100
101
102####### Compile
103
104security.o: security.cpp \
105 security.h \
106 securitybase.h
107
108main.o: main.cpp \
109 security.h \
110 securitybase.h
111
112securitybase.h: securitybase.ui
113 $(UIC) securitybase.ui -o $(INTERFACE_DECL_PATH)/securitybase.h
114
115securitybase.cpp: securitybase.ui
116 $(UIC) securitybase.ui -i securitybase.h -o securitybase.cpp
117
118securitybase.o: securitybase.cpp \
119 securitybase.h \
120 securitybase.ui
121
122moc_security.o: moc_security.cpp \
123 security.h \
124 securitybase.h
125
126moc_securitybase.o: moc_securitybase.cpp \
127 securitybase.h
128
129moc_security.cpp: security.h
130 $(MOC) security.h -o moc_security.cpp
131
132moc_securitybase.cpp: securitybase.h
133 $(MOC) securitybase.h -o moc_securitybase.cpp
134
135
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include <qpe/qpeapplication.h>
22#include <qpe/qcopenvelope_qws.h>
23#include <qpe/global.h>
24
25#include "security.h"
26
27
28int main(int argc, char** argv)
29{
30 QPEApplication a(argc,argv);
31
32 Security dlg;
33
34 a.showMainWidget(&dlg);
35
36 return a.exec();
37}
38
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 @@
1Files: bin/security apps/Settings/Security.desktop
2Priority: optional
3Section: qpe/settings
4Maintainer: Warwick Allison <warwick@trolltech.com>
5Architecture: arm
6Version: $QPE_VERSION-3
7Depends: qpe-base ($QPE_VERSION)
8Description: Security settings dialog
9 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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#include "security.h"
21
22#include <qpe/config.h>
23#include <qpe/password.h>
24#include <qpe/qpedialog.h>
25
26#include <qcheckbox.h>
27#include <qpushbutton.h>
28#include <qcombobox.h>
29#include <qmessagebox.h>
30
31Security::Security( QWidget* parent, const char* name, WFlags fl )
32 : SecurityBase( parent, name, TRUE, fl )
33{
34 valid=FALSE;
35 Config cfg("Security");
36 cfg.setGroup("Passcode");
37 passcode = cfg.readEntry("passcode");
38 passcode_poweron->setChecked(cfg.readBoolEntry("passcode_poweron",FALSE));
39 cfg.setGroup("Sync");
40 int auth_peer = cfg.readNumEntry("auth_peer",0xc0a80100);
41 int auth_peer_bits = cfg.readNumEntry("auth_peer_bits",24);
42 selectNet(auth_peer,auth_peer_bits);
43 connect(syncnet, SIGNAL(textChanged(const QString&)),
44 this, SLOT(setSyncNet(const QString&)));
45
46 /*
47 cfg.setGroup("Remote");
48 if ( telnetAvailable() )
49 telnet->setChecked(cfg.readEntry("allow_telnet"));
50 else
51 telnet->hide();
52
53 if ( sshAvailable() )
54 ssh->setChecked(cfg.readEntry("allow_ssh"));
55 else
56 ssh->hide();
57 */
58
59 connect(changepasscode,SIGNAL(clicked()), this, SLOT(changePassCode()));
60 connect(clearpasscode,SIGNAL(clicked()), this, SLOT(clearPassCode()));
61 updateGUI();
62
63 dl = new QPEDialogListener(this);
64}
65
66Security::~Security()
67{
68}
69
70
71void Security::updateGUI()
72{
73 bool empty = passcode.isEmpty();
74
75 changepasscode->setText( empty ? tr("Set passcode" )
76 : tr("Change passcode" ) );
77 passcode_poweron->setEnabled( !empty );
78 clearpasscode->setEnabled( !empty );
79}
80
81
82void Security::show()
83{
84 valid=FALSE;
85 setEnabled(FALSE);
86 SecurityBase::show();
87 if ( passcode.isEmpty() ) {
88 // could insist...
89 //changePassCode();
90 //if ( passcode.isEmpty() )
91 //reject();
92 } else {
93 QString pc = enterPassCode(tr("Enter passcode"));
94 if ( pc != passcode ) {
95 QMessageBox::critical(this, tr("Passcode incorrect"),
96 tr("The passcode entered is incorrect.\nAccess denied"));
97 reject();
98 return;
99 }
100 }
101 setEnabled(TRUE);
102 valid=TRUE;
103}
104
105void Security::accept()
106{
107 applySecurity();
108 QDialog::accept();
109}
110
111void Security::done(int r)
112{
113 QDialog::done(r);
114 close();
115}
116
117void Security::selectNet(int auth_peer,int auth_peer_bits)
118{
119 QString sn;
120 if ( auth_peer_bits == 0 && auth_peer == 0 ) {
121 sn = tr("Any");
122 } else if ( auth_peer_bits == 32 && auth_peer == 0 ) {
123 sn = tr("None");
124 } else {
125 sn =
126 QString::number((auth_peer>>24)&0xff) + "."
127 + QString::number((auth_peer>>16)&0xff) + "."
128 + QString::number((auth_peer>>8)&0xff) + "."
129 + QString::number((auth_peer>>0)&0xff) + "/"
130 + QString::number(auth_peer_bits);
131 }
132 for (int i=0; i<syncnet->count(); i++) {
133 if ( syncnet->text(i).left(sn.length()) == sn ) {
134 syncnet->setCurrentItem(i);
135 return;
136 }
137 }
138 qDebug("No match for \"%s\"",sn.latin1());
139}
140
141void Security::parseNet(const QString& sn,int& auth_peer,int& auth_peer_bits)
142{
143 auth_peer=0;
144 if ( sn == tr("Any") ) {
145 auth_peer = 0;
146 auth_peer_bits = 0;
147 } else if ( sn == tr("None") ) {
148 auth_peer = 0;
149 auth_peer_bits = 32;
150 } else {
151 int x=0;
152 for (int i=0; i<4; i++) {
153 int nx = sn.find(QChar(i==3 ? '/' : '.'),x);
154 auth_peer = (auth_peer<<8)|sn.mid(x,nx-x).toInt();
155 x = nx+1;
156 }
157 uint n = (uint)sn.find(' ',x)-x;
158 auth_peer_bits = sn.mid(x,n).toInt();
159 }
160}
161
162void Security::setSyncNet(const QString& sn)
163{
164 int auth_peer,auth_peer_bits;
165 parseNet(sn,auth_peer,auth_peer_bits);
166 selectNet(auth_peer,auth_peer_bits);
167}
168
169void Security::applySecurity()
170{
171 if ( valid ) {
172 Config cfg("Security");
173 cfg.setGroup("Passcode");
174 cfg.writeEntry("passcode",passcode);
175 cfg.writeEntry("passcode_poweron",passcode_poweron->isChecked());
176 cfg.setGroup("Sync");
177 int auth_peer=0;
178 int auth_peer_bits;
179 QString sn = syncnet->currentText();
180 parseNet(sn,auth_peer,auth_peer_bits);
181 cfg.writeEntry("auth_peer",auth_peer);
182 cfg.writeEntry("auth_peer_bits",auth_peer_bits);
183 /*
184 cfg.setGroup("Remote");
185 if ( telnetAvailable() )
186 cfg.writeEntry("allow_telnet",telnet->isChecked());
187 if ( sshAvailable() )
188 cfg.writeEntry("allow_ssh",ssh->isChecked());
189 // ### write ssh/telnet sys config files
190 */
191 }
192}
193
194void Security::changePassCode()
195{
196 QString new1;
197 QString new2;
198
199 do {
200 new1 = enterPassCode("Enter new passcode");
201 if ( new1.isNull() )
202 return;
203 new2 = enterPassCode("Re-enter new passcode");
204 if ( new2.isNull() )
205 return;
206 } while (new1 != new2);
207
208 passcode = new1;
209 updateGUI();
210}
211
212void Security::clearPassCode()
213{
214 passcode = QString::null;
215 updateGUI();
216}
217
218
219QString Security::enterPassCode(const QString& prompt)
220{
221 return Password::getPassword(prompt);
222}
223
224bool Security::telnetAvailable() const
225{
226 // ### not implemented
227 return FALSE;
228}
229
230bool Security::sshAvailable() const
231{
232 // ### not implemented
233 return FALSE;
234}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef SECURITY_H
21#define SECURITY_H
22
23#include "securitybase.h"
24
25class QPEDialogListener;
26
27class Security : public SecurityBase
28{
29 Q_OBJECT
30
31public:
32 Security( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
33 ~Security();
34
35 void show();
36
37protected:
38 void accept();
39 void applySecurity();
40 void done(int);
41
42private slots:
43 void changePassCode();
44 void clearPassCode();
45 void setSyncNet(const QString&);
46
47private:
48 bool telnetAvailable() const;
49 bool sshAvailable() const;
50 void updateGUI();
51
52 static void parseNet(const QString& sn,int& auth_peer,int& auth_peer_bits);
53 void selectNet(int auth_peer,int auth_peer_bits);
54
55 QString enterPassCode(const QString&);
56 QString passcode;
57 bool valid;
58
59 QPEDialogListener *dl;
60};
61
62
63#endif // SECURITY_H
64
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 @@
1 TEMPLATE= app
2 CONFIG += qt warn_on release
3 DESTDIR = ../../bin
4 HEADERS = security.h
5 SOURCES = security.cpp main.cpp
6 INTERFACES= securitybase.ui
7INCLUDEPATH += $(QPEDIR)/include
8 DEPENDPATH+= ../$(QPEDIR)/include
9LIBS += -lqpe
10 TARGET = security
11
12TRANSLATIONS = ../../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 @@
1<!DOCTYPE UI><UI>
2<class>SecurityBase</class>
3<widget>
4 <class>QDialog</class>
5 <property stdset="1">
6 <name>name</name>
7 <cstring>SecurityBase</cstring>
8 </property>
9 <property stdset="1">
10 <name>geometry</name>
11 <rect>
12 <x>0</x>
13 <y>0</y>
14 <width>281</width>
15 <height>328</height>
16 </rect>
17 </property>
18 <property stdset="1">
19 <name>caption</name>
20 <string>Security Settings</string>
21 </property>
22 <property>
23 <name>layoutMargin</name>
24 </property>
25 <grid>
26 <property stdset="1">
27 <name>margin</name>
28 <number>11</number>
29 </property>
30 <property stdset="1">
31 <name>spacing</name>
32 <number>6</number>
33 </property>
34 <widget row="0" column="0" >
35 <class>QLayoutWidget</class>
36 <property stdset="1">
37 <name>name</name>
38 <cstring>Layout1</cstring>
39 </property>
40 <property>
41 <name>layoutSpacing</name>
42 </property>
43 <hbox>
44 <property stdset="1">
45 <name>margin</name>
46 <number>0</number>
47 </property>
48 <property stdset="1">
49 <name>spacing</name>
50 <number>-1</number>
51 </property>
52 <widget>
53 <class>QPushButton</class>
54 <property stdset="1">
55 <name>name</name>
56 <cstring>changepasscode</cstring>
57 </property>
58 <property stdset="1">
59 <name>text</name>
60 <string>Change passcode</string>
61 </property>
62 </widget>
63 <widget>
64 <class>QPushButton</class>
65 <property stdset="1">
66 <name>name</name>
67 <cstring>clearpasscode</cstring>
68 </property>
69 <property stdset="1">
70 <name>text</name>
71 <string>Clear passcode</string>
72 </property>
73 </widget>
74 </hbox>
75 </widget>
76 <widget row="1" column="0" >
77 <class>QCheckBox</class>
78 <property stdset="1">
79 <name>name</name>
80 <cstring>passcode_poweron</cstring>
81 </property>
82 <property stdset="1">
83 <name>text</name>
84 <string>Require pass code at power-on</string>
85 </property>
86 </widget>
87 <widget row="3" column="0" >
88 <class>QTabWidget</class>
89 <property stdset="1">
90 <name>name</name>
91 <cstring>TabWidget2</cstring>
92 </property>
93 <widget>
94 <class>QWidget</class>
95 <property stdset="1">
96 <name>name</name>
97 <cstring>tab</cstring>
98 </property>
99 <attribute>
100 <name>title</name>
101 <string>Sync</string>
102 </attribute>
103 <vbox>
104 <property stdset="1">
105 <name>margin</name>
106 <number>11</number>
107 </property>
108 <property stdset="1">
109 <name>spacing</name>
110 <number>6</number>
111 </property>
112 <widget>
113 <class>QLabel</class>
114 <property stdset="1">
115 <name>name</name>
116 <cstring>TextLabel1_2</cstring>
117 </property>
118 <property stdset="1">
119 <name>text</name>
120 <string>Accept sync from network:</string>
121 </property>
122 </widget>
123 <widget>
124 <class>QComboBox</class>
125 <item>
126 <property>
127 <name>text</name>
128 <string>192.168.1.0/24 (default)</string>
129 </property>
130 </item>
131 <item>
132 <property>
133 <name>text</name>
134 <string>192.168.0.0/16</string>
135 </property>
136 </item>
137 <item>
138 <property>
139 <name>text</name>
140 <string>172.16.0.0/12</string>
141 </property>
142 </item>
143 <item>
144 <property>
145 <name>text</name>
146 <string>10.0.0.0/8</string>
147 </property>
148 </item>
149 <item>
150 <property>
151 <name>text</name>
152 <string>Any</string>
153 </property>
154 </item>
155 <item>
156 <property>
157 <name>text</name>
158 <string>None</string>
159 </property>
160 </item>
161 <property stdset="1">
162 <name>name</name>
163 <cstring>syncnet</cstring>
164 </property>
165 <property stdset="1">
166 <name>editable</name>
167 <bool>true</bool>
168 </property>
169 </widget>
170 </vbox>
171 </widget>
172 </widget>
173 <widget row="2" column="0" >
174 <class>QLabel</class>
175 <property stdset="1">
176 <name>name</name>
177 <cstring>TextLabel1</cstring>
178 </property>
179 <property stdset="1">
180 <name>sizePolicy</name>
181 <sizepolicy>
182 <hsizetype>5</hsizetype>
183 <vsizetype>7</vsizetype>
184 </sizepolicy>
185 </property>
186 <property stdset="1">
187 <name>text</name>
188 <string>&lt;P&gt;Pass code protection provides a minimal level of protection from casual access to this device.</string>
189 </property>
190 <property stdset="1">
191 <name>alignment</name>
192 <set>AlignTop|AlignLeft</set>
193 </property>
194 <property>
195 <name>vAlign</name>
196 </property>
197 </widget>
198 </grid>
199</widget>
200</UI>